Skip to content

Conversation

@pyramation
Copy link
Contributor

@pyramation pyramation commented Dec 25, 2025

feat: restore csv-to-pg package and upgrade to @pgsql/utils

Summary

Restores the csv-to-pg package that was removed in commit 1c563fc (June 2025) and upgrades it from the deprecated pg-ast library to @pgsql/utils for latest AST tooling compatibility.

Key changes:

  • Migrated all AST node constructors from pg-ast to @pgsql/utils (e.g., ast.ResTarget()nodes.resTarget())
  • Updated property names to match new API (strsval, valival/fval/sval)
  • Changed null representation from ast.Null() to nodes.aConst({ isnull: true })
  • Removed pg-ast references from FOOTER.md and csv-to-pg README
  • Updated dependencies: @pgsql/types@^17.6.2, @pgsql/utils@^17.8.3, pgsql-deparser@^17.12.2
  • Bumped version to 3.0.0 (breaking API change)

Updates since last revision

Robustness improvements for CSV to INSERT conversion:

  • Fixed makeLocation() to allow valid 0 coordinates - Changed from falsy check (!longitude || !latitude) to explicit null/undefined checks. Previously, coordinates at 0,0 (e.g., Gulf of Guinea) would incorrectly become NULL.
  • Fixed boolean values to use proper PG17 boolean constants - Changed from nodes.string({sval: 'TRUE'}) to nodes.aConst({ boolval: ast.boolean({ boolval: true }) }) for correct AST structure.
  • Added proper PostgreSQL array literal escaping - New escapeArrayElement() function handles NULL, quotes, backslashes, commas, braces, and whitespace in text[] values.
  • Added NULL token handling - Recognizes common CSV NULL representations: NULL, null, \N, NA, N/A, n/a, #N/A, and empty strings.
  • Added timestamp/date/timestamptz type support - Parses ISO8601 format and epoch timestamps (seconds or milliseconds).
  • Added required field validation - New required?: boolean option in field config. When true, throws ValidationError with field name, raw value, expected type, and reason instead of silently returning NULL.
  • Added bbox coordinate validation - makeBoundingBox() now validates exactly 4 numeric parts and coordinate ranges (longitude: -180 to 180, latitude: -90 to 90).

Review & Testing Checklist for Human

  • Verify boolean AST change produces valid SQL - The change from string 'TRUE'/'FALSE' to boolval is significant. Test that INSERT INTO ... VALUES (TRUE, FALSE) deparses correctly, not as string literals.
  • Test 0,0 coordinates - Verify makeLocation(0, 0) produces st_setsrid(st_makepoint(0, 0), 4326) not NULL.
  • Test array escaping edge cases - Values like ["a,b", "c{d}", "e\"f", ""] should produce valid PostgreSQL array literals.
  • Test timestamp parsing - Verify ISO8601 (2025-01-15T10:30:00Z), date-only (2025-01-15), and epoch timestamps work correctly.
  • Test required field validation - Confirm { type: 'text', required: true } throws ValidationError for NULL/empty values.
  • Test bbox validation - Verify invalid bboxes (wrong part count, non-numeric, out-of-range coordinates) throw descriptive errors.

Recommended test plan:

cd packages/csv-to-pg && pnpm test
# Then test with real export:
pgpm init workspace --name test-export
pgpm install @pgpm/db-meta-schema
pgpm deploy
pgpm export

Notes

This PR unblocks the export CLI feature that was broken due to ast.ResTarget is not a function errors. The csv-to-pg package is used by pgpm/core/src/export/export-meta.ts to generate INSERT statements from database rows.

Link to Devin run: https://app.devin.ai/sessions/77df3b12408140e597019f53283de49c
Requested by: Dan Lynch (@pyramation)

- Restore csv-to-pg package from git history (removed in commit 1c563fc)
- Upgrade from pg-ast to @pgsql/utils for latest AST tooling
- Update all AST node constructors to use new API (nodes.* methods)
- Remove pg-ast references from FOOTER.md and csv-to-pg README
- Update package.json to use @pgsql/utils ^17.8.3 and pgsql-deparser ^17.12.2
- Update test snapshots for new AST output format
- Bump version to 3.0.0 for breaking API change
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

- Update CLI to use Inquirerer class from inquirerer package
- Change prompt types from 'config'/'path' to 'text' with proper messages
- Update package.json dependency from @pyramation/prompt to inquirerer ^2.0.3
- Remove @ts-nocheck from utils.ts, parse.ts, parser.ts, and cli.ts
- Add proper TypeScript types and interfaces to all files
- Fix AST construction to use correct PG17 format:
  - Use ast.* (unwrapped) inside A_Const fields (sval, ival, fval)
  - Use nodes.* (wrapped) for top-level nodes
  - Change numeric enum codes to PG17 string enums
  - Fix property names from str to sval
  - Wrap valuesLists items in List nodes
- Fix OnConflictClause to use unwrapped InferClause
- Update js-yaml import from safeLoad to load (v4 API)
- Refactor CLI to use inquirerer's built-in CLI class
- Add @types/js-yaml dev dependency
- Update test snapshots with correct output
- Fix makeLocation() to use explicit null/undefined checks (allows valid 0 coordinates)
- Fix makeBoundingBox() with validation for 4 numeric parts and coordinate ranges
- Fix boolean values to use proper PG17 boolean constants instead of string literals
- Add proper PostgreSQL array literal escaping for text[] type
- Add NULL token handling (NULL, null, \N, NA, N/A, n/a, #N/A, empty string)
- Add timestamp/date/timestamptz type support with ISO8601 parsing
- Add required field validation with ValidationError class
- Update cleanseEmptyStrings to use NULL token detection
@pyramation pyramation merged commit c9a7995 into main Dec 25, 2025
34 checks passed
@pyramation pyramation deleted the devin/1766630963-restore-csv-to-pg branch December 25, 2025 04:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants