fix: serialize extension arrays after provisioning - #4
Conversation
There was a problem hiding this comment.
🟢 Approval recommended
The change is narrowly scoped, aligns with the batch_upsert routine’s parameter types, and is validated by a deterministic regression test covering the reported failure mode.
Pull request overview
This PR fixes a postgres.js type-discovery edge case where extension-installed array types (e.g., ltree[], vector[]/halfvec[]) aren’t recognized on an already-open connection, causing batch array parameters to serialize incorrectly. The solution forces batch arrays through postgres.js’s built-in text[] serializer and lets PostgreSQL cast to the routine’s target array types, plus adds a regression test to prove correctness on a single-connection pool with prepared statement reuse.
Changes:
- Bind
batch_upsertparallel arrays viasql.array(..., textOID)and cast touuid[],public.ltree[],tstzrange[], andpublic.vector[]/public.halfvec[]in SQL. - Add a fresh-
template0regression test that deterministically reproduces the extension-installation-on-same-connection scenario and verifies escaping/null/temporal/vector behavior. - Document the fix in the changelog.
File summaries
| File | Description |
|---|---|
| packages/core/test/support/db.ts | Adds optional max pool size support to force a single-connection pool for deterministic regression coverage. |
| packages/core/test/fresh-extension-arrays.integration.test.ts | New integration regression ensuring extension array types serialize correctly even when installed after connection startup. |
| packages/core/src/write.ts | Uses sql.array with text[] + explicit casts to avoid stale per-connection custom array serializer maps. |
| CHANGELOG.md | Documents the fixed behavior for upsert/upsertMany on the same pool connection used by createIndex. |
Review details
- Files reviewed: 4/4 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Summary
batch_upsertparallel arrays with postgres.js's built-intext[]serializeruuid[],public.ltree[],tstzrange[], and the configured pgvector array type in SQLcreateIndex()installs extensions after a pool connection startstemplate0, single-connection regression covering prepared statement reuse, temporal values, nulls, escaping,halfvec, andvectorRoot cause
postgres.js discovers custom array serializers when a connection starts. When
createIndex()installsltreeandpgvectoron that already-open connection, its type map remains stale. Bare JavaScript arrays then fall back to comma-separated string conversion for the newly resolved custom array OID and PostgreSQL rejects the value with22P02.prepare: falsedoes not fix this on a genuinely fresh database; reconnecting after extension installation only appeared to do so.Validation
./bun run check