Skip to content

Pre-existing: naive ?$n rewrite in postgres connectors, and missing optional peer deps #240

Description

@pi0x

Two pre-existing issues surfaced while reviewing the Neon connector in #191. Both were deliberately left out of that PR because fixing them touches connectors the PR doesn't own.

1. normalizeParams rewrites ? that aren't placeholders

The ?$n rewrite is a naive global regex, so it also rewrites ? inside string literals and the jsonb key-existence operators (?, ?|, ?&):

const normalizeParams = (sql) => { let i = 0; return sql.replace(/\?/g, () => `$${++i}`); };

normalizeParams("SELECT * FROM t WHERE data ? 'key' AND id = ?");
// → SELECT * FROM t WHERE data $1 'key' AND id = $2

normalizeParams("SELECT * FROM t WHERE note = 'why?' AND id = ?");
// → SELECT * FROM t WHERE note = 'why$1' AND id = $2

In both cases the operator/literal is corrupted and the placeholder numbering desyncs from the bound parameters, so the real placeholder becomes $2 while only one param is passed.

Any query using the jsonb ? family, or a literal containing ? (a URL with a query string, a question mark in text), hits this.

The same function is duplicated in three connectors:

  • src/connectors/postgresql.ts:49
  • src/connectors/pglite.ts:50
  • src/connectors/cloudflare-hyperdrive-postgresql.ts:60

A fixed version — a scanner that skips single/double-quoted spans, -- and /* */ comments, and ?| / ?& / ?? — landed in src/connectors/_internal/neon.ts as part of #191 (with unit tests). The three above could adopt it; sharing one implementation from _internal/ seems better than a fourth copy.

2. pg and @planetscale/database are not optional peer dependencies

AGENTS.md states the project value as "Zero runtime deps — all backend drivers are optional peer dependencies", but pg (used by the postgresql connector) and @planetscale/database are declared only as devDependencies, with no peerDependencies / peerDependenciesMeta entry:

peerDependencies: @electric-sql/pglite, @libsql/client, better-sqlite3,
                  drizzle-orm, kysely, mysql2, sqlite3

So installing db0 and importing db0/connectors/postgresql gives no peer-dependency signal that pg is required. #191 adds @neondatabase/serverless and neon-new as optional peers; these two would make the set consistent.

Unrelated and lower priority, but noticed nearby: exports["./connectors/*"].types points at ./dist/connectors/*.d.ts, while obuild emits *.d.mts — there are no .d.ts files in dist/connectors/.


🤖 This issue was drafted by Claude (Opus 4.8) via Claude Code during review of #191. The repros above were executed, not inferred, but a human should sanity-check the proposed direction before anyone acts on it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions