Summary
SqlDriver's three dialect getters decide which dialect's behaviour applies by
matching config.client against a hard-coded pair of literals each:
protectedgetisSqlite(): boolean {constc=(this.configasany).client;returnc==='sqlite3'||c==='better-sqlite3';}protectedgetisPostgres(): boolean {constc=(this.configasany).client;returnc==='pg'||c==='postgresql';}protectedgetisMysql(): boolean {constc=(this.configasany).client;returnc==='mysql'||c==='mysql2';}knex accepts more spellings than that. From knex/lib/constants.js (knex 3.3.0,
the version this repo pins):
constCLIENT_ALIASES=Object.freeze({pg: 'postgres',postgresql: 'postgres',sqlite: 'sqlite3'});constSUPPORTED_CLIENTS=Object.freeze(['mariadb','mssql','mysql','mysql2','oracledb','postgres','pgnative','redshift','sqlite3','cockroachdb','better-sqlite3',].concat(Object.keys(CLIENT_ALIASES)));So client: 'postgres' — knex's own canonical name for the dialect, of which
pg and postgresql are merely the aliases — makes isPostgres return
false. Same shape for client: 'sqlite' (isSqlite → false) and for
cockroachdb / redshift, which speak the pg wire protocol.
Why it is not cosmetic
isPostgres gates real behaviour, not just logging. The clearest case is
nowColumnDefault, where the Postgres branch exists precisely to avoid a
timezone defect:
if(type==='date'){if(this.isMysql)returnthis.knex.raw('(cast(utc_timestamp() as date))');if(this.isPostgres)returnthis.knex.raw("(timezone('utc', now())::date)");}returnthis.knex.fn.now();// ← CURRENT_TIMESTAMPWith client: 'postgres' the driver falls through to knex.fn.now(), i.e. a
bare CURRENT_TIMESTAMP default on a DATE column — which resolves the
calendar day in the server's timezone, the exact defect that branch was
added to remove ("measured: a UTC-12 server records YESTERDAY", per the method's
own docblock). Nothing fails; the column is simply created with the wrong
default, on a configuration knex considers valid.
The file already disagrees with itself
DIALECT_CONNECT_TIMEOUT in the same class covers the wider set for the pg
family — pg, postgres, postgresql, cockroachdb — so two tables in one
file answer "is this Postgres?" differently depending on which one is asked.
This was measured while fixing #11389: a session pin placed behind
DIALECT_CONNECT_TIMEOUT's early return silently skipped redshift, which that
table omits while POSTGRES_WIRE_CLIENTS (added there) includes it. That fix
introduced a third list rather than widening isPostgres, deliberately — the
getters are read from regions of sql-driver.ts held by other in-flight claims,
so widening them was out of scope for that card.
Suggested direction (not a decision)
One dialect-identity source per dialect family, derived from a single table of
client spellings, with the connect-timeout table and the wire-protocol set
reading from it rather than each carrying its own literals. Whether redshift
and cockroachdb should be treated as Postgres for SQL emission (as opposed
to wire parsing) is a genuine question and probably wants a decision rather than
a guess — Redshift in particular diverges on DDL.
Where measured
packages/drivers/driver-sql/src/sql-driver.ts — the three getters, and
DIALECT_CONNECT_TIMEOUT / nowColumnDefault in the same file. Filed while
working #11389; not fixed there.
Summary
SqlDriver's three dialect getters decide which dialect's behaviour applies bymatching
config.clientagainst a hard-coded pair of literals each:knex accepts more spellings than that. From
knex/lib/constants.js(knex 3.3.0,the version this repo pins):
So
client: 'postgres'— knex's own canonical name for the dialect, of whichpgandpostgresqlare merely the aliases — makesisPostgresreturnfalse. Same shape for
client: 'sqlite'(isSqlite→ false) and forcockroachdb/redshift, which speak the pg wire protocol.Why it is not cosmetic
isPostgresgates real behaviour, not just logging. The clearest case isnowColumnDefault, where the Postgres branch exists precisely to avoid atimezone defect:
With
client: 'postgres'the driver falls through toknex.fn.now(), i.e. abare
CURRENT_TIMESTAMPdefault on aDATEcolumn — which resolves thecalendar day in the server's timezone, the exact defect that branch was
added to remove ("measured: a UTC-12 server records YESTERDAY", per the method's
own docblock). Nothing fails; the column is simply created with the wrong
default, on a configuration knex considers valid.
The file already disagrees with itself
DIALECT_CONNECT_TIMEOUTin the same class covers the wider set for the pgfamily —
pg,postgres,postgresql,cockroachdb— so two tables in onefile answer "is this Postgres?" differently depending on which one is asked.
This was measured while fixing #11389: a session pin placed behind
DIALECT_CONNECT_TIMEOUT's early return silently skippedredshift, which thattable omits while
POSTGRES_WIRE_CLIENTS(added there) includes it. That fixintroduced a third list rather than widening
isPostgres, deliberately — thegetters are read from regions of
sql-driver.tsheld by other in-flight claims,so widening them was out of scope for that card.
Suggested direction (not a decision)
One dialect-identity source per dialect family, derived from a single table of
client spellings, with the connect-timeout table and the wire-protocol set
reading from it rather than each carrying its own literals. Whether
redshiftand
cockroachdbshould be treated as Postgres for SQL emission (as opposedto wire parsing) is a genuine question and probably wants a decision rather than
a guess — Redshift in particular diverges on DDL.
Where measured
packages/drivers/driver-sql/src/sql-driver.ts— the three getters, andDIALECT_CONNECT_TIMEOUT/nowColumnDefaultin the same file. Filed whileworking #11389; not fixed there.