@prisma-next/adapter-postgres 0.10.0-dev.9 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { n as createPostgresBuiltinCodecLookup, t as renderLoweredSql } from "./sql-renderer-iX5DLUi7.mjs";
1
+ import { n as createPostgresBuiltinCodecLookup, t as renderLoweredSql } from "./sql-renderer-DFMHmkt_.mjs";
2
2
  import { APP_SPACE_ID } from "@prisma-next/framework-components/control";
3
3
  import { parseContractMarkerRow } from "@prisma-next/sql-runtime";
4
4
  //#region src/core/adapter.ts
@@ -49,4 +49,4 @@ function createPostgresAdapter(options) {
49
49
  //#endregion
50
50
  export { createPostgresAdapter as t };
51
51
 
52
- //# sourceMappingURL=adapter-DorkJByg.mjs.map
52
+ //# sourceMappingURL=adapter-DWa9-y1t.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter-DorkJByg.mjs","names":[],"sources":["../src/core/adapter.ts"],"sourcesContent":["import type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport { APP_SPACE_ID } from '@prisma-next/framework-components/control';\nimport type {\n Adapter,\n AdapterProfile,\n AnyQueryAst,\n LowererContext,\n MarkerReadResult,\n SqlQueryable,\n} from '@prisma-next/sql-relational-core/ast';\nimport { parseContractMarkerRow } from '@prisma-next/sql-runtime';\nimport { createPostgresBuiltinCodecLookup } from './codec-lookup';\nimport { renderLoweredSql } from './sql-renderer';\nimport type { PostgresAdapterOptions, PostgresContract, PostgresLoweredStatement } from './types';\n\nconst defaultCapabilities = Object.freeze({\n postgres: {\n orderBy: true,\n limit: true,\n lateral: true,\n jsonAgg: true,\n returning: true,\n },\n sql: {\n enums: true,\n returning: true,\n defaultInInsert: true,\n },\n});\n\nclass PostgresAdapterImpl\n implements Adapter<AnyQueryAst, PostgresContract, PostgresLoweredStatement>\n{\n // These fields make the adapter instance structurally compatible with RuntimeAdapterInstance<'sql', 'postgres'> without introducing a runtime-plane dependency.\n readonly familyId = 'sql' as const;\n readonly targetId = 'postgres' as const;\n\n readonly profile: AdapterProfile<'postgres'>;\n private readonly codecLookup: CodecLookup;\n\n constructor(options?: PostgresAdapterOptions) {\n this.codecLookup = options?.codecLookup ?? createPostgresBuiltinCodecLookup();\n this.profile = Object.freeze({\n id: options?.profileId ?? 'postgres/default@1',\n target: 'postgres',\n capabilities: defaultCapabilities,\n readMarker: (queryable: SqlQueryable) => readPostgresMarker(queryable),\n });\n }\n\n lower(ast: AnyQueryAst, context: LowererContext<PostgresContract>): PostgresLoweredStatement {\n return renderLoweredSql(ast, context.contract, this.codecLookup);\n }\n}\n\nasync function readPostgresMarker(queryable: SqlQueryable): Promise<MarkerReadResult> {\n const exists = await queryable.query(\n 'select 1 from information_schema.tables where table_schema = $1 and table_name = $2',\n ['prisma_contract', 'marker'],\n );\n if (exists.rows.length === 0) {\n return { kind: 'no-table' };\n }\n\n const result = await queryable.query(\n 'select core_hash, profile_hash, contract_json, canonical_version, updated_at, app_tag, meta, invariants from prisma_contract.marker where space = $1',\n [APP_SPACE_ID],\n );\n const row = result.rows[0];\n if (!row) {\n return { kind: 'absent' };\n }\n // Postgres' driver hydrates `text[]` columns as native JS arrays, so the row is already in the shape the shared parser expects.\n return { kind: 'present', record: parseContractMarkerRow(row) };\n}\n\nexport function createPostgresAdapter(options?: PostgresAdapterOptions) {\n return Object.freeze(new PostgresAdapterImpl(options));\n}\n"],"mappings":";;;;AAeA,MAAM,sBAAsB,OAAO,OAAO;CACxC,UAAU;EACR,SAAS;EACT,OAAO;EACP,SAAS;EACT,SAAS;EACT,WAAW;EACZ;CACD,KAAK;EACH,OAAO;EACP,WAAW;EACX,iBAAiB;EAClB;CACF,CAAC;AAEF,IAAM,sBAAN,MAEA;CAEE,WAAoB;CACpB,WAAoB;CAEpB;CACA;CAEA,YAAY,SAAkC;EAC5C,KAAK,cAAc,SAAS,eAAe,kCAAkC;EAC7E,KAAK,UAAU,OAAO,OAAO;GAC3B,IAAI,SAAS,aAAa;GAC1B,QAAQ;GACR,cAAc;GACd,aAAa,cAA4B,mBAAmB,UAAU;GACvE,CAAC;;CAGJ,MAAM,KAAkB,SAAqE;EAC3F,OAAO,iBAAiB,KAAK,QAAQ,UAAU,KAAK,YAAY;;;AAIpE,eAAe,mBAAmB,WAAoD;CAKpF,KAAI,MAJiB,UAAU,MAC7B,uFACA,CAAC,mBAAmB,SAAS,CAC9B,EACU,KAAK,WAAW,GACzB,OAAO,EAAE,MAAM,YAAY;CAO7B,MAAM,OAAM,MAJS,UAAU,MAC7B,wJACA,CAAC,aAAa,CACf,EACkB,KAAK;CACxB,IAAI,CAAC,KACH,OAAO,EAAE,MAAM,UAAU;CAG3B,OAAO;EAAE,MAAM;EAAW,QAAQ,uBAAuB,IAAI;EAAE;;AAGjE,SAAgB,sBAAsB,SAAkC;CACtE,OAAO,OAAO,OAAO,IAAI,oBAAoB,QAAQ,CAAC"}
1
+ {"version":3,"file":"adapter-DWa9-y1t.mjs","names":[],"sources":["../src/core/adapter.ts"],"sourcesContent":["import type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport { APP_SPACE_ID } from '@prisma-next/framework-components/control';\nimport type {\n Adapter,\n AdapterProfile,\n AnyQueryAst,\n LowererContext,\n MarkerReadResult,\n SqlQueryable,\n} from '@prisma-next/sql-relational-core/ast';\nimport { parseContractMarkerRow } from '@prisma-next/sql-runtime';\nimport { createPostgresBuiltinCodecLookup } from './codec-lookup';\nimport { renderLoweredSql } from './sql-renderer';\nimport type { PostgresAdapterOptions, PostgresContract, PostgresLoweredStatement } from './types';\n\nconst defaultCapabilities = Object.freeze({\n postgres: {\n orderBy: true,\n limit: true,\n lateral: true,\n jsonAgg: true,\n returning: true,\n },\n sql: {\n enums: true,\n returning: true,\n defaultInInsert: true,\n },\n});\n\nclass PostgresAdapterImpl\n implements Adapter<AnyQueryAst, PostgresContract, PostgresLoweredStatement>\n{\n // These fields make the adapter instance structurally compatible with RuntimeAdapterInstance<'sql', 'postgres'> without introducing a runtime-plane dependency.\n readonly familyId = 'sql' as const;\n readonly targetId = 'postgres' as const;\n\n readonly profile: AdapterProfile<'postgres'>;\n private readonly codecLookup: CodecLookup;\n\n constructor(options?: PostgresAdapterOptions) {\n this.codecLookup = options?.codecLookup ?? createPostgresBuiltinCodecLookup();\n this.profile = Object.freeze({\n id: options?.profileId ?? 'postgres/default@1',\n target: 'postgres',\n capabilities: defaultCapabilities,\n readMarker: (queryable: SqlQueryable) => readPostgresMarker(queryable),\n });\n }\n\n lower(ast: AnyQueryAst, context: LowererContext<PostgresContract>): PostgresLoweredStatement {\n return renderLoweredSql(ast, context.contract, this.codecLookup);\n }\n}\n\nasync function readPostgresMarker(queryable: SqlQueryable): Promise<MarkerReadResult> {\n const exists = await queryable.query(\n 'select 1 from information_schema.tables where table_schema = $1 and table_name = $2',\n ['prisma_contract', 'marker'],\n );\n if (exists.rows.length === 0) {\n return { kind: 'no-table' };\n }\n\n const result = await queryable.query(\n 'select core_hash, profile_hash, contract_json, canonical_version, updated_at, app_tag, meta, invariants from prisma_contract.marker where space = $1',\n [APP_SPACE_ID],\n );\n const row = result.rows[0];\n if (!row) {\n return { kind: 'absent' };\n }\n // Postgres' driver hydrates `text[]` columns as native JS arrays, so the row is already in the shape the shared parser expects.\n return { kind: 'present', record: parseContractMarkerRow(row) };\n}\n\nexport function createPostgresAdapter(options?: PostgresAdapterOptions) {\n return Object.freeze(new PostgresAdapterImpl(options));\n}\n"],"mappings":";;;;AAeA,MAAM,sBAAsB,OAAO,OAAO;CACxC,UAAU;EACR,SAAS;EACT,OAAO;EACP,SAAS;EACT,SAAS;EACT,WAAW;EACZ;CACD,KAAK;EACH,OAAO;EACP,WAAW;EACX,iBAAiB;EAClB;CACF,CAAC;AAEF,IAAM,sBAAN,MAEA;CAEE,WAAoB;CACpB,WAAoB;CAEpB;CACA;CAEA,YAAY,SAAkC;EAC5C,KAAK,cAAc,SAAS,eAAe,kCAAkC;EAC7E,KAAK,UAAU,OAAO,OAAO;GAC3B,IAAI,SAAS,aAAa;GAC1B,QAAQ;GACR,cAAc;GACd,aAAa,cAA4B,mBAAmB,UAAU;GACvE,CAAC;;CAGJ,MAAM,KAAkB,SAAqE;EAC3F,OAAO,iBAAiB,KAAK,QAAQ,UAAU,KAAK,YAAY;;;AAIpE,eAAe,mBAAmB,WAAoD;CAKpF,KAAI,MAJiB,UAAU,MAC7B,uFACA,CAAC,mBAAmB,SAAS,CAC9B,EACU,KAAK,WAAW,GACzB,OAAO,EAAE,MAAM,YAAY;CAO7B,MAAM,OAAM,MAJS,UAAU,MAC7B,wJACA,CAAC,aAAa,CACf,EACkB,KAAK;CACxB,IAAI,CAAC,KACH,OAAO,EAAE,MAAM,UAAU;CAG3B,OAAO;EAAE,MAAM;EAAW,QAAQ,uBAAuB,IAAI;EAAE;;AAGjE,SAAgB,sBAAsB,SAAkC;CACtE,OAAO,OAAO,OAAO,IAAI,oBAAoB,QAAQ,CAAC"}
package/dist/adapter.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { t as createPostgresAdapter } from "./adapter-DorkJByg.mjs";
1
+ import { t as createPostgresAdapter } from "./adapter-DWa9-y1t.mjs";
2
2
  export { createPostgresAdapter };
@@ -1 +1 @@
1
- {"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/control-adapter.ts","../src/exports/control.ts"],"mappings":";;;;;;;;;;;;;;;;;cAmCa,sBAAA,YAAkC,iBAAA;EAAA,SACpC,QAAA;EAAA,SACA,QAAA;EAAA,iBAEQ,WAAA;EAiBQ;;;;;;;cARb,WAAA,GAAc,WAAA;EAmDf;;;;EAAA,SA3CF,gBAAA,SAAgB,sBAAA;EA2FtB;;;;;EAAA,SApFM,mBAAA,SAAmB,2BAAA;EA5BkC;;;;;;EAAA,SAoCrD,yBAAA,GACP,MAAA,EAAQ,WAAA,EACR,QAAA,EAAU,wBAAA;EAzBA;;;;;;;;EAoCZ,KAAA,CAAM,GAAA,EAAK,WAAA,EAAa,OAAA,EAAS,cAAA,YAA0B,gBAAA;EAXzD;;;;;;;;EAuBI,UAAA,CACJ,MAAA,EAAQ,qBAAA,qBACR,KAAA,WACC,OAAA,CAAQ,oBAAA;EAFT;;;;;;EAgDI,cAAA,CACJ,MAAA,EAAQ,qBAAA,sBACP,OAAA,CAAQ,WAAA,SAAoB,oBAAA;EAA5B;;;;;;;;;;;;;;;;;;;AC5I2C;;;;;ED8MxC,UAAA,CACJ,MAAA,EAAQ,qBAAA,qBACR,QAAA,YACA,MAAA,YACC,OAAA,CAAQ,WAAA;;;;;;;;;UA8BG,mBAAA;;;;;;;;UAqBA,oBAAA;;;;;;UA0CA,gBAAA;;;;UA0ZA,kBAAA;AAAA;;;cChsBV,yBAAA,EAA2B,2BAAA"}
1
+ {"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/control-adapter.ts","../src/exports/control.ts"],"mappings":";;;;;;;;;;;;;;;;;cAyCa,sBAAA,YAAkC,iBAAA;EAAA,SACpC,QAAA;EAAA,SACA,QAAA;EAAA,iBAEQ,WAAA;EAiBQ;;;;;;;cARb,WAAA,GAAc,WAAA;EAmDf;;;;EAAA,SA3CF,gBAAA,SAAgB,sBAAA;EAoGtB;;;;;EAAA,SA7FM,mBAAA,SAAmB,2BAAA;EA5BkC;;;;;;EAAA,SAoCrD,yBAAA,GACP,MAAA,EAAQ,WAAA,EACR,QAAA,EAAU,wBAAA;EAzBA;;;;;;;;EAoCZ,KAAA,CAAM,GAAA,EAAK,WAAA,EAAa,OAAA,EAAS,cAAA,YAA0B,gBAAA;EAXzD;;;;;;;;EAuBI,UAAA,CACJ,MAAA,EAAQ,qBAAA,qBACR,KAAA,WACC,OAAA,CAAQ,oBAAA;EAFT;;;;;;EAyDI,cAAA,CACJ,MAAA,EAAQ,qBAAA,sBACP,OAAA,CAAQ,WAAA,SAAoB,oBAAA;EAA5B;;;;;;;;;;;;;;;;;;;AC3J2C;;;;;ED4OxC,UAAA,CACJ,MAAA,EAAQ,qBAAA,qBACR,QAAA,YACA,MAAA,YACC,OAAA,CAAQ,WAAA;;;;;;;;;UA8BG,mBAAA;;;;;;;;UAqBA,oBAAA;;;;;;UA0CA,gBAAA;;;;UA0ZA,kBAAA;AAAA;;;cC9tBV,yBAAA,EAA2B,2BAAA"}
package/dist/control.mjs CHANGED
@@ -1,8 +1,10 @@
1
- import { n as createPostgresBuiltinCodecLookup, t as renderLoweredSql } from "./sql-renderer-iX5DLUi7.mjs";
1
+ import { n as createPostgresBuiltinCodecLookup, t as renderLoweredSql } from "./sql-renderer-DFMHmkt_.mjs";
2
2
  import { t as postgresAdapterDescriptorMeta } from "./descriptor-meta-ZIv9PU-5.mjs";
3
+ import { APP_SPACE_ID } from "@prisma-next/framework-components/control";
3
4
  import { SqlEscapeError, escapeLiteral, qualifyName, quoteIdentifier } from "@prisma-next/target-postgres/sql-utils";
4
5
  import { ifDefined } from "@prisma-next/utils/defined";
5
6
  import { PG_ENUM_CODEC_ID } from "@prisma-next/target-postgres/codec-ids";
7
+ import { parseMarkerRowSafely, withMarkerReadErrorHandling } from "@prisma-next/errors/execution";
6
8
  import { parseContractMarkerRow } from "@prisma-next/family-sql/verify";
7
9
  import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
8
10
  import { parsePostgresDefault, parsePostgresDefault as parsePostgresDefault$1 } from "@prisma-next/target-postgres/default-normalizer";
@@ -102,6 +104,7 @@ async function introspectPostgresEnumTypes(options) {
102
104
  }
103
105
  //#endregion
104
106
  //#region src/core/control-adapter.ts
107
+ const POSTGRES_MARKER_TABLE = "prisma_contract.marker";
105
108
  /**
106
109
  * Postgres control plane adapter for control-plane operations like introspection.
107
110
  * Provides target-specific implementations for control-plane domain actions.
@@ -158,10 +161,14 @@ var PostgresControlAdapter = class {
158
161
  * parse errors, so we probe before reading.
159
162
  */
160
163
  async readMarker(driver, space) {
161
- if ((await driver.query(`select 1
164
+ const markerContext = {
165
+ space,
166
+ markerLocation: POSTGRES_MARKER_TABLE
167
+ };
168
+ if ((await withMarkerReadErrorHandling(() => driver.query(`select 1
162
169
  from information_schema.tables
163
- where table_schema = $1 and table_name = $2`, ["prisma_contract", "marker"])).rows.length === 0) return null;
164
- const row = (await driver.query(`select
170
+ where table_schema = $1 and table_name = $2`, ["prisma_contract", "marker"]), markerContext)).rows.length === 0) return null;
171
+ const row = (await withMarkerReadErrorHandling(() => driver.query(`select
165
172
  core_hash,
166
173
  profile_hash,
167
174
  contract_json,
@@ -171,9 +178,9 @@ var PostgresControlAdapter = class {
171
178
  meta,
172
179
  invariants
173
180
  from prisma_contract.marker
174
- where space = $1`, [space])).rows[0];
181
+ where space = $1`, [space]), markerContext)).rows[0];
175
182
  if (!row) return null;
176
- return parseContractMarkerRow(row);
183
+ return parseMarkerRowSafely(row, parseContractMarkerRow, markerContext);
177
184
  }
178
185
  /**
179
186
  * Reads every row from `prisma_contract.marker` and returns them keyed
@@ -182,10 +189,14 @@ var PostgresControlAdapter = class {
182
189
  * map rather than raising "relation does not exist".
183
190
  */
184
191
  async readAllMarkers(driver) {
185
- if ((await driver.query(`select 1
192
+ const markerContext = {
193
+ space: APP_SPACE_ID,
194
+ markerLocation: POSTGRES_MARKER_TABLE
195
+ };
196
+ if ((await withMarkerReadErrorHandling(() => driver.query(`select 1
186
197
  from information_schema.tables
187
- where table_schema = $1 and table_name = $2`, ["prisma_contract", "marker"])).rows.length === 0) return /* @__PURE__ */ new Map();
188
- const result = await driver.query(`select
198
+ where table_schema = $1 and table_name = $2`, ["prisma_contract", "marker"]), markerContext)).rows.length === 0) return /* @__PURE__ */ new Map();
199
+ const result = await withMarkerReadErrorHandling(() => driver.query(`select
189
200
  space,
190
201
  core_hash,
191
202
  profile_hash,
@@ -195,9 +206,12 @@ var PostgresControlAdapter = class {
195
206
  app_tag,
196
207
  meta,
197
208
  invariants
198
- from prisma_contract.marker`);
209
+ from prisma_contract.marker`), markerContext);
199
210
  const rows = /* @__PURE__ */ new Map();
200
- for (const row of result.rows) rows.set(row.space, parseContractMarkerRow(row));
211
+ for (const row of result.rows) rows.set(row.space, parseMarkerRowSafely(row, parseContractMarkerRow, {
212
+ space: row.space,
213
+ markerLocation: POSTGRES_MARKER_TABLE
214
+ }));
201
215
  return rows;
202
216
  }
203
217
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"control.mjs","names":["parsePostgresDefault","normalizeSchemaNativeType"],"sources":["../src/core/enum-control-hooks.ts","../src/core/control-adapter.ts","../src/core/control-mutation-defaults.ts","../src/exports/control.ts"],"sourcesContent":["import type { ControlDriverInstance } from '@prisma-next/framework-components/control';\nimport { PG_ENUM_CODEC_ID } from '@prisma-next/target-postgres/codec-ids';\n\n/**\n * Codec-typed annotation shape that the introspector writes under\n * `schema.annotations.pg.storageTypes[<typeName>]`. Distinct from\n * `StorageTypeInstance` because the introspector emits a plain literal\n * (no class-instance API surface): only the fields downstream consumers\n * actually read from the introspected envelope.\n */\nexport interface PostgresEnumStorageTypeAnnotation {\n readonly codecId: typeof PG_ENUM_CODEC_ID;\n readonly nativeType: string;\n readonly typeParams: { readonly values: readonly string[] };\n}\n\n/**\n * Postgres enum introspection.\n *\n * Migration planning and schema verification for enum types live at the\n * SQL family layer + the Postgres target's planner-strategies layer (see\n * `nativeEnumPlanCallStrategy` and the family-level `verifyEnumType`\n * walk). Introspection is the only piece that remains here because the\n * control adapter still calls into a codec-keyed dispatch surface\n * (`storage.types` is rebuilt from this map in `control-adapter.ts`);\n * the introspector returns the codec-typed shape that downstream\n * `Contract` consumers expect.\n */\ntype EnumRow = {\n schema_name: string;\n type_name: string;\n values: string[];\n};\n\nconst ENUM_INTROSPECT_QUERY = `\n SELECT\n n.nspname AS schema_name,\n t.typname AS type_name,\n array_agg(e.enumlabel ORDER BY e.enumsortorder) AS values\n FROM pg_type t\n JOIN pg_namespace n ON t.typnamespace = n.oid\n JOIN pg_enum e ON t.oid = e.enumtypid\n WHERE n.nspname = $1\n GROUP BY n.nspname, t.typname\n ORDER BY n.nspname, t.typname\n`;\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((entry) => typeof entry === 'string');\n}\n\n/**\n * Parses a PostgreSQL array value into a JavaScript string array.\n *\n * The `pg` library returns `array_agg` results either as a JS array\n * (when type parsers are configured) or as a string in PostgreSQL array\n * literal format (`{value1,value2,...}`). Handles PG's quoting rules:\n * - Elements containing commas, quotes, backslashes, or whitespace are\n * double-quoted.\n * - Inside quoted elements, `\\\"` represents `\"` and `\\\\` represents `\\`.\n *\n * Returns `null` when the input cannot be parsed as a PG array.\n */\nexport function parsePostgresArray(value: unknown): string[] | null {\n if (isStringArray(value)) {\n return value;\n }\n if (typeof value === 'string' && value.startsWith('{') && value.endsWith('}')) {\n const inner = value.slice(1, -1);\n if (inner === '') {\n return [];\n }\n return parseArrayElements(inner);\n }\n return null;\n}\n\nfunction parseArrayElements(input: string): string[] {\n const result: string[] = [];\n let i = 0;\n while (i < input.length) {\n if (input[i] === ',') {\n i++;\n continue;\n }\n if (input[i] === '\"') {\n i++;\n let element = '';\n while (i < input.length && input[i] !== '\"') {\n if (input[i] === '\\\\' && i + 1 < input.length) {\n i++;\n element += input[i];\n } else {\n element += input[i];\n }\n i++;\n }\n i++;\n result.push(element);\n } else {\n const nextComma = input.indexOf(',', i);\n if (nextComma === -1) {\n result.push(input.slice(i).trim());\n i = input.length;\n } else {\n result.push(input.slice(i, nextComma).trim());\n i = nextComma;\n }\n }\n }\n return result;\n}\n\n/**\n * Reads enum types from the live Postgres schema and returns them in\n * the codec-typed annotation shape consumed by `control-adapter.ts`\n * (which writes them under `schema.annotations.pg.storageTypes`).\n */\nexport async function introspectPostgresEnumTypes(options: {\n readonly driver: ControlDriverInstance<'sql', 'postgres'>;\n readonly schemaName?: string;\n}): Promise<Record<string, PostgresEnumStorageTypeAnnotation>> {\n const namespace = options.schemaName ?? 'public';\n const result = await options.driver.query<EnumRow>(ENUM_INTROSPECT_QUERY, [namespace]);\n const types: Record<string, PostgresEnumStorageTypeAnnotation> = {};\n for (const row of result.rows) {\n const values = parsePostgresArray(row.values);\n if (!values) {\n throw new Error(\n `Failed to parse enum values for type \"${row.type_name}\": ` +\n `unexpected format: ${JSON.stringify(row.values)}`,\n );\n }\n types[row.type_name] = {\n codecId: PG_ENUM_CODEC_ID,\n nativeType: row.type_name,\n typeParams: { values },\n };\n }\n return types;\n}\n","import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';\nimport { parseContractMarkerRow } from '@prisma-next/family-sql/verify';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport type { ControlDriverInstance } from '@prisma-next/framework-components/control';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport type { PostgresEnumStorageEntry } from '@prisma-next/sql-contract/types';\nimport type {\n AnyQueryAst,\n LoweredStatement,\n LowererContext,\n} from '@prisma-next/sql-relational-core/ast';\nimport type {\n PrimaryKey,\n SqlColumnIR,\n SqlForeignKeyIR,\n SqlIndexIR,\n SqlReferentialAction,\n SqlSchemaIR,\n SqlTableIR,\n SqlUniqueIR,\n} from '@prisma-next/sql-schema-ir/types';\nimport { parsePostgresDefault } from '@prisma-next/target-postgres/default-normalizer';\nimport { readExistingEnumValues } from '@prisma-next/target-postgres/enum-planning';\nimport { normalizeSchemaNativeType } from '@prisma-next/target-postgres/native-type-normalizer';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { createPostgresBuiltinCodecLookup } from './codec-lookup';\nimport { introspectPostgresEnumTypes } from './enum-control-hooks';\nimport { renderLoweredSql } from './sql-renderer';\nimport type { PostgresContract } from './types';\n\n/**\n * Postgres control plane adapter for control-plane operations like introspection.\n * Provides target-specific implementations for control-plane domain actions.\n */\nexport class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {\n readonly familyId = 'sql' as const;\n readonly targetId = 'postgres' as const;\n\n private readonly codecLookup: CodecLookup;\n\n /**\n * @param codecLookup - Codec lookup used by the SQL renderer to resolve\n * per-codec metadata at lower-time. Defaults to a Postgres-builtins-only\n * lookup when omitted. Stack-aware callers\n * (`SqlControlAdapterDescriptor.create(stack)`) supply\n * `stack.codecLookup` so extension codecs are visible to the renderer.\n */\n constructor(codecLookup?: CodecLookup) {\n this.codecLookup = codecLookup ?? createPostgresBuiltinCodecLookup();\n }\n\n /**\n * Target-specific normalizer for raw Postgres default expressions.\n * Used by schema verification to normalize raw defaults before comparison.\n */\n readonly normalizeDefault = parsePostgresDefault;\n\n /**\n * Target-specific normalizer for Postgres schema native type names.\n * Used by schema verification to normalize introspected type names\n * before comparison with contract native types.\n */\n readonly normalizeNativeType = normalizeSchemaNativeType;\n\n /**\n * Bridges native `PostgresEnumStorageEntry` IR walks against the Postgres\n * introspection shape (`schema.annotations.pg.storageTypes`). Lets\n * the family-level schema verifier walk enum types without reaching\n * into target-specific annotation layouts itself.\n */\n readonly resolveExistingEnumValues = (\n schema: SqlSchemaIR,\n enumType: PostgresEnumStorageEntry,\n ): readonly string[] | null => readExistingEnumValues(schema, enumType.nativeType);\n\n /**\n * Lower a SQL query AST into a Postgres-flavored `{ sql, params }` payload.\n *\n * Delegates to the shared `renderLoweredSql` renderer so the control adapter\n * emits byte-identical SQL to `PostgresAdapterImpl.lower()` for the same AST\n * and contract. Used at migration plan/emit time (e.g. by `dataTransform`)\n * without instantiating the runtime adapter.\n */\n lower(ast: AnyQueryAst, context: LowererContext<unknown>): LoweredStatement {\n return renderLoweredSql(ast, context.contract as PostgresContract, this.codecLookup);\n }\n\n /**\n * Reads the contract marker from `prisma_contract.marker`. Probes\n * `information_schema.tables` first so a fresh database (where the\n * `prisma_contract` schema doesn't yet exist) returns `null` instead of a\n * \"relation does not exist\" error — some Postgres wire-protocol clients\n * (e.g. PGlite's TCP proxy) don't fully recover from extended-protocol\n * parse errors, so we probe before reading.\n */\n async readMarker(\n driver: ControlDriverInstance<'sql', 'postgres'>,\n space: string,\n ): Promise<ContractMarkerRecord | null> {\n const exists = await driver.query(\n `select 1\n from information_schema.tables\n where table_schema = $1 and table_name = $2`,\n ['prisma_contract', 'marker'],\n );\n if (exists.rows.length === 0) {\n return null;\n }\n\n const result = await driver.query<{\n core_hash: string;\n profile_hash: string;\n contract_json: unknown | null;\n canonical_version: number | null;\n updated_at: Date | string;\n app_tag: string | null;\n meta: unknown | null;\n invariants: readonly string[];\n }>(\n `select\n core_hash,\n profile_hash,\n contract_json,\n canonical_version,\n updated_at,\n app_tag,\n meta,\n invariants\n from prisma_contract.marker\n where space = $1`,\n [space],\n );\n\n const row = result.rows[0];\n if (!row) return null;\n return parseContractMarkerRow(row);\n }\n\n /**\n * Reads every row from `prisma_contract.marker` and returns them keyed\n * by `space`. Mirrors the existence probe in {@link readMarker}: a\n * fresh database without the `prisma_contract` schema returns an empty\n * map rather than raising \"relation does not exist\".\n */\n async readAllMarkers(\n driver: ControlDriverInstance<'sql', 'postgres'>,\n ): Promise<ReadonlyMap<string, ContractMarkerRecord>> {\n const exists = await driver.query(\n `select 1\n from information_schema.tables\n where table_schema = $1 and table_name = $2`,\n ['prisma_contract', 'marker'],\n );\n if (exists.rows.length === 0) {\n return new Map();\n }\n\n const result = await driver.query<{\n space: string;\n core_hash: string;\n profile_hash: string;\n contract_json: unknown | null;\n canonical_version: number | null;\n updated_at: Date | string;\n app_tag: string | null;\n meta: unknown | null;\n invariants: readonly string[];\n }>(\n `select\n space,\n core_hash,\n profile_hash,\n contract_json,\n canonical_version,\n updated_at,\n app_tag,\n meta,\n invariants\n from prisma_contract.marker`,\n );\n\n const rows = new Map<string, ContractMarkerRecord>();\n for (const row of result.rows) {\n rows.set(row.space, parseContractMarkerRow(row));\n }\n return rows;\n }\n\n /**\n * Introspects a Postgres database schema and returns a raw SqlSchemaIR.\n *\n * This is a pure schema discovery operation that queries the Postgres catalog\n * and returns the schema structure without type mapping or contract enrichment.\n * Type mapping and enrichment are handled separately by enrichment helpers.\n *\n * When `contract` is provided and its storage declares more than one\n * namespace (or any explicit bound namespace), the adapter walks every\n * declared namespace and merges the per-schema introspection results\n * into a single `SqlSchemaIR`. `UNBOUND_NAMESPACE_ID` resolves to the\n * connection's `current_schema()` so late-bound tables follow the\n * runtime `search_path`. When no contract is passed, the adapter falls\n * back to introspecting the single `schema` argument (defaulting to\n * `'public'`).\n *\n * Uses batched queries to minimize database round trips (6 queries per\n * schema walked).\n *\n * @param driver - ControlDriverInstance<'sql', 'postgres'> instance for executing queries\n * @param contract - Optional contract for contract-guided introspection (multi-namespace walk, filtering)\n * @param schema - Schema name to introspect when no contract is provided (defaults to 'public')\n * @returns Promise resolving to SqlSchemaIR representing the live database schema\n */\n async introspect(\n driver: ControlDriverInstance<'sql', 'postgres'>,\n contract?: unknown,\n schema = 'public',\n ): Promise<SqlSchemaIR> {\n const declaredNamespaces = extractContractNamespaceIds(contract);\n const ir =\n declaredNamespaces.length > 0\n ? await this.introspectNamespaces(driver, declaredNamespaces)\n : await this.introspectSchema(driver, schema);\n // Capture the list of non-system schemas so downstream planners\n // (e.g. `verifyPostgresNamespacePresence`) can determine which\n // contract-declared namespaces need a `CREATE SCHEMA` before the\n // table DDL.\n const existingSchemas = await this.listExistingSchemas(driver);\n const annotations = ir.annotations ?? {};\n const pg = (annotations as { pg?: Record<string, unknown> }).pg ?? {};\n return {\n ...ir,\n annotations: {\n ...annotations,\n pg: { ...pg, existingSchemas },\n },\n };\n }\n\n /**\n * Lists every non-system schema present in the connected database.\n * The introspection consumer (`verifyPostgresNamespacePresence`)\n * treats the result as the authoritative ground truth — declared\n * namespaces whose `ddlSchemaName` is missing from this list become\n * `missing_schema` issues, and the planner emits the matching\n * `CREATE SCHEMA` before table DDL.\n */\n private async listExistingSchemas(\n driver: ControlDriverInstance<'sql', 'postgres'>,\n ): Promise<readonly string[]> {\n const result = await driver.query<{ nspname: string }>(\n `SELECT nspname\n FROM pg_catalog.pg_namespace\n WHERE nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')\n AND nspname NOT LIKE 'pg_temp_%'\n AND nspname NOT LIKE 'pg_toast_temp_%'\n ORDER BY nspname`,\n );\n return result.rows.map((row) => row.nspname);\n }\n\n /**\n * Walks every declared namespace, resolving `UNBOUND_NAMESPACE_ID` to\n * the connection's `current_schema()`, and merges the per-schema results\n * into a single `SqlSchemaIR`. The merged `tables` map is flat (keyed by\n * table name) so callers that look up by `tableName` see every contract\n * table regardless of which namespace it lives in.\n */\n private async introspectNamespaces(\n driver: ControlDriverInstance<'sql', 'postgres'>,\n namespaceIds: readonly string[],\n ): Promise<SqlSchemaIR> {\n const resolvedSchemas = await Promise.all(\n namespaceIds.map(async (id) => {\n if (id === UNBOUND_NAMESPACE_ID) {\n const { rows } = await driver.query<{ current_schema: string }>(\n 'SELECT current_schema() AS current_schema',\n );\n return rows[0]?.current_schema ?? 'public';\n }\n return id;\n }),\n );\n const uniqueSchemas = Array.from(new Set(resolvedSchemas));\n\n const perSchema = await Promise.all(uniqueSchemas.map((s) => this.introspectSchema(driver, s)));\n\n const mergedTables: Record<string, SqlTableIR> = {};\n for (const ir of perSchema) {\n for (const [tableName, table] of Object.entries(ir.tables)) {\n mergedTables[tableName] = table;\n }\n }\n\n // Annotations carry the first schema's metadata (Postgres version,\n // enum storage types). Multi-namespace storage types are introspected\n // per schema; merging them is deferred until a contract actually\n // declares enum types on more than one namespace.\n const firstAnnotations = perSchema[0]?.annotations;\n return {\n tables: mergedTables,\n ...ifDefined('annotations', firstAnnotations),\n };\n }\n\n /**\n * Introspects a single Postgres schema and returns a raw SqlSchemaIR\n * containing only the tables in that schema. Used by `introspect` as\n * the per-namespace walk.\n */\n private async introspectSchema(\n driver: ControlDriverInstance<'sql', 'postgres'>,\n schema: string,\n ): Promise<SqlSchemaIR> {\n // Execute all queries in parallel for efficiency (6 queries instead of 5T+1)\n const [tablesResult, columnsResult, pkResult, fkResult, uniqueResult, indexResult] =\n await Promise.all([\n // Query all tables\n driver.query<{ table_name: string }>(\n `SELECT table_name\n FROM information_schema.tables\n WHERE table_schema = $1\n AND table_type = 'BASE TABLE'\n ORDER BY table_name`,\n [schema],\n ),\n // Query all columns for all tables in schema\n driver.query<{\n table_name: string;\n column_name: string;\n data_type: string;\n udt_name: string;\n is_nullable: string;\n character_maximum_length: number | null;\n numeric_precision: number | null;\n numeric_scale: number | null;\n column_default: string | null;\n formatted_type: string | null;\n }>(\n `SELECT\n c.table_name,\n column_name,\n data_type,\n udt_name,\n is_nullable,\n character_maximum_length,\n numeric_precision,\n numeric_scale,\n column_default,\n format_type(a.atttypid, a.atttypmod) AS formatted_type\n FROM information_schema.columns c\n JOIN pg_catalog.pg_class cl\n ON cl.relname = c.table_name\n JOIN pg_catalog.pg_namespace ns\n ON ns.nspname = c.table_schema\n AND ns.oid = cl.relnamespace\n JOIN pg_catalog.pg_attribute a\n ON a.attrelid = cl.oid\n AND a.attname = c.column_name\n AND a.attnum > 0\n AND NOT a.attisdropped\n WHERE c.table_schema = $1\n ORDER BY c.table_name, c.ordinal_position`,\n [schema],\n ),\n // Query all primary keys for all tables in schema\n driver.query<{\n table_name: string;\n constraint_name: string;\n column_name: string;\n ordinal_position: number;\n }>(\n `SELECT\n tc.table_name,\n tc.constraint_name,\n kcu.column_name,\n kcu.ordinal_position\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n AND tc.table_name = kcu.table_name\n WHERE tc.table_schema = $1\n AND tc.constraint_type = 'PRIMARY KEY'\n ORDER BY tc.table_name, kcu.ordinal_position`,\n [schema],\n ),\n // Query all foreign keys for all tables in schema, including referential actions.\n // Uses pg_catalog for correct positional pairing of composite FK columns\n // (information_schema.constraint_column_usage lacks ordinal_position,\n // which causes Cartesian products for multi-column FKs).\n driver.query<{\n table_name: string;\n constraint_name: string;\n column_name: string;\n ordinal_position: number;\n referenced_table_schema: string;\n referenced_table_name: string;\n referenced_column_name: string;\n delete_rule: string;\n update_rule: string;\n }>(\n `SELECT\n tc.table_name,\n tc.constraint_name,\n kcu.column_name,\n kcu.ordinal_position,\n ref_ns.nspname AS referenced_table_schema,\n ref_cl.relname AS referenced_table_name,\n ref_att.attname AS referenced_column_name,\n rc.delete_rule,\n rc.update_rule\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n AND tc.table_name = kcu.table_name\n JOIN pg_catalog.pg_constraint pgc\n ON pgc.conname = tc.constraint_name\n AND pgc.connamespace = (\n SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = tc.table_schema\n )\n JOIN pg_catalog.pg_class ref_cl\n ON ref_cl.oid = pgc.confrelid\n JOIN pg_catalog.pg_namespace ref_ns\n ON ref_ns.oid = ref_cl.relnamespace\n JOIN pg_catalog.pg_attribute ref_att\n ON ref_att.attrelid = pgc.confrelid\n AND ref_att.attnum = pgc.confkey[kcu.ordinal_position]\n JOIN information_schema.referential_constraints rc\n ON rc.constraint_name = tc.constraint_name\n AND rc.constraint_schema = tc.table_schema\n WHERE tc.table_schema = $1\n AND tc.constraint_type = 'FOREIGN KEY'\n ORDER BY tc.table_name, tc.constraint_name, kcu.ordinal_position`,\n [schema],\n ),\n // Query all unique constraints for all tables in schema (excluding PKs)\n driver.query<{\n table_name: string;\n constraint_name: string;\n column_name: string;\n ordinal_position: number;\n }>(\n `SELECT\n tc.table_name,\n tc.constraint_name,\n kcu.column_name,\n kcu.ordinal_position\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n AND tc.table_name = kcu.table_name\n WHERE tc.table_schema = $1\n AND tc.constraint_type = 'UNIQUE'\n ORDER BY tc.table_name, tc.constraint_name, kcu.ordinal_position`,\n [schema],\n ),\n // Query all indexes for all tables in schema (excluding constraints).\n // `index_position` is the column's position within the index (1-based),\n // derived from `pg_index.indkey` so composite indexes round-trip with\n // their declared column order intact.\n driver.query<{\n tablename: string;\n indexname: string;\n indisunique: boolean;\n attname: string | null;\n index_position: number;\n amname: string | null;\n reloptions: string[] | null;\n }>(\n // `ix.indkey` is an int2vector of column numbers in the order the\n // columns appear in the index definition. Unnest it WITH ORDINALITY\n // so each (index, column) row carries its position in the index,\n // then ORDER BY that position. Without this the rows come back in\n // table-column order (`a.attnum`), which silently shuffles the\n // columns of any composite index whose index order differs from\n // the table order — verification compares against the contract\n // with order-sensitive equality and reports a spurious\n // `index_mismatch`.\n `SELECT\n i.tablename,\n i.indexname,\n ix.indisunique,\n a.attname,\n k.ord AS index_position,\n am.amname,\n ic.reloptions\n FROM pg_indexes i\n JOIN pg_class ic ON ic.relname = i.indexname\n JOIN pg_namespace ins ON ins.oid = ic.relnamespace AND ins.nspname = $1\n JOIN pg_index ix ON ix.indexrelid = ic.oid\n JOIN pg_am am ON am.oid = ic.relam\n JOIN pg_class t ON t.oid = ix.indrelid\n JOIN pg_namespace tn ON tn.oid = t.relnamespace AND tn.nspname = $1\n JOIN LATERAL unnest(ix.indkey::int[]) WITH ORDINALITY AS k(attnum, ord) ON true\n LEFT JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = k.attnum AND a.attnum > 0\n WHERE i.schemaname = $1\n AND NOT EXISTS (\n SELECT 1\n FROM information_schema.table_constraints tc\n WHERE tc.table_schema = $1\n AND tc.table_name = i.tablename\n AND tc.constraint_name = i.indexname\n )\n ORDER BY i.tablename, i.indexname, k.ord`,\n [schema],\n ),\n ]);\n\n // Group results by table name for efficient lookup\n const columnsByTable = groupBy(columnsResult.rows, 'table_name');\n const pksByTable = groupBy(pkResult.rows, 'table_name');\n const fksByTable = groupBy(fkResult.rows, 'table_name');\n const uniquesByTable = groupBy(uniqueResult.rows, 'table_name');\n const indexesByTable = groupBy(indexResult.rows, 'tablename');\n\n // Get set of PK constraint names per table (to exclude from uniques)\n const pkConstraintsByTable = new Map<string, Set<string>>();\n for (const row of pkResult.rows) {\n let constraints = pkConstraintsByTable.get(row.table_name);\n if (!constraints) {\n constraints = new Set();\n pkConstraintsByTable.set(row.table_name, constraints);\n }\n constraints.add(row.constraint_name);\n }\n\n const tables: Record<string, SqlTableIR> = {};\n\n for (const tableRow of tablesResult.rows) {\n const tableName = tableRow.table_name;\n\n // Process columns for this table\n const columns: Record<string, SqlColumnIR> = {};\n for (const colRow of columnsByTable.get(tableName) ?? []) {\n let nativeType = colRow.udt_name;\n const formattedType = colRow.formatted_type\n ? normalizeFormattedType(colRow.formatted_type, colRow.data_type, colRow.udt_name)\n : null;\n if (formattedType) {\n nativeType = formattedType;\n } else if (colRow.data_type === 'character varying' || colRow.data_type === 'character') {\n if (colRow.character_maximum_length) {\n nativeType = `${colRow.data_type}(${colRow.character_maximum_length})`;\n } else {\n nativeType = colRow.data_type;\n }\n } else if (colRow.data_type === 'numeric' || colRow.data_type === 'decimal') {\n if (colRow.numeric_precision && colRow.numeric_scale !== null) {\n nativeType = `${colRow.data_type}(${colRow.numeric_precision},${colRow.numeric_scale})`;\n } else if (colRow.numeric_precision) {\n nativeType = `${colRow.data_type}(${colRow.numeric_precision})`;\n } else {\n nativeType = colRow.data_type;\n }\n } else {\n nativeType = colRow.udt_name || colRow.data_type;\n }\n\n columns[colRow.column_name] = {\n name: colRow.column_name,\n nativeType,\n nullable: colRow.is_nullable === 'YES',\n ...ifDefined('default', colRow.column_default ?? undefined),\n };\n }\n\n // Process primary key\n const pkRows = [...(pksByTable.get(tableName) ?? [])];\n const primaryKeyColumns = pkRows\n .sort((a, b) => a.ordinal_position - b.ordinal_position)\n .map((row) => row.column_name);\n const primaryKey: PrimaryKey | undefined =\n primaryKeyColumns.length > 0\n ? {\n columns: primaryKeyColumns,\n ...(pkRows[0]?.constraint_name ? { name: pkRows[0].constraint_name } : {}),\n }\n : undefined;\n\n // Process foreign keys\n const foreignKeysMap = new Map<\n string,\n {\n columns: string[];\n referencedTable: string;\n referencedSchema: string;\n referencedColumns: string[];\n name: string;\n deleteRule: string;\n updateRule: string;\n }\n >();\n for (const fkRow of fksByTable.get(tableName) ?? []) {\n const existing = foreignKeysMap.get(fkRow.constraint_name);\n if (existing) {\n existing.columns.push(fkRow.column_name);\n existing.referencedColumns.push(fkRow.referenced_column_name);\n } else {\n foreignKeysMap.set(fkRow.constraint_name, {\n columns: [fkRow.column_name],\n referencedTable: fkRow.referenced_table_name,\n referencedSchema: fkRow.referenced_table_schema,\n referencedColumns: [fkRow.referenced_column_name],\n name: fkRow.constraint_name,\n deleteRule: fkRow.delete_rule,\n updateRule: fkRow.update_rule,\n });\n }\n }\n const foreignKeys: readonly SqlForeignKeyIR[] = Array.from(foreignKeysMap.values()).map(\n (fk) => ({\n columns: Object.freeze([...fk.columns]) as readonly string[],\n referencedTable: fk.referencedTable,\n referencedSchema: fk.referencedSchema,\n referencedColumns: Object.freeze([...fk.referencedColumns]) as readonly string[],\n name: fk.name,\n ...ifDefined('onDelete', mapReferentialAction(fk.deleteRule)),\n ...ifDefined('onUpdate', mapReferentialAction(fk.updateRule)),\n }),\n );\n\n // Process unique constraints (excluding those that are also PKs)\n const pkConstraints = pkConstraintsByTable.get(tableName) ?? new Set();\n const uniquesMap = new Map<string, { columns: string[]; name: string }>();\n for (const uniqueRow of uniquesByTable.get(tableName) ?? []) {\n // Skip if this constraint is also a primary key\n if (pkConstraints.has(uniqueRow.constraint_name)) {\n continue;\n }\n const existing = uniquesMap.get(uniqueRow.constraint_name);\n if (existing) {\n existing.columns.push(uniqueRow.column_name);\n } else {\n uniquesMap.set(uniqueRow.constraint_name, {\n columns: [uniqueRow.column_name],\n name: uniqueRow.constraint_name,\n });\n }\n }\n const uniques: readonly SqlUniqueIR[] = Array.from(uniquesMap.values()).map((uq) => ({\n columns: Object.freeze([...uq.columns]) as readonly string[],\n name: uq.name,\n }));\n\n // Process indexes\n const indexesMap = new Map<\n string,\n {\n columns: string[];\n name: string;\n unique: boolean;\n type: string | undefined;\n options: Record<string, string> | undefined;\n }\n >();\n for (const idxRow of indexesByTable.get(tableName) ?? []) {\n if (!idxRow.attname) {\n continue;\n }\n const existing = indexesMap.get(idxRow.indexname);\n if (existing) {\n existing.columns.push(idxRow.attname);\n } else {\n // Drop btree (the Postgres default) so a contract index without an\n // explicit type matches a default-method introspected index without\n // forcing DROP+CREATE on every plan.\n const indexType = idxRow.amname && idxRow.amname !== 'btree' ? idxRow.amname : undefined;\n const indexOptions = parsePgReloptions(idxRow.reloptions, idxRow.indexname);\n indexesMap.set(idxRow.indexname, {\n columns: [idxRow.attname],\n name: idxRow.indexname,\n unique: idxRow.indisunique,\n type: indexType,\n options: indexOptions,\n });\n }\n }\n const indexes: readonly SqlIndexIR[] = Array.from(indexesMap.values()).map((idx) => ({\n columns: Object.freeze([...idx.columns]) as readonly string[],\n name: idx.name,\n unique: idx.unique,\n ...(idx.type !== undefined && { type: idx.type }),\n ...(idx.options !== undefined && { options: idx.options }),\n }));\n\n tables[tableName] = {\n name: tableName,\n columns,\n ...ifDefined('primaryKey', primaryKey),\n foreignKeys,\n uniques,\n indexes,\n };\n }\n\n const storageTypes = await introspectPostgresEnumTypes({ driver, schemaName: schema });\n\n const annotations = {\n pg: {\n schema,\n version: await this.getPostgresVersion(driver),\n ...ifDefined(\n 'storageTypes',\n Object.keys(storageTypes).length > 0 ? storageTypes : undefined,\n ),\n },\n };\n\n return {\n tables,\n annotations,\n };\n }\n\n /**\n * Gets the Postgres version from the database.\n */\n private async getPostgresVersion(\n driver: ControlDriverInstance<'sql', 'postgres'>,\n ): Promise<string> {\n const result = await driver.query<{ version: string }>('SELECT version() AS version', []);\n const versionString = result.rows[0]?.version ?? '';\n // Extract version number from \"PostgreSQL 15.1 ...\" format\n const match = versionString.match(/PostgreSQL (\\d+\\.\\d+)/);\n return match?.[1] ?? 'unknown';\n }\n}\n\n/**\n * Extracts the namespace coordinate ids declared on a contract's storage,\n * or returns an empty array when no contract (or no storage / namespaces)\n * is present. Used by `PostgresControlAdapter.introspect` to decide\n * between the multi-namespace walk and the single-schema fallback.\n */\nfunction extractContractNamespaceIds(contract: unknown): readonly string[] {\n if (contract === null || typeof contract !== 'object') return [];\n const storage = (contract as { storage?: unknown }).storage;\n if (storage === null || typeof storage !== 'object') return [];\n const namespaces = (storage as { namespaces?: unknown }).namespaces;\n if (namespaces === null || typeof namespaces !== 'object') return [];\n return Object.keys(namespaces as Record<string, unknown>);\n}\n\nfunction normalizeFormattedType(formattedType: string, dataType: string, udtName: string): string {\n if (formattedType === 'integer') {\n return 'int4';\n }\n if (formattedType === 'smallint') {\n return 'int2';\n }\n if (formattedType === 'bigint') {\n return 'int8';\n }\n if (formattedType === 'real') {\n return 'float4';\n }\n if (formattedType === 'double precision') {\n return 'float8';\n }\n if (formattedType === 'boolean') {\n return 'bool';\n }\n if (formattedType.startsWith('varchar')) {\n return formattedType.replace('varchar', 'character varying');\n }\n if (formattedType.startsWith('bpchar')) {\n return formattedType.replace('bpchar', 'character');\n }\n if (formattedType.startsWith('varbit')) {\n return formattedType.replace('varbit', 'bit varying');\n }\n if (dataType === 'timestamp with time zone' || udtName === 'timestamptz') {\n return formattedType.replace('timestamp', 'timestamptz').replace(' with time zone', '').trim();\n }\n if (dataType === 'timestamp without time zone' || udtName === 'timestamp') {\n return formattedType.replace(' without time zone', '').trim();\n }\n if (dataType === 'time with time zone' || udtName === 'timetz') {\n return formattedType.replace('time', 'timetz').replace(' with time zone', '').trim();\n }\n if (dataType === 'time without time zone' || udtName === 'time') {\n return formattedType.replace(' without time zone', '').trim();\n }\n // Only dataType === 'USER-DEFINED' should ever be quoted, but this should be safe without\n // checking that explicitly either way\n if (formattedType.startsWith('\"') && formattedType.endsWith('\"')) {\n return formattedType.slice(1, -1);\n }\n return formattedType;\n}\n\n/**\n * The five standard PostgreSQL referential action rules as returned by\n * `information_schema.referential_constraints.delete_rule` / `update_rule`.\n */\ntype PgReferentialActionRule = 'NO ACTION' | 'RESTRICT' | 'CASCADE' | 'SET NULL' | 'SET DEFAULT';\n\nconst PG_REFERENTIAL_ACTION_MAP: Record<PgReferentialActionRule, SqlReferentialAction> = {\n 'NO ACTION': 'noAction',\n RESTRICT: 'restrict',\n CASCADE: 'cascade',\n 'SET NULL': 'setNull',\n 'SET DEFAULT': 'setDefault',\n};\n\n/**\n * Maps a Postgres referential action rule to the canonical SqlReferentialAction.\n * Returns undefined for 'NO ACTION' (the database default) to keep the IR sparse.\n * Throws for unrecognized rules to prevent silent data loss.\n */\nfunction mapReferentialAction(rule: string): SqlReferentialAction | undefined {\n const mapped = PG_REFERENTIAL_ACTION_MAP[rule as PgReferentialActionRule];\n if (mapped === undefined) {\n throw new Error(\n `Unknown PostgreSQL referential action rule: \"${rule}\". Expected one of: NO ACTION, RESTRICT, CASCADE, SET NULL, SET DEFAULT.`,\n );\n }\n if (mapped === 'noAction') return undefined;\n return mapped;\n}\n\n/**\n * Groups an array of objects by a specified key.\n * Returns a Map for O(1) lookup by group key.\n */\n/**\n * Parses a `pg_class.reloptions` array into a `Record<string, string>`.\n *\n * Postgres returns reloptions as a `text[]` whose entries are `key=value`\n * strings; the value side is always a string regardless of the underlying\n * scalar type. The verifier compares contract options to introspected\n * options after coercing both sides to strings, so keeping the raw text\n * here is correct.\n *\n * Returns `undefined` when the input is null/empty (no WITH clause).\n */\nexport function parsePgReloptions(\n reloptions: readonly string[] | null,\n indexName: string,\n): Record<string, string> | undefined {\n if (!reloptions || reloptions.length === 0) {\n return undefined;\n }\n const result: Record<string, string> = {};\n for (const entry of reloptions) {\n const eq = entry.indexOf('=');\n if (eq === -1) {\n throw new Error(\n `Postgres introspection: malformed reloption entry \"${entry}\" on index \"${indexName}\" (expected \"key=value\")`,\n );\n }\n const key = entry.slice(0, eq);\n const value = entry.slice(eq + 1);\n result[key] = value;\n }\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\nfunction groupBy<T, K extends keyof T>(items: readonly T[], key: K): Map<T[K], T[]> {\n const map = new Map<T[K], T[]>();\n for (const item of items) {\n const groupKey = item[key];\n let group = map.get(groupKey);\n if (!group) {\n group = [];\n map.set(groupKey, group);\n }\n group.push(item);\n }\n return map;\n}\n","import type { ExecutionMutationDefaultValue } from '@prisma-next/contract/types';\nimport { timestampNowControlDescriptor } from '@prisma-next/family-sql/control';\nimport type {\n ControlMutationDefaultEntry,\n DefaultFunctionLoweringContext,\n LoweredDefaultResult,\n MutationDefaultGeneratorDescriptor,\n ParsedDefaultFunctionCall,\n} from '@prisma-next/framework-components/control';\nimport {\n builtinGeneratorRegistryMetadata,\n resolveBuiltinGeneratedColumnDescriptor,\n} from '@prisma-next/ids';\n\nfunction invalidArgumentDiagnostic(input: {\n readonly context: DefaultFunctionLoweringContext;\n readonly span: ParsedDefaultFunctionCall['span'];\n readonly message: string;\n}): LoweredDefaultResult {\n return {\n ok: false,\n diagnostic: {\n code: 'PSL_INVALID_DEFAULT_FUNCTION_ARGUMENT',\n message: input.message,\n sourceId: input.context.sourceId,\n span: input.span,\n },\n };\n}\n\nfunction executionGenerator(\n id: ExecutionMutationDefaultValue['id'],\n params?: Record<string, unknown>,\n): LoweredDefaultResult {\n return {\n ok: true,\n value: {\n kind: 'execution',\n generated: {\n kind: 'generator',\n id,\n ...(params ? { params } : {}),\n },\n },\n };\n}\n\nfunction expectNoArgs(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n readonly usage: string;\n}): LoweredDefaultResult | undefined {\n if (input.call.args.length === 0) {\n return undefined;\n }\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.span,\n message: `Default function \"${input.call.name}\" does not accept arguments. Use ${input.usage}.`,\n });\n}\n\nfunction parseIntegerArgument(raw: string): number | undefined {\n const trimmed = raw.trim();\n if (!/^-?\\d+$/.test(trimmed)) {\n return undefined;\n }\n const value = Number(trimmed);\n if (!Number.isInteger(value)) {\n return undefined;\n }\n return value;\n}\n\nfunction parseStringLiteral(raw: string): string | undefined {\n const match = raw.trim().match(/^(['\"])(.*)\\1$/s);\n if (!match) {\n return undefined;\n }\n return match[2] ?? '';\n}\n\nfunction lowerAutoincrement(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n}): LoweredDefaultResult {\n const maybeNoArgs = expectNoArgs({\n call: input.call,\n context: input.context,\n usage: '`autoincrement()`',\n });\n if (maybeNoArgs) {\n return maybeNoArgs;\n }\n return {\n ok: true,\n value: {\n kind: 'storage',\n defaultValue: {\n kind: 'function',\n expression: 'autoincrement()',\n },\n },\n };\n}\n\nfunction lowerNow(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n}): LoweredDefaultResult {\n const maybeNoArgs = expectNoArgs({\n call: input.call,\n context: input.context,\n usage: '`now()`',\n });\n if (maybeNoArgs) {\n return maybeNoArgs;\n }\n return {\n ok: true,\n value: {\n kind: 'storage',\n defaultValue: {\n kind: 'function',\n expression: 'now()',\n },\n },\n };\n}\n\nfunction lowerUuid(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n}): LoweredDefaultResult {\n if (input.call.args.length === 0) {\n return executionGenerator('uuidv4');\n }\n if (input.call.args.length !== 1) {\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.span,\n message:\n 'Default function \"uuid\" accepts at most one version argument: `uuid()`, `uuid(4)`, or `uuid(7)`.',\n });\n }\n const version = parseIntegerArgument(input.call.args[0]?.raw ?? '');\n if (version === 4) {\n return executionGenerator('uuidv4');\n }\n if (version === 7) {\n return executionGenerator('uuidv7');\n }\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.args[0]?.span ?? input.call.span,\n message:\n 'Default function \"uuid\" supports only `uuid()`, `uuid(4)`, or `uuid(7)` in SQL PSL provider v1.',\n });\n}\n\nfunction lowerCuid(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n}): LoweredDefaultResult {\n if (input.call.args.length === 0) {\n return {\n ok: false,\n diagnostic: {\n code: 'PSL_UNKNOWN_DEFAULT_FUNCTION',\n message:\n 'Default function \"cuid()\" is not supported in SQL PSL provider v1. Use `cuid(2)` instead.',\n sourceId: input.context.sourceId,\n span: input.call.span,\n },\n };\n }\n if (input.call.args.length !== 1) {\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.span,\n message: 'Default function \"cuid\" accepts exactly one version argument: `cuid(2)`.',\n });\n }\n const version = parseIntegerArgument(input.call.args[0]?.raw ?? '');\n if (version === 2) {\n return executionGenerator('cuid2');\n }\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.args[0]?.span ?? input.call.span,\n message: 'Default function \"cuid\" supports only `cuid(2)` in SQL PSL provider v1.',\n });\n}\n\nfunction lowerUlid(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n}): LoweredDefaultResult {\n const maybeNoArgs = expectNoArgs({\n call: input.call,\n context: input.context,\n usage: '`ulid()`',\n });\n if (maybeNoArgs) {\n return maybeNoArgs;\n }\n return executionGenerator('ulid');\n}\n\nfunction lowerNanoid(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n}): LoweredDefaultResult {\n if (input.call.args.length === 0) {\n return executionGenerator('nanoid');\n }\n if (input.call.args.length !== 1) {\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.span,\n message:\n 'Default function \"nanoid\" accepts at most one size argument: `nanoid()` or `nanoid(<2-255>)`.',\n });\n }\n const size = parseIntegerArgument(input.call.args[0]?.raw ?? '');\n if (size !== undefined && size >= 2 && size <= 255) {\n return executionGenerator('nanoid', { size });\n }\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.args[0]?.span ?? input.call.span,\n message: 'Default function \"nanoid\" size argument must be an integer between 2 and 255.',\n });\n}\n\nfunction lowerDbgenerated(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n}): LoweredDefaultResult {\n if (input.call.args.length !== 1) {\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.span,\n message:\n 'Default function \"dbgenerated\" requires exactly one string argument: `dbgenerated(\"...\")`.',\n });\n }\n const rawExpression = parseStringLiteral(input.call.args[0]?.raw ?? '');\n if (rawExpression === undefined) {\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.args[0]?.span ?? input.call.span,\n message: 'Default function \"dbgenerated\" argument must be a string literal.',\n });\n }\n if (rawExpression.trim().length === 0) {\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.args[0]?.span ?? input.call.span,\n message: 'Default function \"dbgenerated\" argument cannot be empty.',\n });\n }\n return {\n ok: true,\n value: {\n kind: 'storage',\n defaultValue: {\n kind: 'function',\n expression: rawExpression,\n },\n },\n };\n}\n\nconst postgresDefaultFunctionRegistryEntries = [\n ['autoincrement', { lower: lowerAutoincrement, usageSignatures: ['autoincrement()'] }],\n ['now', { lower: lowerNow, usageSignatures: ['now()'] }],\n ['uuid', { lower: lowerUuid, usageSignatures: ['uuid()', 'uuid(4)', 'uuid(7)'] }],\n ['cuid', { lower: lowerCuid, usageSignatures: ['cuid(2)'] }],\n ['ulid', { lower: lowerUlid, usageSignatures: ['ulid()'] }],\n ['nanoid', { lower: lowerNanoid, usageSignatures: ['nanoid()', 'nanoid(<2-255>)'] }],\n ['dbgenerated', { lower: lowerDbgenerated, usageSignatures: ['dbgenerated(\"...\")'] }],\n] satisfies ReadonlyArray<readonly [string, ControlMutationDefaultEntry]>;\n\nconst postgresScalarTypeDescriptors = new Map<string, string>([\n ['String', 'pg/text@1'],\n ['Boolean', 'pg/bool@1'],\n ['Int', 'pg/int4@1'],\n ['BigInt', 'pg/int8@1'],\n ['Float', 'pg/float8@1'],\n ['Decimal', 'pg/numeric@1'],\n ['DateTime', 'pg/timestamptz@1'],\n ['Json', 'pg/jsonb@1'],\n ['Bytes', 'pg/bytea@1'],\n]);\n\nexport function createPostgresDefaultFunctionRegistry(): ReadonlyMap<\n string,\n ControlMutationDefaultEntry\n> {\n return new Map(postgresDefaultFunctionRegistryEntries);\n}\n\nexport function createPostgresMutationDefaultGeneratorDescriptors(): readonly MutationDefaultGeneratorDescriptor[] {\n return [\n ...builtinGeneratorRegistryMetadata.map(\n ({ id, applicableCodecIds }): MutationDefaultGeneratorDescriptor => ({\n id,\n applicableCodecIds,\n resolveGeneratedColumnDescriptor: ({ generated }) => {\n if (generated.kind !== 'generator' || generated.id !== id) {\n return undefined;\n }\n const descriptor = resolveBuiltinGeneratedColumnDescriptor({\n id,\n ...(generated.params ? { params: generated.params } : {}),\n });\n return {\n codecId: descriptor.type.codecId,\n nativeType: descriptor.type.nativeType,\n ...(descriptor.type.typeRef ? { typeRef: descriptor.type.typeRef } : {}),\n ...(descriptor.typeParams ? { typeParams: descriptor.typeParams } : {}),\n };\n },\n }),\n ),\n timestampNowControlDescriptor(),\n ];\n}\n\nexport function createPostgresScalarTypeDescriptors(): ReadonlyMap<string, string> {\n return new Map(postgresScalarTypeDescriptors);\n}\n","import type { SqlControlAdapterDescriptor } from '@prisma-next/family-sql/control';\nimport type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';\nimport {\n escapeLiteral,\n qualifyName,\n quoteIdentifier,\n SqlEscapeError,\n} from '@prisma-next/target-postgres/sql-utils';\nimport { PostgresControlAdapter } from '../core/control-adapter';\nimport {\n createPostgresDefaultFunctionRegistry,\n createPostgresMutationDefaultGeneratorDescriptors,\n createPostgresScalarTypeDescriptors,\n} from '../core/control-mutation-defaults';\nimport { postgresAdapterDescriptorMeta } from '../core/descriptor-meta';\n\nconst postgresAdapterDescriptor: SqlControlAdapterDescriptor<'postgres'> = {\n ...postgresAdapterDescriptorMeta,\n scalarTypeDescriptors: createPostgresScalarTypeDescriptors(),\n controlMutationDefaults: {\n defaultFunctionRegistry: createPostgresDefaultFunctionRegistry(),\n generatorDescriptors: createPostgresMutationDefaultGeneratorDescriptors(),\n },\n create(stack): SqlControlAdapter<'postgres'> {\n return new PostgresControlAdapter(stack.codecLookup);\n },\n};\n\nexport default postgresAdapterDescriptor;\n\nexport { parsePostgresDefault } from '@prisma-next/target-postgres/default-normalizer';\nexport { normalizeSchemaNativeType } from '@prisma-next/target-postgres/native-type-normalizer';\nexport { PostgresControlAdapter } from '../core/control-adapter';\nexport { escapeLiteral, qualifyName, quoteIdentifier, SqlEscapeError };\n"],"mappings":"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"}
1
+ {"version":3,"file":"control.mjs","names":["parsePostgresDefault","normalizeSchemaNativeType"],"sources":["../src/core/enum-control-hooks.ts","../src/core/control-adapter.ts","../src/core/control-mutation-defaults.ts","../src/exports/control.ts"],"sourcesContent":["import type { ControlDriverInstance } from '@prisma-next/framework-components/control';\nimport { PG_ENUM_CODEC_ID } from '@prisma-next/target-postgres/codec-ids';\n\n/**\n * Codec-typed annotation shape that the introspector writes under\n * `schema.annotations.pg.storageTypes[<typeName>]`. Distinct from\n * `StorageTypeInstance` because the introspector emits a plain literal\n * (no class-instance API surface): only the fields downstream consumers\n * actually read from the introspected envelope.\n */\nexport interface PostgresEnumStorageTypeAnnotation {\n readonly codecId: typeof PG_ENUM_CODEC_ID;\n readonly nativeType: string;\n readonly typeParams: { readonly values: readonly string[] };\n}\n\n/**\n * Postgres enum introspection.\n *\n * Migration planning and schema verification for enum types live at the\n * SQL family layer + the Postgres target's planner-strategies layer (see\n * `nativeEnumPlanCallStrategy` and the family-level `verifyEnumType`\n * walk). Introspection is the only piece that remains here because the\n * control adapter still calls into a codec-keyed dispatch surface\n * (`storage.types` is rebuilt from this map in `control-adapter.ts`);\n * the introspector returns the codec-typed shape that downstream\n * `Contract` consumers expect.\n */\ntype EnumRow = {\n schema_name: string;\n type_name: string;\n values: string[];\n};\n\nconst ENUM_INTROSPECT_QUERY = `\n SELECT\n n.nspname AS schema_name,\n t.typname AS type_name,\n array_agg(e.enumlabel ORDER BY e.enumsortorder) AS values\n FROM pg_type t\n JOIN pg_namespace n ON t.typnamespace = n.oid\n JOIN pg_enum e ON t.oid = e.enumtypid\n WHERE n.nspname = $1\n GROUP BY n.nspname, t.typname\n ORDER BY n.nspname, t.typname\n`;\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((entry) => typeof entry === 'string');\n}\n\n/**\n * Parses a PostgreSQL array value into a JavaScript string array.\n *\n * The `pg` library returns `array_agg` results either as a JS array\n * (when type parsers are configured) or as a string in PostgreSQL array\n * literal format (`{value1,value2,...}`). Handles PG's quoting rules:\n * - Elements containing commas, quotes, backslashes, or whitespace are\n * double-quoted.\n * - Inside quoted elements, `\\\"` represents `\"` and `\\\\` represents `\\`.\n *\n * Returns `null` when the input cannot be parsed as a PG array.\n */\nexport function parsePostgresArray(value: unknown): string[] | null {\n if (isStringArray(value)) {\n return value;\n }\n if (typeof value === 'string' && value.startsWith('{') && value.endsWith('}')) {\n const inner = value.slice(1, -1);\n if (inner === '') {\n return [];\n }\n return parseArrayElements(inner);\n }\n return null;\n}\n\nfunction parseArrayElements(input: string): string[] {\n const result: string[] = [];\n let i = 0;\n while (i < input.length) {\n if (input[i] === ',') {\n i++;\n continue;\n }\n if (input[i] === '\"') {\n i++;\n let element = '';\n while (i < input.length && input[i] !== '\"') {\n if (input[i] === '\\\\' && i + 1 < input.length) {\n i++;\n element += input[i];\n } else {\n element += input[i];\n }\n i++;\n }\n i++;\n result.push(element);\n } else {\n const nextComma = input.indexOf(',', i);\n if (nextComma === -1) {\n result.push(input.slice(i).trim());\n i = input.length;\n } else {\n result.push(input.slice(i, nextComma).trim());\n i = nextComma;\n }\n }\n }\n return result;\n}\n\n/**\n * Reads enum types from the live Postgres schema and returns them in\n * the codec-typed annotation shape consumed by `control-adapter.ts`\n * (which writes them under `schema.annotations.pg.storageTypes`).\n */\nexport async function introspectPostgresEnumTypes(options: {\n readonly driver: ControlDriverInstance<'sql', 'postgres'>;\n readonly schemaName?: string;\n}): Promise<Record<string, PostgresEnumStorageTypeAnnotation>> {\n const namespace = options.schemaName ?? 'public';\n const result = await options.driver.query<EnumRow>(ENUM_INTROSPECT_QUERY, [namespace]);\n const types: Record<string, PostgresEnumStorageTypeAnnotation> = {};\n for (const row of result.rows) {\n const values = parsePostgresArray(row.values);\n if (!values) {\n throw new Error(\n `Failed to parse enum values for type \"${row.type_name}\": ` +\n `unexpected format: ${JSON.stringify(row.values)}`,\n );\n }\n types[row.type_name] = {\n codecId: PG_ENUM_CODEC_ID,\n nativeType: row.type_name,\n typeParams: { values },\n };\n }\n return types;\n}\n","import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport { parseMarkerRowSafely, withMarkerReadErrorHandling } from '@prisma-next/errors/execution';\nimport type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';\nimport { parseContractMarkerRow } from '@prisma-next/family-sql/verify';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport {\n APP_SPACE_ID,\n type ControlDriverInstance,\n} from '@prisma-next/framework-components/control';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport type { PostgresEnumStorageEntry } from '@prisma-next/sql-contract/types';\nimport type {\n AnyQueryAst,\n LoweredStatement,\n LowererContext,\n} from '@prisma-next/sql-relational-core/ast';\nimport type {\n PrimaryKey,\n SqlColumnIR,\n SqlForeignKeyIR,\n SqlIndexIR,\n SqlReferentialAction,\n SqlSchemaIR,\n SqlTableIR,\n SqlUniqueIR,\n} from '@prisma-next/sql-schema-ir/types';\nimport { parsePostgresDefault } from '@prisma-next/target-postgres/default-normalizer';\nimport { readExistingEnumValues } from '@prisma-next/target-postgres/enum-planning';\nimport { normalizeSchemaNativeType } from '@prisma-next/target-postgres/native-type-normalizer';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { createPostgresBuiltinCodecLookup } from './codec-lookup';\nimport { introspectPostgresEnumTypes } from './enum-control-hooks';\nimport { renderLoweredSql } from './sql-renderer';\nimport type { PostgresContract } from './types';\n\nconst POSTGRES_MARKER_TABLE = 'prisma_contract.marker';\n\n/**\n * Postgres control plane adapter for control-plane operations like introspection.\n * Provides target-specific implementations for control-plane domain actions.\n */\nexport class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {\n readonly familyId = 'sql' as const;\n readonly targetId = 'postgres' as const;\n\n private readonly codecLookup: CodecLookup;\n\n /**\n * @param codecLookup - Codec lookup used by the SQL renderer to resolve\n * per-codec metadata at lower-time. Defaults to a Postgres-builtins-only\n * lookup when omitted. Stack-aware callers\n * (`SqlControlAdapterDescriptor.create(stack)`) supply\n * `stack.codecLookup` so extension codecs are visible to the renderer.\n */\n constructor(codecLookup?: CodecLookup) {\n this.codecLookup = codecLookup ?? createPostgresBuiltinCodecLookup();\n }\n\n /**\n * Target-specific normalizer for raw Postgres default expressions.\n * Used by schema verification to normalize raw defaults before comparison.\n */\n readonly normalizeDefault = parsePostgresDefault;\n\n /**\n * Target-specific normalizer for Postgres schema native type names.\n * Used by schema verification to normalize introspected type names\n * before comparison with contract native types.\n */\n readonly normalizeNativeType = normalizeSchemaNativeType;\n\n /**\n * Bridges native `PostgresEnumStorageEntry` IR walks against the Postgres\n * introspection shape (`schema.annotations.pg.storageTypes`). Lets\n * the family-level schema verifier walk enum types without reaching\n * into target-specific annotation layouts itself.\n */\n readonly resolveExistingEnumValues = (\n schema: SqlSchemaIR,\n enumType: PostgresEnumStorageEntry,\n ): readonly string[] | null => readExistingEnumValues(schema, enumType.nativeType);\n\n /**\n * Lower a SQL query AST into a Postgres-flavored `{ sql, params }` payload.\n *\n * Delegates to the shared `renderLoweredSql` renderer so the control adapter\n * emits byte-identical SQL to `PostgresAdapterImpl.lower()` for the same AST\n * and contract. Used at migration plan/emit time (e.g. by `dataTransform`)\n * without instantiating the runtime adapter.\n */\n lower(ast: AnyQueryAst, context: LowererContext<unknown>): LoweredStatement {\n return renderLoweredSql(ast, context.contract as PostgresContract, this.codecLookup);\n }\n\n /**\n * Reads the contract marker from `prisma_contract.marker`. Probes\n * `information_schema.tables` first so a fresh database (where the\n * `prisma_contract` schema doesn't yet exist) returns `null` instead of a\n * \"relation does not exist\" error — some Postgres wire-protocol clients\n * (e.g. PGlite's TCP proxy) don't fully recover from extended-protocol\n * parse errors, so we probe before reading.\n */\n async readMarker(\n driver: ControlDriverInstance<'sql', 'postgres'>,\n space: string,\n ): Promise<ContractMarkerRecord | null> {\n const markerContext = { space, markerLocation: POSTGRES_MARKER_TABLE };\n const exists = await withMarkerReadErrorHandling(\n () =>\n driver.query(\n `select 1\n from information_schema.tables\n where table_schema = $1 and table_name = $2`,\n ['prisma_contract', 'marker'],\n ),\n markerContext,\n );\n if (exists.rows.length === 0) {\n return null;\n }\n\n const result = await withMarkerReadErrorHandling(\n () =>\n driver.query<{\n core_hash: string;\n profile_hash: string;\n contract_json: unknown | null;\n canonical_version: number | null;\n updated_at: Date | string;\n app_tag: string | null;\n meta: unknown | null;\n invariants: readonly string[];\n }>(\n `select\n core_hash,\n profile_hash,\n contract_json,\n canonical_version,\n updated_at,\n app_tag,\n meta,\n invariants\n from prisma_contract.marker\n where space = $1`,\n [space],\n ),\n markerContext,\n );\n\n const row = result.rows[0];\n if (!row) return null;\n return parseMarkerRowSafely(row, parseContractMarkerRow, markerContext);\n }\n\n /**\n * Reads every row from `prisma_contract.marker` and returns them keyed\n * by `space`. Mirrors the existence probe in {@link readMarker}: a\n * fresh database without the `prisma_contract` schema returns an empty\n * map rather than raising \"relation does not exist\".\n */\n async readAllMarkers(\n driver: ControlDriverInstance<'sql', 'postgres'>,\n ): Promise<ReadonlyMap<string, ContractMarkerRecord>> {\n const markerContext = { space: APP_SPACE_ID, markerLocation: POSTGRES_MARKER_TABLE };\n const exists = await withMarkerReadErrorHandling(\n () =>\n driver.query(\n `select 1\n from information_schema.tables\n where table_schema = $1 and table_name = $2`,\n ['prisma_contract', 'marker'],\n ),\n markerContext,\n );\n if (exists.rows.length === 0) {\n return new Map();\n }\n\n const result = await withMarkerReadErrorHandling(\n () =>\n driver.query<{\n space: string;\n core_hash: string;\n profile_hash: string;\n contract_json: unknown | null;\n canonical_version: number | null;\n updated_at: Date | string;\n app_tag: string | null;\n meta: unknown | null;\n invariants: readonly string[];\n }>(\n `select\n space,\n core_hash,\n profile_hash,\n contract_json,\n canonical_version,\n updated_at,\n app_tag,\n meta,\n invariants\n from prisma_contract.marker`,\n ),\n markerContext,\n );\n\n const rows = new Map<string, ContractMarkerRecord>();\n for (const row of result.rows) {\n rows.set(\n row.space,\n parseMarkerRowSafely(row, parseContractMarkerRow, {\n space: row.space,\n markerLocation: POSTGRES_MARKER_TABLE,\n }),\n );\n }\n return rows;\n }\n\n /**\n * Introspects a Postgres database schema and returns a raw SqlSchemaIR.\n *\n * This is a pure schema discovery operation that queries the Postgres catalog\n * and returns the schema structure without type mapping or contract enrichment.\n * Type mapping and enrichment are handled separately by enrichment helpers.\n *\n * When `contract` is provided and its storage declares more than one\n * namespace (or any explicit bound namespace), the adapter walks every\n * declared namespace and merges the per-schema introspection results\n * into a single `SqlSchemaIR`. `UNBOUND_NAMESPACE_ID` resolves to the\n * connection's `current_schema()` so late-bound tables follow the\n * runtime `search_path`. When no contract is passed, the adapter falls\n * back to introspecting the single `schema` argument (defaulting to\n * `'public'`).\n *\n * Uses batched queries to minimize database round trips (6 queries per\n * schema walked).\n *\n * @param driver - ControlDriverInstance<'sql', 'postgres'> instance for executing queries\n * @param contract - Optional contract for contract-guided introspection (multi-namespace walk, filtering)\n * @param schema - Schema name to introspect when no contract is provided (defaults to 'public')\n * @returns Promise resolving to SqlSchemaIR representing the live database schema\n */\n async introspect(\n driver: ControlDriverInstance<'sql', 'postgres'>,\n contract?: unknown,\n schema = 'public',\n ): Promise<SqlSchemaIR> {\n const declaredNamespaces = extractContractNamespaceIds(contract);\n const ir =\n declaredNamespaces.length > 0\n ? await this.introspectNamespaces(driver, declaredNamespaces)\n : await this.introspectSchema(driver, schema);\n // Capture the list of non-system schemas so downstream planners\n // (e.g. `verifyPostgresNamespacePresence`) can determine which\n // contract-declared namespaces need a `CREATE SCHEMA` before the\n // table DDL.\n const existingSchemas = await this.listExistingSchemas(driver);\n const annotations = ir.annotations ?? {};\n const pg = (annotations as { pg?: Record<string, unknown> }).pg ?? {};\n return {\n ...ir,\n annotations: {\n ...annotations,\n pg: { ...pg, existingSchemas },\n },\n };\n }\n\n /**\n * Lists every non-system schema present in the connected database.\n * The introspection consumer (`verifyPostgresNamespacePresence`)\n * treats the result as the authoritative ground truth — declared\n * namespaces whose `ddlSchemaName` is missing from this list become\n * `missing_schema` issues, and the planner emits the matching\n * `CREATE SCHEMA` before table DDL.\n */\n private async listExistingSchemas(\n driver: ControlDriverInstance<'sql', 'postgres'>,\n ): Promise<readonly string[]> {\n const result = await driver.query<{ nspname: string }>(\n `SELECT nspname\n FROM pg_catalog.pg_namespace\n WHERE nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')\n AND nspname NOT LIKE 'pg_temp_%'\n AND nspname NOT LIKE 'pg_toast_temp_%'\n ORDER BY nspname`,\n );\n return result.rows.map((row) => row.nspname);\n }\n\n /**\n * Walks every declared namespace, resolving `UNBOUND_NAMESPACE_ID` to\n * the connection's `current_schema()`, and merges the per-schema results\n * into a single `SqlSchemaIR`. The merged `tables` map is flat (keyed by\n * table name) so callers that look up by `tableName` see every contract\n * table regardless of which namespace it lives in.\n */\n private async introspectNamespaces(\n driver: ControlDriverInstance<'sql', 'postgres'>,\n namespaceIds: readonly string[],\n ): Promise<SqlSchemaIR> {\n const resolvedSchemas = await Promise.all(\n namespaceIds.map(async (id) => {\n if (id === UNBOUND_NAMESPACE_ID) {\n const { rows } = await driver.query<{ current_schema: string }>(\n 'SELECT current_schema() AS current_schema',\n );\n return rows[0]?.current_schema ?? 'public';\n }\n return id;\n }),\n );\n const uniqueSchemas = Array.from(new Set(resolvedSchemas));\n\n const perSchema = await Promise.all(uniqueSchemas.map((s) => this.introspectSchema(driver, s)));\n\n const mergedTables: Record<string, SqlTableIR> = {};\n for (const ir of perSchema) {\n for (const [tableName, table] of Object.entries(ir.tables)) {\n mergedTables[tableName] = table;\n }\n }\n\n // Annotations carry the first schema's metadata (Postgres version,\n // enum storage types). Multi-namespace storage types are introspected\n // per schema; merging them is deferred until a contract actually\n // declares enum types on more than one namespace.\n const firstAnnotations = perSchema[0]?.annotations;\n return {\n tables: mergedTables,\n ...ifDefined('annotations', firstAnnotations),\n };\n }\n\n /**\n * Introspects a single Postgres schema and returns a raw SqlSchemaIR\n * containing only the tables in that schema. Used by `introspect` as\n * the per-namespace walk.\n */\n private async introspectSchema(\n driver: ControlDriverInstance<'sql', 'postgres'>,\n schema: string,\n ): Promise<SqlSchemaIR> {\n // Execute all queries in parallel for efficiency (6 queries instead of 5T+1)\n const [tablesResult, columnsResult, pkResult, fkResult, uniqueResult, indexResult] =\n await Promise.all([\n // Query all tables\n driver.query<{ table_name: string }>(\n `SELECT table_name\n FROM information_schema.tables\n WHERE table_schema = $1\n AND table_type = 'BASE TABLE'\n ORDER BY table_name`,\n [schema],\n ),\n // Query all columns for all tables in schema\n driver.query<{\n table_name: string;\n column_name: string;\n data_type: string;\n udt_name: string;\n is_nullable: string;\n character_maximum_length: number | null;\n numeric_precision: number | null;\n numeric_scale: number | null;\n column_default: string | null;\n formatted_type: string | null;\n }>(\n `SELECT\n c.table_name,\n column_name,\n data_type,\n udt_name,\n is_nullable,\n character_maximum_length,\n numeric_precision,\n numeric_scale,\n column_default,\n format_type(a.atttypid, a.atttypmod) AS formatted_type\n FROM information_schema.columns c\n JOIN pg_catalog.pg_class cl\n ON cl.relname = c.table_name\n JOIN pg_catalog.pg_namespace ns\n ON ns.nspname = c.table_schema\n AND ns.oid = cl.relnamespace\n JOIN pg_catalog.pg_attribute a\n ON a.attrelid = cl.oid\n AND a.attname = c.column_name\n AND a.attnum > 0\n AND NOT a.attisdropped\n WHERE c.table_schema = $1\n ORDER BY c.table_name, c.ordinal_position`,\n [schema],\n ),\n // Query all primary keys for all tables in schema\n driver.query<{\n table_name: string;\n constraint_name: string;\n column_name: string;\n ordinal_position: number;\n }>(\n `SELECT\n tc.table_name,\n tc.constraint_name,\n kcu.column_name,\n kcu.ordinal_position\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n AND tc.table_name = kcu.table_name\n WHERE tc.table_schema = $1\n AND tc.constraint_type = 'PRIMARY KEY'\n ORDER BY tc.table_name, kcu.ordinal_position`,\n [schema],\n ),\n // Query all foreign keys for all tables in schema, including referential actions.\n // Uses pg_catalog for correct positional pairing of composite FK columns\n // (information_schema.constraint_column_usage lacks ordinal_position,\n // which causes Cartesian products for multi-column FKs).\n driver.query<{\n table_name: string;\n constraint_name: string;\n column_name: string;\n ordinal_position: number;\n referenced_table_schema: string;\n referenced_table_name: string;\n referenced_column_name: string;\n delete_rule: string;\n update_rule: string;\n }>(\n `SELECT\n tc.table_name,\n tc.constraint_name,\n kcu.column_name,\n kcu.ordinal_position,\n ref_ns.nspname AS referenced_table_schema,\n ref_cl.relname AS referenced_table_name,\n ref_att.attname AS referenced_column_name,\n rc.delete_rule,\n rc.update_rule\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n AND tc.table_name = kcu.table_name\n JOIN pg_catalog.pg_constraint pgc\n ON pgc.conname = tc.constraint_name\n AND pgc.connamespace = (\n SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = tc.table_schema\n )\n JOIN pg_catalog.pg_class ref_cl\n ON ref_cl.oid = pgc.confrelid\n JOIN pg_catalog.pg_namespace ref_ns\n ON ref_ns.oid = ref_cl.relnamespace\n JOIN pg_catalog.pg_attribute ref_att\n ON ref_att.attrelid = pgc.confrelid\n AND ref_att.attnum = pgc.confkey[kcu.ordinal_position]\n JOIN information_schema.referential_constraints rc\n ON rc.constraint_name = tc.constraint_name\n AND rc.constraint_schema = tc.table_schema\n WHERE tc.table_schema = $1\n AND tc.constraint_type = 'FOREIGN KEY'\n ORDER BY tc.table_name, tc.constraint_name, kcu.ordinal_position`,\n [schema],\n ),\n // Query all unique constraints for all tables in schema (excluding PKs)\n driver.query<{\n table_name: string;\n constraint_name: string;\n column_name: string;\n ordinal_position: number;\n }>(\n `SELECT\n tc.table_name,\n tc.constraint_name,\n kcu.column_name,\n kcu.ordinal_position\n FROM information_schema.table_constraints tc\n JOIN information_schema.key_column_usage kcu\n ON tc.constraint_name = kcu.constraint_name\n AND tc.table_schema = kcu.table_schema\n AND tc.table_name = kcu.table_name\n WHERE tc.table_schema = $1\n AND tc.constraint_type = 'UNIQUE'\n ORDER BY tc.table_name, tc.constraint_name, kcu.ordinal_position`,\n [schema],\n ),\n // Query all indexes for all tables in schema (excluding constraints).\n // `index_position` is the column's position within the index (1-based),\n // derived from `pg_index.indkey` so composite indexes round-trip with\n // their declared column order intact.\n driver.query<{\n tablename: string;\n indexname: string;\n indisunique: boolean;\n attname: string | null;\n index_position: number;\n amname: string | null;\n reloptions: string[] | null;\n }>(\n // `ix.indkey` is an int2vector of column numbers in the order the\n // columns appear in the index definition. Unnest it WITH ORDINALITY\n // so each (index, column) row carries its position in the index,\n // then ORDER BY that position. Without this the rows come back in\n // table-column order (`a.attnum`), which silently shuffles the\n // columns of any composite index whose index order differs from\n // the table order — verification compares against the contract\n // with order-sensitive equality and reports a spurious\n // `index_mismatch`.\n `SELECT\n i.tablename,\n i.indexname,\n ix.indisunique,\n a.attname,\n k.ord AS index_position,\n am.amname,\n ic.reloptions\n FROM pg_indexes i\n JOIN pg_class ic ON ic.relname = i.indexname\n JOIN pg_namespace ins ON ins.oid = ic.relnamespace AND ins.nspname = $1\n JOIN pg_index ix ON ix.indexrelid = ic.oid\n JOIN pg_am am ON am.oid = ic.relam\n JOIN pg_class t ON t.oid = ix.indrelid\n JOIN pg_namespace tn ON tn.oid = t.relnamespace AND tn.nspname = $1\n JOIN LATERAL unnest(ix.indkey::int[]) WITH ORDINALITY AS k(attnum, ord) ON true\n LEFT JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = k.attnum AND a.attnum > 0\n WHERE i.schemaname = $1\n AND NOT EXISTS (\n SELECT 1\n FROM information_schema.table_constraints tc\n WHERE tc.table_schema = $1\n AND tc.table_name = i.tablename\n AND tc.constraint_name = i.indexname\n )\n ORDER BY i.tablename, i.indexname, k.ord`,\n [schema],\n ),\n ]);\n\n // Group results by table name for efficient lookup\n const columnsByTable = groupBy(columnsResult.rows, 'table_name');\n const pksByTable = groupBy(pkResult.rows, 'table_name');\n const fksByTable = groupBy(fkResult.rows, 'table_name');\n const uniquesByTable = groupBy(uniqueResult.rows, 'table_name');\n const indexesByTable = groupBy(indexResult.rows, 'tablename');\n\n // Get set of PK constraint names per table (to exclude from uniques)\n const pkConstraintsByTable = new Map<string, Set<string>>();\n for (const row of pkResult.rows) {\n let constraints = pkConstraintsByTable.get(row.table_name);\n if (!constraints) {\n constraints = new Set();\n pkConstraintsByTable.set(row.table_name, constraints);\n }\n constraints.add(row.constraint_name);\n }\n\n const tables: Record<string, SqlTableIR> = {};\n\n for (const tableRow of tablesResult.rows) {\n const tableName = tableRow.table_name;\n\n // Process columns for this table\n const columns: Record<string, SqlColumnIR> = {};\n for (const colRow of columnsByTable.get(tableName) ?? []) {\n let nativeType = colRow.udt_name;\n const formattedType = colRow.formatted_type\n ? normalizeFormattedType(colRow.formatted_type, colRow.data_type, colRow.udt_name)\n : null;\n if (formattedType) {\n nativeType = formattedType;\n } else if (colRow.data_type === 'character varying' || colRow.data_type === 'character') {\n if (colRow.character_maximum_length) {\n nativeType = `${colRow.data_type}(${colRow.character_maximum_length})`;\n } else {\n nativeType = colRow.data_type;\n }\n } else if (colRow.data_type === 'numeric' || colRow.data_type === 'decimal') {\n if (colRow.numeric_precision && colRow.numeric_scale !== null) {\n nativeType = `${colRow.data_type}(${colRow.numeric_precision},${colRow.numeric_scale})`;\n } else if (colRow.numeric_precision) {\n nativeType = `${colRow.data_type}(${colRow.numeric_precision})`;\n } else {\n nativeType = colRow.data_type;\n }\n } else {\n nativeType = colRow.udt_name || colRow.data_type;\n }\n\n columns[colRow.column_name] = {\n name: colRow.column_name,\n nativeType,\n nullable: colRow.is_nullable === 'YES',\n ...ifDefined('default', colRow.column_default ?? undefined),\n };\n }\n\n // Process primary key\n const pkRows = [...(pksByTable.get(tableName) ?? [])];\n const primaryKeyColumns = pkRows\n .sort((a, b) => a.ordinal_position - b.ordinal_position)\n .map((row) => row.column_name);\n const primaryKey: PrimaryKey | undefined =\n primaryKeyColumns.length > 0\n ? {\n columns: primaryKeyColumns,\n ...(pkRows[0]?.constraint_name ? { name: pkRows[0].constraint_name } : {}),\n }\n : undefined;\n\n // Process foreign keys\n const foreignKeysMap = new Map<\n string,\n {\n columns: string[];\n referencedTable: string;\n referencedSchema: string;\n referencedColumns: string[];\n name: string;\n deleteRule: string;\n updateRule: string;\n }\n >();\n for (const fkRow of fksByTable.get(tableName) ?? []) {\n const existing = foreignKeysMap.get(fkRow.constraint_name);\n if (existing) {\n existing.columns.push(fkRow.column_name);\n existing.referencedColumns.push(fkRow.referenced_column_name);\n } else {\n foreignKeysMap.set(fkRow.constraint_name, {\n columns: [fkRow.column_name],\n referencedTable: fkRow.referenced_table_name,\n referencedSchema: fkRow.referenced_table_schema,\n referencedColumns: [fkRow.referenced_column_name],\n name: fkRow.constraint_name,\n deleteRule: fkRow.delete_rule,\n updateRule: fkRow.update_rule,\n });\n }\n }\n const foreignKeys: readonly SqlForeignKeyIR[] = Array.from(foreignKeysMap.values()).map(\n (fk) => ({\n columns: Object.freeze([...fk.columns]) as readonly string[],\n referencedTable: fk.referencedTable,\n referencedSchema: fk.referencedSchema,\n referencedColumns: Object.freeze([...fk.referencedColumns]) as readonly string[],\n name: fk.name,\n ...ifDefined('onDelete', mapReferentialAction(fk.deleteRule)),\n ...ifDefined('onUpdate', mapReferentialAction(fk.updateRule)),\n }),\n );\n\n // Process unique constraints (excluding those that are also PKs)\n const pkConstraints = pkConstraintsByTable.get(tableName) ?? new Set();\n const uniquesMap = new Map<string, { columns: string[]; name: string }>();\n for (const uniqueRow of uniquesByTable.get(tableName) ?? []) {\n // Skip if this constraint is also a primary key\n if (pkConstraints.has(uniqueRow.constraint_name)) {\n continue;\n }\n const existing = uniquesMap.get(uniqueRow.constraint_name);\n if (existing) {\n existing.columns.push(uniqueRow.column_name);\n } else {\n uniquesMap.set(uniqueRow.constraint_name, {\n columns: [uniqueRow.column_name],\n name: uniqueRow.constraint_name,\n });\n }\n }\n const uniques: readonly SqlUniqueIR[] = Array.from(uniquesMap.values()).map((uq) => ({\n columns: Object.freeze([...uq.columns]) as readonly string[],\n name: uq.name,\n }));\n\n // Process indexes\n const indexesMap = new Map<\n string,\n {\n columns: string[];\n name: string;\n unique: boolean;\n type: string | undefined;\n options: Record<string, string> | undefined;\n }\n >();\n for (const idxRow of indexesByTable.get(tableName) ?? []) {\n if (!idxRow.attname) {\n continue;\n }\n const existing = indexesMap.get(idxRow.indexname);\n if (existing) {\n existing.columns.push(idxRow.attname);\n } else {\n // Drop btree (the Postgres default) so a contract index without an\n // explicit type matches a default-method introspected index without\n // forcing DROP+CREATE on every plan.\n const indexType = idxRow.amname && idxRow.amname !== 'btree' ? idxRow.amname : undefined;\n const indexOptions = parsePgReloptions(idxRow.reloptions, idxRow.indexname);\n indexesMap.set(idxRow.indexname, {\n columns: [idxRow.attname],\n name: idxRow.indexname,\n unique: idxRow.indisunique,\n type: indexType,\n options: indexOptions,\n });\n }\n }\n const indexes: readonly SqlIndexIR[] = Array.from(indexesMap.values()).map((idx) => ({\n columns: Object.freeze([...idx.columns]) as readonly string[],\n name: idx.name,\n unique: idx.unique,\n ...(idx.type !== undefined && { type: idx.type }),\n ...(idx.options !== undefined && { options: idx.options }),\n }));\n\n tables[tableName] = {\n name: tableName,\n columns,\n ...ifDefined('primaryKey', primaryKey),\n foreignKeys,\n uniques,\n indexes,\n };\n }\n\n const storageTypes = await introspectPostgresEnumTypes({ driver, schemaName: schema });\n\n const annotations = {\n pg: {\n schema,\n version: await this.getPostgresVersion(driver),\n ...ifDefined(\n 'storageTypes',\n Object.keys(storageTypes).length > 0 ? storageTypes : undefined,\n ),\n },\n };\n\n return {\n tables,\n annotations,\n };\n }\n\n /**\n * Gets the Postgres version from the database.\n */\n private async getPostgresVersion(\n driver: ControlDriverInstance<'sql', 'postgres'>,\n ): Promise<string> {\n const result = await driver.query<{ version: string }>('SELECT version() AS version', []);\n const versionString = result.rows[0]?.version ?? '';\n // Extract version number from \"PostgreSQL 15.1 ...\" format\n const match = versionString.match(/PostgreSQL (\\d+\\.\\d+)/);\n return match?.[1] ?? 'unknown';\n }\n}\n\n/**\n * Extracts the namespace coordinate ids declared on a contract's storage,\n * or returns an empty array when no contract (or no storage / namespaces)\n * is present. Used by `PostgresControlAdapter.introspect` to decide\n * between the multi-namespace walk and the single-schema fallback.\n */\nfunction extractContractNamespaceIds(contract: unknown): readonly string[] {\n if (contract === null || typeof contract !== 'object') return [];\n const storage = (contract as { storage?: unknown }).storage;\n if (storage === null || typeof storage !== 'object') return [];\n const namespaces = (storage as { namespaces?: unknown }).namespaces;\n if (namespaces === null || typeof namespaces !== 'object') return [];\n return Object.keys(namespaces as Record<string, unknown>);\n}\n\nfunction normalizeFormattedType(formattedType: string, dataType: string, udtName: string): string {\n if (formattedType === 'integer') {\n return 'int4';\n }\n if (formattedType === 'smallint') {\n return 'int2';\n }\n if (formattedType === 'bigint') {\n return 'int8';\n }\n if (formattedType === 'real') {\n return 'float4';\n }\n if (formattedType === 'double precision') {\n return 'float8';\n }\n if (formattedType === 'boolean') {\n return 'bool';\n }\n if (formattedType.startsWith('varchar')) {\n return formattedType.replace('varchar', 'character varying');\n }\n if (formattedType.startsWith('bpchar')) {\n return formattedType.replace('bpchar', 'character');\n }\n if (formattedType.startsWith('varbit')) {\n return formattedType.replace('varbit', 'bit varying');\n }\n if (dataType === 'timestamp with time zone' || udtName === 'timestamptz') {\n return formattedType.replace('timestamp', 'timestamptz').replace(' with time zone', '').trim();\n }\n if (dataType === 'timestamp without time zone' || udtName === 'timestamp') {\n return formattedType.replace(' without time zone', '').trim();\n }\n if (dataType === 'time with time zone' || udtName === 'timetz') {\n return formattedType.replace('time', 'timetz').replace(' with time zone', '').trim();\n }\n if (dataType === 'time without time zone' || udtName === 'time') {\n return formattedType.replace(' without time zone', '').trim();\n }\n // Only dataType === 'USER-DEFINED' should ever be quoted, but this should be safe without\n // checking that explicitly either way\n if (formattedType.startsWith('\"') && formattedType.endsWith('\"')) {\n return formattedType.slice(1, -1);\n }\n return formattedType;\n}\n\n/**\n * The five standard PostgreSQL referential action rules as returned by\n * `information_schema.referential_constraints.delete_rule` / `update_rule`.\n */\ntype PgReferentialActionRule = 'NO ACTION' | 'RESTRICT' | 'CASCADE' | 'SET NULL' | 'SET DEFAULT';\n\nconst PG_REFERENTIAL_ACTION_MAP: Record<PgReferentialActionRule, SqlReferentialAction> = {\n 'NO ACTION': 'noAction',\n RESTRICT: 'restrict',\n CASCADE: 'cascade',\n 'SET NULL': 'setNull',\n 'SET DEFAULT': 'setDefault',\n};\n\n/**\n * Maps a Postgres referential action rule to the canonical SqlReferentialAction.\n * Returns undefined for 'NO ACTION' (the database default) to keep the IR sparse.\n * Throws for unrecognized rules to prevent silent data loss.\n */\nfunction mapReferentialAction(rule: string): SqlReferentialAction | undefined {\n const mapped = PG_REFERENTIAL_ACTION_MAP[rule as PgReferentialActionRule];\n if (mapped === undefined) {\n throw new Error(\n `Unknown PostgreSQL referential action rule: \"${rule}\". Expected one of: NO ACTION, RESTRICT, CASCADE, SET NULL, SET DEFAULT.`,\n );\n }\n if (mapped === 'noAction') return undefined;\n return mapped;\n}\n\n/**\n * Groups an array of objects by a specified key.\n * Returns a Map for O(1) lookup by group key.\n */\n/**\n * Parses a `pg_class.reloptions` array into a `Record<string, string>`.\n *\n * Postgres returns reloptions as a `text[]` whose entries are `key=value`\n * strings; the value side is always a string regardless of the underlying\n * scalar type. The verifier compares contract options to introspected\n * options after coercing both sides to strings, so keeping the raw text\n * here is correct.\n *\n * Returns `undefined` when the input is null/empty (no WITH clause).\n */\nexport function parsePgReloptions(\n reloptions: readonly string[] | null,\n indexName: string,\n): Record<string, string> | undefined {\n if (!reloptions || reloptions.length === 0) {\n return undefined;\n }\n const result: Record<string, string> = {};\n for (const entry of reloptions) {\n const eq = entry.indexOf('=');\n if (eq === -1) {\n throw new Error(\n `Postgres introspection: malformed reloption entry \"${entry}\" on index \"${indexName}\" (expected \"key=value\")`,\n );\n }\n const key = entry.slice(0, eq);\n const value = entry.slice(eq + 1);\n result[key] = value;\n }\n return Object.keys(result).length > 0 ? result : undefined;\n}\n\nfunction groupBy<T, K extends keyof T>(items: readonly T[], key: K): Map<T[K], T[]> {\n const map = new Map<T[K], T[]>();\n for (const item of items) {\n const groupKey = item[key];\n let group = map.get(groupKey);\n if (!group) {\n group = [];\n map.set(groupKey, group);\n }\n group.push(item);\n }\n return map;\n}\n","import type { ExecutionMutationDefaultValue } from '@prisma-next/contract/types';\nimport { timestampNowControlDescriptor } from '@prisma-next/family-sql/control';\nimport type {\n ControlMutationDefaultEntry,\n DefaultFunctionLoweringContext,\n LoweredDefaultResult,\n MutationDefaultGeneratorDescriptor,\n ParsedDefaultFunctionCall,\n} from '@prisma-next/framework-components/control';\nimport {\n builtinGeneratorRegistryMetadata,\n resolveBuiltinGeneratedColumnDescriptor,\n} from '@prisma-next/ids';\n\nfunction invalidArgumentDiagnostic(input: {\n readonly context: DefaultFunctionLoweringContext;\n readonly span: ParsedDefaultFunctionCall['span'];\n readonly message: string;\n}): LoweredDefaultResult {\n return {\n ok: false,\n diagnostic: {\n code: 'PSL_INVALID_DEFAULT_FUNCTION_ARGUMENT',\n message: input.message,\n sourceId: input.context.sourceId,\n span: input.span,\n },\n };\n}\n\nfunction executionGenerator(\n id: ExecutionMutationDefaultValue['id'],\n params?: Record<string, unknown>,\n): LoweredDefaultResult {\n return {\n ok: true,\n value: {\n kind: 'execution',\n generated: {\n kind: 'generator',\n id,\n ...(params ? { params } : {}),\n },\n },\n };\n}\n\nfunction expectNoArgs(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n readonly usage: string;\n}): LoweredDefaultResult | undefined {\n if (input.call.args.length === 0) {\n return undefined;\n }\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.span,\n message: `Default function \"${input.call.name}\" does not accept arguments. Use ${input.usage}.`,\n });\n}\n\nfunction parseIntegerArgument(raw: string): number | undefined {\n const trimmed = raw.trim();\n if (!/^-?\\d+$/.test(trimmed)) {\n return undefined;\n }\n const value = Number(trimmed);\n if (!Number.isInteger(value)) {\n return undefined;\n }\n return value;\n}\n\nfunction parseStringLiteral(raw: string): string | undefined {\n const match = raw.trim().match(/^(['\"])(.*)\\1$/s);\n if (!match) {\n return undefined;\n }\n return match[2] ?? '';\n}\n\nfunction lowerAutoincrement(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n}): LoweredDefaultResult {\n const maybeNoArgs = expectNoArgs({\n call: input.call,\n context: input.context,\n usage: '`autoincrement()`',\n });\n if (maybeNoArgs) {\n return maybeNoArgs;\n }\n return {\n ok: true,\n value: {\n kind: 'storage',\n defaultValue: {\n kind: 'function',\n expression: 'autoincrement()',\n },\n },\n };\n}\n\nfunction lowerNow(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n}): LoweredDefaultResult {\n const maybeNoArgs = expectNoArgs({\n call: input.call,\n context: input.context,\n usage: '`now()`',\n });\n if (maybeNoArgs) {\n return maybeNoArgs;\n }\n return {\n ok: true,\n value: {\n kind: 'storage',\n defaultValue: {\n kind: 'function',\n expression: 'now()',\n },\n },\n };\n}\n\nfunction lowerUuid(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n}): LoweredDefaultResult {\n if (input.call.args.length === 0) {\n return executionGenerator('uuidv4');\n }\n if (input.call.args.length !== 1) {\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.span,\n message:\n 'Default function \"uuid\" accepts at most one version argument: `uuid()`, `uuid(4)`, or `uuid(7)`.',\n });\n }\n const version = parseIntegerArgument(input.call.args[0]?.raw ?? '');\n if (version === 4) {\n return executionGenerator('uuidv4');\n }\n if (version === 7) {\n return executionGenerator('uuidv7');\n }\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.args[0]?.span ?? input.call.span,\n message:\n 'Default function \"uuid\" supports only `uuid()`, `uuid(4)`, or `uuid(7)` in SQL PSL provider v1.',\n });\n}\n\nfunction lowerCuid(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n}): LoweredDefaultResult {\n if (input.call.args.length === 0) {\n return {\n ok: false,\n diagnostic: {\n code: 'PSL_UNKNOWN_DEFAULT_FUNCTION',\n message:\n 'Default function \"cuid()\" is not supported in SQL PSL provider v1. Use `cuid(2)` instead.',\n sourceId: input.context.sourceId,\n span: input.call.span,\n },\n };\n }\n if (input.call.args.length !== 1) {\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.span,\n message: 'Default function \"cuid\" accepts exactly one version argument: `cuid(2)`.',\n });\n }\n const version = parseIntegerArgument(input.call.args[0]?.raw ?? '');\n if (version === 2) {\n return executionGenerator('cuid2');\n }\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.args[0]?.span ?? input.call.span,\n message: 'Default function \"cuid\" supports only `cuid(2)` in SQL PSL provider v1.',\n });\n}\n\nfunction lowerUlid(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n}): LoweredDefaultResult {\n const maybeNoArgs = expectNoArgs({\n call: input.call,\n context: input.context,\n usage: '`ulid()`',\n });\n if (maybeNoArgs) {\n return maybeNoArgs;\n }\n return executionGenerator('ulid');\n}\n\nfunction lowerNanoid(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n}): LoweredDefaultResult {\n if (input.call.args.length === 0) {\n return executionGenerator('nanoid');\n }\n if (input.call.args.length !== 1) {\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.span,\n message:\n 'Default function \"nanoid\" accepts at most one size argument: `nanoid()` or `nanoid(<2-255>)`.',\n });\n }\n const size = parseIntegerArgument(input.call.args[0]?.raw ?? '');\n if (size !== undefined && size >= 2 && size <= 255) {\n return executionGenerator('nanoid', { size });\n }\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.args[0]?.span ?? input.call.span,\n message: 'Default function \"nanoid\" size argument must be an integer between 2 and 255.',\n });\n}\n\nfunction lowerDbgenerated(input: {\n readonly call: ParsedDefaultFunctionCall;\n readonly context: DefaultFunctionLoweringContext;\n}): LoweredDefaultResult {\n if (input.call.args.length !== 1) {\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.span,\n message:\n 'Default function \"dbgenerated\" requires exactly one string argument: `dbgenerated(\"...\")`.',\n });\n }\n const rawExpression = parseStringLiteral(input.call.args[0]?.raw ?? '');\n if (rawExpression === undefined) {\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.args[0]?.span ?? input.call.span,\n message: 'Default function \"dbgenerated\" argument must be a string literal.',\n });\n }\n if (rawExpression.trim().length === 0) {\n return invalidArgumentDiagnostic({\n context: input.context,\n span: input.call.args[0]?.span ?? input.call.span,\n message: 'Default function \"dbgenerated\" argument cannot be empty.',\n });\n }\n return {\n ok: true,\n value: {\n kind: 'storage',\n defaultValue: {\n kind: 'function',\n expression: rawExpression,\n },\n },\n };\n}\n\nconst postgresDefaultFunctionRegistryEntries = [\n ['autoincrement', { lower: lowerAutoincrement, usageSignatures: ['autoincrement()'] }],\n ['now', { lower: lowerNow, usageSignatures: ['now()'] }],\n ['uuid', { lower: lowerUuid, usageSignatures: ['uuid()', 'uuid(4)', 'uuid(7)'] }],\n ['cuid', { lower: lowerCuid, usageSignatures: ['cuid(2)'] }],\n ['ulid', { lower: lowerUlid, usageSignatures: ['ulid()'] }],\n ['nanoid', { lower: lowerNanoid, usageSignatures: ['nanoid()', 'nanoid(<2-255>)'] }],\n ['dbgenerated', { lower: lowerDbgenerated, usageSignatures: ['dbgenerated(\"...\")'] }],\n] satisfies ReadonlyArray<readonly [string, ControlMutationDefaultEntry]>;\n\nconst postgresScalarTypeDescriptors = new Map<string, string>([\n ['String', 'pg/text@1'],\n ['Boolean', 'pg/bool@1'],\n ['Int', 'pg/int4@1'],\n ['BigInt', 'pg/int8@1'],\n ['Float', 'pg/float8@1'],\n ['Decimal', 'pg/numeric@1'],\n ['DateTime', 'pg/timestamptz@1'],\n ['Json', 'pg/jsonb@1'],\n ['Bytes', 'pg/bytea@1'],\n]);\n\nexport function createPostgresDefaultFunctionRegistry(): ReadonlyMap<\n string,\n ControlMutationDefaultEntry\n> {\n return new Map(postgresDefaultFunctionRegistryEntries);\n}\n\nexport function createPostgresMutationDefaultGeneratorDescriptors(): readonly MutationDefaultGeneratorDescriptor[] {\n return [\n ...builtinGeneratorRegistryMetadata.map(\n ({ id, applicableCodecIds }): MutationDefaultGeneratorDescriptor => ({\n id,\n applicableCodecIds,\n resolveGeneratedColumnDescriptor: ({ generated }) => {\n if (generated.kind !== 'generator' || generated.id !== id) {\n return undefined;\n }\n const descriptor = resolveBuiltinGeneratedColumnDescriptor({\n id,\n ...(generated.params ? { params: generated.params } : {}),\n });\n return {\n codecId: descriptor.type.codecId,\n nativeType: descriptor.type.nativeType,\n ...(descriptor.type.typeRef ? { typeRef: descriptor.type.typeRef } : {}),\n ...(descriptor.typeParams ? { typeParams: descriptor.typeParams } : {}),\n };\n },\n }),\n ),\n timestampNowControlDescriptor(),\n ];\n}\n\nexport function createPostgresScalarTypeDescriptors(): ReadonlyMap<string, string> {\n return new Map(postgresScalarTypeDescriptors);\n}\n","import type { SqlControlAdapterDescriptor } from '@prisma-next/family-sql/control';\nimport type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';\nimport {\n escapeLiteral,\n qualifyName,\n quoteIdentifier,\n SqlEscapeError,\n} from '@prisma-next/target-postgres/sql-utils';\nimport { PostgresControlAdapter } from '../core/control-adapter';\nimport {\n createPostgresDefaultFunctionRegistry,\n createPostgresMutationDefaultGeneratorDescriptors,\n createPostgresScalarTypeDescriptors,\n} from '../core/control-mutation-defaults';\nimport { postgresAdapterDescriptorMeta } from '../core/descriptor-meta';\n\nconst postgresAdapterDescriptor: SqlControlAdapterDescriptor<'postgres'> = {\n ...postgresAdapterDescriptorMeta,\n scalarTypeDescriptors: createPostgresScalarTypeDescriptors(),\n controlMutationDefaults: {\n defaultFunctionRegistry: createPostgresDefaultFunctionRegistry(),\n generatorDescriptors: createPostgresMutationDefaultGeneratorDescriptors(),\n },\n create(stack): SqlControlAdapter<'postgres'> {\n return new PostgresControlAdapter(stack.codecLookup);\n },\n};\n\nexport default postgresAdapterDescriptor;\n\nexport { parsePostgresDefault } from '@prisma-next/target-postgres/default-normalizer';\nexport { normalizeSchemaNativeType } from '@prisma-next/target-postgres/native-type-normalizer';\nexport { PostgresControlAdapter } from '../core/control-adapter';\nexport { escapeLiteral, qualifyName, quoteIdentifier, SqlEscapeError };\n"],"mappings":"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"}
package/dist/runtime.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as createPostgresAdapter } from "./adapter-DorkJByg.mjs";
1
+ import { t as createPostgresAdapter } from "./adapter-DWa9-y1t.mjs";
2
2
  import { n as postgresQueryOperations, t as postgresAdapterDescriptorMeta } from "./descriptor-meta-ZIv9PU-5.mjs";
3
3
  import { extractCodecLookup } from "@prisma-next/framework-components/control";
4
4
  import { postgresCodecRegistry } from "@prisma-next/target-postgres/codecs";
@@ -407,9 +407,7 @@ function renderInsert(ast, contract, pim) {
407
407
  const updateEntries = Object.entries(action.set);
408
408
  if (updateEntries.length === 0) throw new Error("INSERT onConflict do-update-set requires at least one assignment");
409
409
  const updates = updateEntries.map(([colName, value]) => {
410
- const target = quoteIdentifier(colName);
411
- if (value.kind === "param-ref" || value.kind === "prepared-param-ref") return `${target} = ${renderParamRef(value, pim)}`;
412
- return `${target} = ${renderColumn(value)}`;
410
+ return `${quoteIdentifier(colName)} = ${renderExpr(value, contract, pim)}`;
413
411
  });
414
412
  return ` ON CONFLICT (${conflictColumns.join(", ")}) DO UPDATE SET ${updates.join(", ")}`;
415
413
  }
@@ -423,20 +421,7 @@ function renderUpdate(ast, contract, pim) {
423
421
  const setEntries = Object.entries(ast.set);
424
422
  if (setEntries.length === 0) throw new Error("UPDATE requires at least one SET assignment");
425
423
  const setClauses = setEntries.map(([col, val]) => {
426
- const column = quoteIdentifier(col);
427
- let value;
428
- switch (val.kind) {
429
- case "param-ref":
430
- case "prepared-param-ref":
431
- value = renderParamRef(val, pim);
432
- break;
433
- case "column-ref":
434
- value = renderColumn(val);
435
- break;
436
- // v8 ignore next 4
437
- default: throw new Error(`Unsupported value node in UPDATE: ${val.kind}`);
438
- }
439
- return `${column} = ${value}`;
424
+ return `${quoteIdentifier(col)} = ${renderExpr(val, contract, pim)}`;
440
425
  });
441
426
  const whereClause = ast.where ? ` WHERE ${renderWhere(ast.where, contract, pim)}` : "";
442
427
  const returningClause = ast.returning?.length ? ` RETURNING ${renderReturning(ast.returning, contract, pim)}` : "";
@@ -459,4 +444,4 @@ function renderRawSql(ast, contract, pim) {
459
444
  //#endregion
460
445
  export { createPostgresBuiltinCodecLookup as n, renderLoweredSql as t };
461
446
 
462
- //# sourceMappingURL=sql-renderer-iX5DLUi7.mjs.map
447
+ //# sourceMappingURL=sql-renderer-DFMHmkt_.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sql-renderer-iX5DLUi7.mjs","names":[],"sources":["../src/core/codec-lookup.ts","../src/core/sql-renderer.ts"],"sourcesContent":["import type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport { extractCodecLookup } from '@prisma-next/framework-components/control';\nimport { postgresCodecRegistry } from '@prisma-next/target-postgres/codecs';\n\n/**\n * Build a {@link CodecLookup} populated with the Postgres-builtin codec definitions only.\n *\n * This is the default lookup used by `createPostgresAdapter()` and `new PostgresControlAdapter()` when called without a stack-derived lookup (e.g. from tests, or one-off scripts that don't compose a full stack).\n *\n * Extension codecs (e.g. `pg/vector@1` from `@prisma-next/extension-pgvector`) are intentionally NOT included here: a bare adapter cannot see extensions. Stack-composed paths (`SqlControlAdapterDescriptor.create(stack)` / `SqlRuntimeAdapterDescriptor.create(stack)`) supply the broader, extension-inclusive lookup at construction time.\n */\nexport function createPostgresBuiltinCodecLookup(): CodecLookup {\n return extractCodecLookup([\n {\n id: 'postgres-builtin-codecs',\n types: { codecTypes: { codecDescriptors: Array.from(postgresCodecRegistry.values()) } },\n },\n ]);\n}\n","import type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport { runtimeError } from '@prisma-next/framework-components/runtime';\nimport {\n type AggregateExpr,\n type AnyExpression,\n type AnyFromSource,\n type AnyParamRef,\n type AnyQueryAst,\n type BinaryExpr,\n type ColumnRef,\n collectOrderedParamRefs,\n type DeleteAst,\n type InsertAst,\n type InsertValue,\n type JoinAst,\n type JoinOnExpr,\n type JsonArrayAggExpr,\n type JsonObjectExpr,\n type ListExpression,\n LiteralExpr,\n type LoweredParam,\n type NullCheckExpr,\n type OperationExpr,\n type OrderByItem,\n type ProjectionItem,\n type RawSqlExpr,\n type SelectAst,\n type SubqueryExpr,\n type UpdateAst,\n} from '@prisma-next/sql-relational-core/ast';\nimport { escapeLiteral, quoteIdentifier } from '@prisma-next/target-postgres/sql-utils';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { PostgresContract } from './types';\n\n/**\n * Postgres native types whose unknown-OID parameter inference is reliable in arbitrary expression positions. Parameters bound to a codec whose `meta.db.sql.postgres.nativeType` falls in this set are emitted as plain `$N`; everything else (including `json`, `jsonb`, extension types like `vector`, and unknown user types) is emitted as `$N::<nativeType>` so the planner picks an unambiguous overload.\n *\n * `json` / `jsonb` are intentionally excluded despite being Postgres builtins: their operator overloads make context inference unreliable in expression positions (e.g. `$1 -> 'key'` is ambiguous between the two).\n *\n * Spellings match the on-disk `meta.db.sql.postgres.nativeType` values in `@prisma-next/target-postgres`'s codec definitions, not the `udt_name` abbreviations that ADR 205 used as illustrative shorthand. The lookup-based cast policy compares against these strings directly.\n */\nconst POSTGRES_INFERRABLE_NATIVE_TYPES: ReadonlySet<string> = new Set([\n // Numeric\n 'integer',\n 'smallint',\n 'bigint',\n 'real',\n 'double precision',\n 'numeric',\n // Boolean\n 'boolean',\n // Strings\n 'text',\n 'character',\n 'character varying',\n // Temporal\n 'timestamp',\n 'timestamp without time zone',\n 'timestamp with time zone',\n 'time',\n 'timetz',\n 'interval',\n // Bit strings\n 'bit',\n 'bit varying',\n]);\n\nfunction renderTypedParam(\n index: number,\n codecId: string | undefined,\n codecLookup: CodecLookup,\n): string {\n if (codecId === undefined) {\n return `$${index}`;\n }\n const meta = codecLookup.metaFor(codecId);\n const isRegistered =\n codecLookup.get(codecId) !== undefined ||\n meta !== undefined ||\n codecLookup.targetTypesFor(codecId) !== undefined;\n if (!isRegistered) {\n throw new Error(\n `Postgres lowering: ParamRef carries codecId \"${codecId}\" but the ` +\n 'assembled codec lookup has no entry for it. This usually indicates ' +\n 'a missing extension pack in the runtime stack — register the pack ' +\n 'that contributes this codec (e.g. `extensionPacks: [pgvectorRuntime]`), ' +\n 'or use the codec directly from `@prisma-next/target-postgres/codecs` ' +\n \"if it's a builtin.\",\n );\n }\n // The framework `CodecLookup.metaFor` returns the family-agnostic `CodecMeta` whose `db` is `Record<string, unknown>`. The SQL family populates a narrower shape with `db.sql.<dialect>.nativeType: string`; navigate that path defensively and string-check the leaf.\n const dbRecord = meta?.db;\n const sqlBlock = isRecord(dbRecord) ? dbRecord['sql'] : undefined;\n const dialectBlock = isRecord(sqlBlock) ? sqlBlock['postgres'] : undefined;\n const nativeType = isRecord(dialectBlock) ? dialectBlock['nativeType'] : undefined;\n if (typeof nativeType === 'string' && !POSTGRES_INFERRABLE_NATIVE_TYPES.has(nativeType)) {\n return `$${index}::${nativeType}`;\n }\n return `$${index}`;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\n/**\n * Per-render carrier threaded through every helper. Bundles the param-index map (for `$N` numbering) and the assembled-stack `codecLookup` (for cast policy at the `renderTypedParam` chokepoint). Carrying both on a single value keeps helper signatures stable.\n */\ninterface ParamIndexMap {\n readonly indexMap: Map<AnyParamRef, number>;\n readonly codecLookup: CodecLookup;\n}\n\n/**\n * Render a SQL query AST to a Postgres-flavored `{ sql, params }` payload.\n *\n * Shared between the runtime (`PostgresAdapterImpl.lower`) and control (`PostgresControlAdapter.lower`) entrypoints so emit-time and run-time paths produce byte-identical output for the same AST.\n */\nexport function renderLoweredSql(\n ast: AnyQueryAst,\n contract: PostgresContract,\n codecLookup: CodecLookup,\n): { readonly sql: string; readonly params: readonly LoweredParam[] } {\n const orderedRefs = collectOrderedParamRefs(ast);\n const indexMap = new Map<AnyParamRef, number>();\n const params: LoweredParam[] = orderedRefs.map((ref, i) => {\n indexMap.set(ref, i + 1);\n return ref.kind === 'prepared-param-ref'\n ? { kind: 'bind', name: ref.name }\n : { kind: 'literal', value: ref.value };\n });\n const pim: ParamIndexMap = { indexMap, codecLookup };\n\n const node = ast;\n let sql: string;\n switch (node.kind) {\n case 'select':\n sql = renderSelect(node, contract, pim);\n break;\n case 'insert':\n sql = renderInsert(node, contract, pim);\n break;\n case 'update':\n sql = renderUpdate(node, contract, pim);\n break;\n case 'delete':\n sql = renderDelete(node, contract, pim);\n break;\n case 'raw-sql':\n sql = renderRawSql(node, contract, pim);\n break;\n // v8 ignore next 4\n default:\n throw new Error(\n `Unsupported AST node kind: ${(node satisfies never as { kind: string }).kind}`,\n );\n }\n\n return Object.freeze({ sql, params: Object.freeze(params) });\n}\n\nfunction renderLimitOffset(\n keyword: 'LIMIT' | 'OFFSET',\n value: SelectAst['limit'] | SelectAst['offset'],\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n if (value === undefined) return '';\n if (typeof value === 'number') return `${keyword} ${value}`;\n return `${keyword} ${renderExpr(value, contract, pim)}`;\n}\n\nfunction renderSelect(ast: SelectAst, contract: PostgresContract, pim: ParamIndexMap): string {\n const selectClause = `SELECT ${renderDistinctPrefix(ast.distinct, ast.distinctOn, contract, pim)}${renderProjection(\n ast.projection,\n contract,\n pim,\n )}`;\n const fromClause = `FROM ${renderSource(ast.from, contract, pim)}`;\n\n const joinsClause = ast.joins?.length\n ? ast.joins.map((join) => renderJoin(join, contract, pim)).join(' ')\n : '';\n\n const whereClause = ast.where ? `WHERE ${renderWhere(ast.where, contract, pim)}` : '';\n const groupByClause = ast.groupBy?.length\n ? `GROUP BY ${ast.groupBy.map((expr) => renderExpr(expr, contract, pim)).join(', ')}`\n : '';\n const havingClause = ast.having ? `HAVING ${renderWhere(ast.having, contract, pim)}` : '';\n const orderClause = ast.orderBy?.length\n ? `ORDER BY ${ast.orderBy\n .map((order) => {\n const expr = renderExpr(order.expr, contract, pim);\n return `${expr} ${order.dir.toUpperCase()}`;\n })\n .join(', ')}`\n : '';\n const limitClause = renderLimitOffset('LIMIT', ast.limit, contract, pim);\n const offsetClause = renderLimitOffset('OFFSET', ast.offset, contract, pim);\n\n const clauses = [\n selectClause,\n fromClause,\n joinsClause,\n whereClause,\n groupByClause,\n havingClause,\n orderClause,\n limitClause,\n offsetClause,\n ]\n .filter((part) => part.length > 0)\n .join(' ');\n return clauses.trim();\n}\n\nfunction renderProjection(\n projection: ReadonlyArray<ProjectionItem>,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n return projection\n .map((item) => {\n const alias = quoteIdentifier(item.alias);\n if (item.expr.kind === 'literal') {\n return `${renderLiteral(item.expr)} AS ${alias}`;\n }\n return `${renderExpr(item.expr, contract, pim)} AS ${alias}`;\n })\n .join(', ');\n}\n\nfunction renderReturning(\n items: ReadonlyArray<ProjectionItem>,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n return items\n .map((item) => {\n if (item.expr.kind === 'column-ref') {\n const rendered = renderColumn(item.expr);\n return item.expr.column === item.alias\n ? rendered\n : `${rendered} AS ${quoteIdentifier(item.alias)}`;\n }\n if (item.expr.kind === 'literal') {\n return `${renderLiteral(item.expr)} AS ${quoteIdentifier(item.alias)}`;\n }\n return `${renderExpr(item.expr, contract, pim)} AS ${quoteIdentifier(item.alias)}`;\n })\n .join(', ');\n}\n\nfunction renderDistinctPrefix(\n distinct: true | undefined,\n distinctOn: ReadonlyArray<AnyExpression> | undefined,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n if (distinctOn && distinctOn.length > 0) {\n const rendered = distinctOn.map((expr) => renderExpr(expr, contract, pim)).join(', ');\n return `DISTINCT ON (${rendered}) `;\n }\n if (distinct) {\n return 'DISTINCT ';\n }\n return '';\n}\n\nfunction renderSource(\n source: AnyFromSource,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n const node = source;\n switch (node.kind) {\n case 'table-source': {\n const table = quoteIdentifier(node.name);\n if (!node.alias) {\n return table;\n }\n return `${table} AS ${quoteIdentifier(node.alias)}`;\n }\n case 'derived-table-source':\n return `(${renderSelect(node.query, contract, pim)}) AS ${quoteIdentifier(node.alias)}`;\n // v8 ignore next 4\n default:\n throw new Error(\n `Unsupported source node kind: ${(node satisfies never as { kind: string }).kind}`,\n );\n }\n}\n\nfunction assertScalarSubquery(query: SelectAst): void {\n if (query.projection.length !== 1) {\n throw new Error('Subquery expressions must project exactly one column');\n }\n}\n\nfunction renderSubqueryExpr(\n expr: SubqueryExpr,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n assertScalarSubquery(expr.query);\n return `(${renderSelect(expr.query, contract, pim)})`;\n}\n\nfunction renderWhere(expr: AnyExpression, contract: PostgresContract, pim: ParamIndexMap): string {\n return renderExpr(expr, contract, pim);\n}\n\nfunction renderNullCheck(\n expr: NullCheckExpr,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n const rendered = renderExpr(expr.expr, contract, pim);\n const renderedExpr = isAtomicExpressionKind(expr.expr.kind) ? rendered : `(${rendered})`;\n return expr.isNull ? `${renderedExpr} IS NULL` : `${renderedExpr} IS NOT NULL`;\n}\n\n/**\n * Atomic expression kinds whose rendered SQL is already self-delimited (a column reference, parameter, literal, function call, aggregate, etc.) and therefore does not need surrounding parentheses when used as the left operand of a postfix predicate like `IS NULL` or `IS NOT NULL`, or as either operand of a binary infix operator.\n *\n * Anything not in this set is treated as composite (binary, AND/OR/NOT, EXISTS, nested IS NULL, subqueries, operation templates) and gets wrapped to preserve grouping.\n */\nfunction isAtomicExpressionKind(kind: AnyExpression['kind']): boolean {\n switch (kind) {\n case 'column-ref':\n case 'identifier-ref':\n case 'param-ref':\n case 'prepared-param-ref':\n case 'literal':\n case 'aggregate':\n case 'json-object':\n case 'json-array-agg':\n case 'list':\n return true;\n case 'subquery':\n case 'operation':\n case 'binary':\n case 'and':\n case 'or':\n case 'exists':\n case 'null-check':\n case 'not':\n return false;\n }\n}\n\nfunction renderBinary(expr: BinaryExpr, contract: PostgresContract, pim: ParamIndexMap): string {\n if (expr.right.kind === 'list' && expr.right.values.length === 0) {\n if (expr.op === 'in') {\n return 'FALSE';\n }\n if (expr.op === 'notIn') {\n return 'TRUE';\n }\n }\n\n const leftExpr = expr.left;\n const left = renderExpr(leftExpr, contract, pim);\n const leftRendered =\n leftExpr.kind === 'operation' || leftExpr.kind === 'subquery' ? `(${left})` : left;\n\n const rightNode = expr.right;\n let right: string;\n switch (rightNode.kind) {\n case 'list':\n right = renderListLiteral(rightNode, contract, pim);\n break;\n case 'literal':\n right = renderLiteral(rightNode);\n break;\n case 'column-ref':\n right = renderColumn(rightNode);\n break;\n case 'param-ref':\n case 'prepared-param-ref':\n right = renderParamRef(rightNode, pim);\n break;\n default:\n right = renderExpr(rightNode, contract, pim);\n break;\n }\n\n const operatorMap: Record<BinaryExpr['op'], string> = {\n eq: '=',\n neq: '!=',\n gt: '>',\n lt: '<',\n gte: '>=',\n lte: '<=',\n like: 'LIKE',\n in: 'IN',\n notIn: 'NOT IN',\n };\n\n return `${leftRendered} ${operatorMap[expr.op]} ${right}`;\n}\n\nfunction renderListLiteral(\n expr: ListExpression,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n if (expr.values.length === 0) {\n return '(NULL)';\n }\n const values = expr.values\n .map((v) => {\n if (v.kind === 'param-ref' || v.kind === 'prepared-param-ref') {\n return renderParamRef(v, pim);\n }\n if (v.kind === 'literal') return renderLiteral(v);\n return renderExpr(v, contract, pim);\n })\n .join(', ');\n return `(${values})`;\n}\n\nfunction renderColumn(ref: ColumnRef): string {\n if (ref.table === 'excluded') {\n return `excluded.${quoteIdentifier(ref.column)}`;\n }\n return `${quoteIdentifier(ref.table)}.${quoteIdentifier(ref.column)}`;\n}\n\nfunction renderAggregateExpr(\n expr: AggregateExpr,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n const fn = expr.fn.toUpperCase();\n if (!expr.expr) {\n return `${fn}(*)`;\n }\n return `${fn}(${renderExpr(expr.expr, contract, pim)})`;\n}\n\nfunction renderJsonObjectExpr(\n expr: JsonObjectExpr,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n const args = expr.entries\n .flatMap((entry): [string, string] => {\n const key = `'${escapeLiteral(entry.key)}'`;\n if (entry.value.kind === 'literal') {\n return [key, renderLiteral(entry.value)];\n }\n return [key, renderExpr(entry.value, contract, pim)];\n })\n .join(', ');\n return `json_build_object(${args})`;\n}\n\nfunction renderOrderByItems(\n items: ReadonlyArray<OrderByItem>,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n return items\n .map((item) => `${renderExpr(item.expr, contract, pim)} ${item.dir.toUpperCase()}`)\n .join(', ');\n}\n\nfunction renderJsonArrayAggExpr(\n expr: JsonArrayAggExpr,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n const aggregateOrderBy =\n expr.orderBy && expr.orderBy.length > 0\n ? ` ORDER BY ${renderOrderByItems(expr.orderBy, contract, pim)}`\n : '';\n const aggregated = `json_agg(${renderExpr(expr.expr, contract, pim)}${aggregateOrderBy})`;\n if (expr.onEmpty === 'emptyArray') {\n return `coalesce(${aggregated}, json_build_array())`;\n }\n return aggregated;\n}\n\nfunction renderExpr(expr: AnyExpression, contract: PostgresContract, pim: ParamIndexMap): string {\n const node = expr;\n switch (node.kind) {\n case 'column-ref':\n return renderColumn(node);\n case 'identifier-ref':\n return quoteIdentifier(node.name);\n case 'operation':\n return renderOperation(node, contract, pim);\n case 'subquery':\n return renderSubqueryExpr(node, contract, pim);\n case 'aggregate':\n return renderAggregateExpr(node, contract, pim);\n case 'json-object':\n return renderJsonObjectExpr(node, contract, pim);\n case 'json-array-agg':\n return renderJsonArrayAggExpr(node, contract, pim);\n case 'binary':\n return renderBinary(node, contract, pim);\n case 'and':\n if (node.exprs.length === 0) {\n return 'TRUE';\n }\n return `(${node.exprs.map((part) => renderExpr(part, contract, pim)).join(' AND ')})`;\n case 'or':\n if (node.exprs.length === 0) {\n return 'FALSE';\n }\n return `(${node.exprs.map((part) => renderExpr(part, contract, pim)).join(' OR ')})`;\n case 'exists': {\n const notKeyword = node.notExists ? 'NOT ' : '';\n const subquery = renderSelect(node.subquery, contract, pim);\n return `${notKeyword}EXISTS (${subquery})`;\n }\n case 'null-check':\n return renderNullCheck(node, contract, pim);\n case 'not':\n return `NOT (${renderExpr(node.expr, contract, pim)})`;\n case 'param-ref':\n case 'prepared-param-ref':\n return renderParamRef(node, pim);\n case 'literal':\n return renderLiteral(node);\n case 'list':\n return renderListLiteral(node, contract, pim);\n // v8 ignore next 4\n default:\n throw new Error(\n `Unsupported expression node kind: ${(node satisfies never as { kind: string }).kind}`,\n );\n }\n}\n\nfunction renderParamRef(ref: AnyParamRef, pim: ParamIndexMap): string {\n const index = pim.indexMap.get(ref);\n if (index === undefined) {\n throw new Error('ParamRef not found in index map');\n }\n if (ref.kind === 'prepared-param-ref') {\n return renderTypedParam(index, ref.codec.codecId, pim.codecLookup);\n }\n if (ref.codec === undefined) {\n throw runtimeError(\n 'RUNTIME.PARAM_REF_MISSING_CODEC',\n 'Postgres renderer: ParamRef reached lowering without a bound CodecRef. ' +\n 'Every column-bound ParamRef must carry a codec under the AST-bound codec contract. ' +\n 'This usually indicates a builder path that constructed a ParamRef without threading the column codec.',\n { paramIndex: index, ...ifDefined('name', ref.name) },\n );\n }\n return renderTypedParam(index, ref.codec.codecId, pim.codecLookup);\n}\n\nfunction renderLiteral(expr: LiteralExpr): string {\n if (typeof expr.value === 'string') {\n return `'${escapeLiteral(expr.value)}'`;\n }\n if (typeof expr.value === 'number' || typeof expr.value === 'boolean') {\n return String(expr.value);\n }\n if (typeof expr.value === 'bigint') {\n return String(expr.value);\n }\n if (expr.value === null) {\n return 'NULL';\n }\n if (expr.value === undefined) {\n return 'NULL';\n }\n if (expr.value instanceof Date) {\n return `'${escapeLiteral(expr.value.toISOString())}'`;\n }\n if (Array.isArray(expr.value)) {\n return `ARRAY[${expr.value.map((v: unknown) => renderLiteral(new LiteralExpr(v))).join(', ')}]`;\n }\n const json = JSON.stringify(expr.value);\n if (json === undefined) {\n return 'NULL';\n }\n return `'${escapeLiteral(json)}'`;\n}\n\nfunction renderOperation(\n expr: OperationExpr,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n const self = renderExpr(expr.self, contract, pim);\n const args = expr.args.map((arg) => {\n return renderExpr(arg, contract, pim);\n });\n\n // Resolve `{{self}}` and `{{argN}}` from the original template in a single pass. Doing this with sequential `String.prototype.replace` calls is unsafe: a substituted fragment can itself contain text that matches a later token (e.g. an arg literal containing the substring `{{arg1}}`), and the next iteration would corrupt it. A single regex callback never re-scans already-substituted output.\n return expr.lowering.template.replace(\n /\\{\\{self\\}\\}|\\{\\{arg(\\d+)\\}\\}/g,\n (token, argIndex: string | undefined) => {\n if (token === '{{self}}') {\n return self;\n }\n const arg = args[Number(argIndex)];\n if (arg === undefined) {\n throw new Error(\n `Operation lowering template for \"${expr.method}\" referenced missing argument {{arg${argIndex}}}; template has ${args.length} arg(s)`,\n );\n }\n return arg;\n },\n );\n}\n\nfunction renderJoin(join: JoinAst, contract: PostgresContract, pim: ParamIndexMap): string {\n const joinType = join.joinType.toUpperCase();\n const lateral = join.lateral ? 'LATERAL ' : '';\n const source = renderSource(join.source, contract, pim);\n const onClause = renderJoinOn(join.on, contract, pim);\n return `${joinType} JOIN ${lateral}${source} ON ${onClause}`;\n}\n\nfunction renderJoinOn(on: JoinOnExpr, contract: PostgresContract, pim: ParamIndexMap): string {\n if (on.kind === 'eq-col-join-on') {\n const left = renderColumn(on.left);\n const right = renderColumn(on.right);\n return `${left} = ${right}`;\n }\n return renderWhere(on, contract, pim);\n}\n\nfunction getInsertColumnOrder(\n rows: ReadonlyArray<Record<string, InsertValue>>,\n contract: PostgresContract,\n tableName: string,\n): string[] {\n const orderedColumns: string[] = [];\n const seenColumns = new Set<string>();\n\n for (const row of rows) {\n for (const column of Object.keys(row)) {\n if (seenColumns.has(column)) {\n continue;\n }\n seenColumns.add(column);\n orderedColumns.push(column);\n }\n }\n\n if (orderedColumns.length > 0) {\n return orderedColumns;\n }\n\n let table: { columns: Record<string, unknown> } | undefined;\n for (const ns of Object.values(contract.storage.namespaces)) {\n // Namespace.tables is Record<string, IRNode> at the interface level;\n // SQL family namespaces hold StorageTable instances which have .columns.\n const found = ns.tables[tableName] as { columns: Record<string, unknown> } | undefined;\n if (found !== undefined) {\n table = found;\n break;\n }\n }\n if (!table) {\n throw new Error(`INSERT target table not found in contract storage: ${tableName}`);\n }\n return Object.keys(table.columns);\n}\n\nfunction renderInsertValue(value: InsertValue | undefined, pim: ParamIndexMap): string {\n if (!value || value.kind === 'default-value') {\n return 'DEFAULT';\n }\n\n switch (value.kind) {\n case 'param-ref':\n case 'prepared-param-ref':\n return renderParamRef(value, pim);\n case 'column-ref':\n return renderColumn(value);\n // v8 ignore next 4\n default:\n throw new Error(\n `Unsupported value node in INSERT: ${(value satisfies never as { kind: string }).kind}`,\n );\n }\n}\n\nfunction renderInsert(ast: InsertAst, contract: PostgresContract, pim: ParamIndexMap): string {\n const table = quoteIdentifier(ast.table.name);\n const rows = ast.rows;\n if (rows.length === 0) {\n throw new Error('INSERT requires at least one row');\n }\n const hasExplicitValues = rows.some((row) => Object.keys(row).length > 0);\n const insertClause = (() => {\n if (!hasExplicitValues) {\n if (rows.length === 1) {\n return `INSERT INTO ${table} DEFAULT VALUES`;\n }\n\n const defaultColumns = getInsertColumnOrder(rows, contract, ast.table.name);\n if (defaultColumns.length === 0) {\n return `INSERT INTO ${table} VALUES ${rows.map(() => '()').join(', ')}`;\n }\n\n const quotedColumns = defaultColumns.map((column) => quoteIdentifier(column));\n const defaultRow = `(${defaultColumns.map(() => 'DEFAULT').join(', ')})`;\n return `INSERT INTO ${table} (${quotedColumns.join(', ')}) VALUES ${rows\n .map(() => defaultRow)\n .join(', ')}`;\n }\n\n const columnOrder = getInsertColumnOrder(rows, contract, ast.table.name);\n const columns = columnOrder.map((column) => quoteIdentifier(column));\n const values = rows\n .map((row) => {\n const renderedRow = columnOrder.map((column) => renderInsertValue(row[column], pim));\n return `(${renderedRow.join(', ')})`;\n })\n .join(', ');\n\n return `INSERT INTO ${table} (${columns.join(', ')}) VALUES ${values}`;\n })();\n const onConflictClause = ast.onConflict\n ? (() => {\n const conflictColumns = ast.onConflict.columns.map((col) => quoteIdentifier(col.column));\n if (conflictColumns.length === 0) {\n throw new Error('INSERT onConflict requires at least one conflict column');\n }\n\n const action = ast.onConflict.action;\n switch (action.kind) {\n case 'do-nothing':\n return ` ON CONFLICT (${conflictColumns.join(', ')}) DO NOTHING`;\n case 'do-update-set': {\n const updateEntries = Object.entries(action.set);\n if (updateEntries.length === 0) {\n throw new Error('INSERT onConflict do-update-set requires at least one assignment');\n }\n const updates = updateEntries.map(([colName, value]) => {\n const target = quoteIdentifier(colName);\n if (value.kind === 'param-ref' || value.kind === 'prepared-param-ref') {\n return `${target} = ${renderParamRef(value, pim)}`;\n }\n return `${target} = ${renderColumn(value)}`;\n });\n return ` ON CONFLICT (${conflictColumns.join(', ')}) DO UPDATE SET ${updates.join(', ')}`;\n }\n // v8 ignore next 4\n default:\n throw new Error(\n `Unsupported onConflict action: ${(action satisfies never as { kind: string }).kind}`,\n );\n }\n })()\n : '';\n const returningClause = ast.returning?.length\n ? ` RETURNING ${renderReturning(ast.returning, contract, pim)}`\n : '';\n\n return `${insertClause}${onConflictClause}${returningClause}`;\n}\n\nfunction renderUpdate(ast: UpdateAst, contract: PostgresContract, pim: ParamIndexMap): string {\n const table = quoteIdentifier(ast.table.name);\n const setEntries = Object.entries(ast.set);\n if (setEntries.length === 0) {\n throw new Error('UPDATE requires at least one SET assignment');\n }\n const setClauses = setEntries.map(([col, val]) => {\n const column = quoteIdentifier(col);\n let value: string;\n switch (val.kind) {\n case 'param-ref':\n case 'prepared-param-ref':\n value = renderParamRef(val, pim);\n break;\n case 'column-ref':\n value = renderColumn(val);\n break;\n // v8 ignore next 4\n default:\n throw new Error(\n `Unsupported value node in UPDATE: ${(val satisfies never as { kind: string }).kind}`,\n );\n }\n return `${column} = ${value}`;\n });\n\n const whereClause = ast.where ? ` WHERE ${renderWhere(ast.where, contract, pim)}` : '';\n const returningClause = ast.returning?.length\n ? ` RETURNING ${renderReturning(ast.returning, contract, pim)}`\n : '';\n\n return `UPDATE ${table} SET ${setClauses.join(', ')}${whereClause}${returningClause}`;\n}\n\nfunction renderDelete(ast: DeleteAst, contract: PostgresContract, pim: ParamIndexMap): string {\n const table = quoteIdentifier(ast.table.name);\n const whereClause = ast.where ? ` WHERE ${renderWhere(ast.where, contract, pim)}` : '';\n const returningClause = ast.returning?.length\n ? ` RETURNING ${renderReturning(ast.returning, contract, pim)}`\n : '';\n\n return `DELETE FROM ${table}${whereClause}${returningClause}`;\n}\n\nfunction renderRawSql(ast: RawSqlExpr, contract: PostgresContract, pim: ParamIndexMap): string {\n const out: string[] = [];\n for (let i = 0; i < ast.fragments.length; i++) {\n out.push(ast.fragments[i] ?? '');\n if (i < ast.args.length) {\n const arg = ast.args[i];\n if (arg !== undefined) {\n out.push(renderExpr(arg, contract, pim));\n }\n }\n }\n return out.join('');\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sql-renderer-DFMHmkt_.mjs","names":[],"sources":["../src/core/codec-lookup.ts","../src/core/sql-renderer.ts"],"sourcesContent":["import type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport { extractCodecLookup } from '@prisma-next/framework-components/control';\nimport { postgresCodecRegistry } from '@prisma-next/target-postgres/codecs';\n\n/**\n * Build a {@link CodecLookup} populated with the Postgres-builtin codec definitions only.\n *\n * This is the default lookup used by `createPostgresAdapter()` and `new PostgresControlAdapter()` when called without a stack-derived lookup (e.g. from tests, or one-off scripts that don't compose a full stack).\n *\n * Extension codecs (e.g. `pg/vector@1` from `@prisma-next/extension-pgvector`) are intentionally NOT included here: a bare adapter cannot see extensions. Stack-composed paths (`SqlControlAdapterDescriptor.create(stack)` / `SqlRuntimeAdapterDescriptor.create(stack)`) supply the broader, extension-inclusive lookup at construction time.\n */\nexport function createPostgresBuiltinCodecLookup(): CodecLookup {\n return extractCodecLookup([\n {\n id: 'postgres-builtin-codecs',\n types: { codecTypes: { codecDescriptors: Array.from(postgresCodecRegistry.values()) } },\n },\n ]);\n}\n","import type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport { runtimeError } from '@prisma-next/framework-components/runtime';\nimport {\n type AggregateExpr,\n type AnyExpression,\n type AnyFromSource,\n type AnyParamRef,\n type AnyQueryAst,\n type BinaryExpr,\n type ColumnRef,\n collectOrderedParamRefs,\n type DeleteAst,\n type InsertAst,\n type InsertValue,\n type JoinAst,\n type JoinOnExpr,\n type JsonArrayAggExpr,\n type JsonObjectExpr,\n type ListExpression,\n LiteralExpr,\n type LoweredParam,\n type NullCheckExpr,\n type OperationExpr,\n type OrderByItem,\n type ProjectionItem,\n type RawSqlExpr,\n type SelectAst,\n type SubqueryExpr,\n type UpdateAst,\n} from '@prisma-next/sql-relational-core/ast';\nimport { escapeLiteral, quoteIdentifier } from '@prisma-next/target-postgres/sql-utils';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { PostgresContract } from './types';\n\n/**\n * Postgres native types whose unknown-OID parameter inference is reliable in arbitrary expression positions. Parameters bound to a codec whose `meta.db.sql.postgres.nativeType` falls in this set are emitted as plain `$N`; everything else (including `json`, `jsonb`, extension types like `vector`, and unknown user types) is emitted as `$N::<nativeType>` so the planner picks an unambiguous overload.\n *\n * `json` / `jsonb` are intentionally excluded despite being Postgres builtins: their operator overloads make context inference unreliable in expression positions (e.g. `$1 -> 'key'` is ambiguous between the two).\n *\n * Spellings match the on-disk `meta.db.sql.postgres.nativeType` values in `@prisma-next/target-postgres`'s codec definitions, not the `udt_name` abbreviations that ADR 205 used as illustrative shorthand. The lookup-based cast policy compares against these strings directly.\n */\nconst POSTGRES_INFERRABLE_NATIVE_TYPES: ReadonlySet<string> = new Set([\n // Numeric\n 'integer',\n 'smallint',\n 'bigint',\n 'real',\n 'double precision',\n 'numeric',\n // Boolean\n 'boolean',\n // Strings\n 'text',\n 'character',\n 'character varying',\n // Temporal\n 'timestamp',\n 'timestamp without time zone',\n 'timestamp with time zone',\n 'time',\n 'timetz',\n 'interval',\n // Bit strings\n 'bit',\n 'bit varying',\n]);\n\nfunction renderTypedParam(\n index: number,\n codecId: string | undefined,\n codecLookup: CodecLookup,\n): string {\n if (codecId === undefined) {\n return `$${index}`;\n }\n const meta = codecLookup.metaFor(codecId);\n const isRegistered =\n codecLookup.get(codecId) !== undefined ||\n meta !== undefined ||\n codecLookup.targetTypesFor(codecId) !== undefined;\n if (!isRegistered) {\n throw new Error(\n `Postgres lowering: ParamRef carries codecId \"${codecId}\" but the ` +\n 'assembled codec lookup has no entry for it. This usually indicates ' +\n 'a missing extension pack in the runtime stack — register the pack ' +\n 'that contributes this codec (e.g. `extensionPacks: [pgvectorRuntime]`), ' +\n 'or use the codec directly from `@prisma-next/target-postgres/codecs` ' +\n \"if it's a builtin.\",\n );\n }\n // The framework `CodecLookup.metaFor` returns the family-agnostic `CodecMeta` whose `db` is `Record<string, unknown>`. The SQL family populates a narrower shape with `db.sql.<dialect>.nativeType: string`; navigate that path defensively and string-check the leaf.\n const dbRecord = meta?.db;\n const sqlBlock = isRecord(dbRecord) ? dbRecord['sql'] : undefined;\n const dialectBlock = isRecord(sqlBlock) ? sqlBlock['postgres'] : undefined;\n const nativeType = isRecord(dialectBlock) ? dialectBlock['nativeType'] : undefined;\n if (typeof nativeType === 'string' && !POSTGRES_INFERRABLE_NATIVE_TYPES.has(nativeType)) {\n return `$${index}::${nativeType}`;\n }\n return `$${index}`;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\n/**\n * Per-render carrier threaded through every helper. Bundles the param-index map (for `$N` numbering) and the assembled-stack `codecLookup` (for cast policy at the `renderTypedParam` chokepoint). Carrying both on a single value keeps helper signatures stable.\n */\ninterface ParamIndexMap {\n readonly indexMap: Map<AnyParamRef, number>;\n readonly codecLookup: CodecLookup;\n}\n\n/**\n * Render a SQL query AST to a Postgres-flavored `{ sql, params }` payload.\n *\n * Shared between the runtime (`PostgresAdapterImpl.lower`) and control (`PostgresControlAdapter.lower`) entrypoints so emit-time and run-time paths produce byte-identical output for the same AST.\n */\nexport function renderLoweredSql(\n ast: AnyQueryAst,\n contract: PostgresContract,\n codecLookup: CodecLookup,\n): { readonly sql: string; readonly params: readonly LoweredParam[] } {\n const orderedRefs = collectOrderedParamRefs(ast);\n const indexMap = new Map<AnyParamRef, number>();\n const params: LoweredParam[] = orderedRefs.map((ref, i) => {\n indexMap.set(ref, i + 1);\n return ref.kind === 'prepared-param-ref'\n ? { kind: 'bind', name: ref.name }\n : { kind: 'literal', value: ref.value };\n });\n const pim: ParamIndexMap = { indexMap, codecLookup };\n\n const node = ast;\n let sql: string;\n switch (node.kind) {\n case 'select':\n sql = renderSelect(node, contract, pim);\n break;\n case 'insert':\n sql = renderInsert(node, contract, pim);\n break;\n case 'update':\n sql = renderUpdate(node, contract, pim);\n break;\n case 'delete':\n sql = renderDelete(node, contract, pim);\n break;\n case 'raw-sql':\n sql = renderRawSql(node, contract, pim);\n break;\n // v8 ignore next 4\n default:\n throw new Error(\n `Unsupported AST node kind: ${(node satisfies never as { kind: string }).kind}`,\n );\n }\n\n return Object.freeze({ sql, params: Object.freeze(params) });\n}\n\nfunction renderLimitOffset(\n keyword: 'LIMIT' | 'OFFSET',\n value: SelectAst['limit'] | SelectAst['offset'],\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n if (value === undefined) return '';\n if (typeof value === 'number') return `${keyword} ${value}`;\n return `${keyword} ${renderExpr(value, contract, pim)}`;\n}\n\nfunction renderSelect(ast: SelectAst, contract: PostgresContract, pim: ParamIndexMap): string {\n const selectClause = `SELECT ${renderDistinctPrefix(ast.distinct, ast.distinctOn, contract, pim)}${renderProjection(\n ast.projection,\n contract,\n pim,\n )}`;\n const fromClause = `FROM ${renderSource(ast.from, contract, pim)}`;\n\n const joinsClause = ast.joins?.length\n ? ast.joins.map((join) => renderJoin(join, contract, pim)).join(' ')\n : '';\n\n const whereClause = ast.where ? `WHERE ${renderWhere(ast.where, contract, pim)}` : '';\n const groupByClause = ast.groupBy?.length\n ? `GROUP BY ${ast.groupBy.map((expr) => renderExpr(expr, contract, pim)).join(', ')}`\n : '';\n const havingClause = ast.having ? `HAVING ${renderWhere(ast.having, contract, pim)}` : '';\n const orderClause = ast.orderBy?.length\n ? `ORDER BY ${ast.orderBy\n .map((order) => {\n const expr = renderExpr(order.expr, contract, pim);\n return `${expr} ${order.dir.toUpperCase()}`;\n })\n .join(', ')}`\n : '';\n const limitClause = renderLimitOffset('LIMIT', ast.limit, contract, pim);\n const offsetClause = renderLimitOffset('OFFSET', ast.offset, contract, pim);\n\n const clauses = [\n selectClause,\n fromClause,\n joinsClause,\n whereClause,\n groupByClause,\n havingClause,\n orderClause,\n limitClause,\n offsetClause,\n ]\n .filter((part) => part.length > 0)\n .join(' ');\n return clauses.trim();\n}\n\nfunction renderProjection(\n projection: ReadonlyArray<ProjectionItem>,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n return projection\n .map((item) => {\n const alias = quoteIdentifier(item.alias);\n if (item.expr.kind === 'literal') {\n return `${renderLiteral(item.expr)} AS ${alias}`;\n }\n return `${renderExpr(item.expr, contract, pim)} AS ${alias}`;\n })\n .join(', ');\n}\n\nfunction renderReturning(\n items: ReadonlyArray<ProjectionItem>,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n return items\n .map((item) => {\n if (item.expr.kind === 'column-ref') {\n const rendered = renderColumn(item.expr);\n return item.expr.column === item.alias\n ? rendered\n : `${rendered} AS ${quoteIdentifier(item.alias)}`;\n }\n if (item.expr.kind === 'literal') {\n return `${renderLiteral(item.expr)} AS ${quoteIdentifier(item.alias)}`;\n }\n return `${renderExpr(item.expr, contract, pim)} AS ${quoteIdentifier(item.alias)}`;\n })\n .join(', ');\n}\n\nfunction renderDistinctPrefix(\n distinct: true | undefined,\n distinctOn: ReadonlyArray<AnyExpression> | undefined,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n if (distinctOn && distinctOn.length > 0) {\n const rendered = distinctOn.map((expr) => renderExpr(expr, contract, pim)).join(', ');\n return `DISTINCT ON (${rendered}) `;\n }\n if (distinct) {\n return 'DISTINCT ';\n }\n return '';\n}\n\nfunction renderSource(\n source: AnyFromSource,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n const node = source;\n switch (node.kind) {\n case 'table-source': {\n const table = quoteIdentifier(node.name);\n if (!node.alias) {\n return table;\n }\n return `${table} AS ${quoteIdentifier(node.alias)}`;\n }\n case 'derived-table-source':\n return `(${renderSelect(node.query, contract, pim)}) AS ${quoteIdentifier(node.alias)}`;\n // v8 ignore next 4\n default:\n throw new Error(\n `Unsupported source node kind: ${(node satisfies never as { kind: string }).kind}`,\n );\n }\n}\n\nfunction assertScalarSubquery(query: SelectAst): void {\n if (query.projection.length !== 1) {\n throw new Error('Subquery expressions must project exactly one column');\n }\n}\n\nfunction renderSubqueryExpr(\n expr: SubqueryExpr,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n assertScalarSubquery(expr.query);\n return `(${renderSelect(expr.query, contract, pim)})`;\n}\n\nfunction renderWhere(expr: AnyExpression, contract: PostgresContract, pim: ParamIndexMap): string {\n return renderExpr(expr, contract, pim);\n}\n\nfunction renderNullCheck(\n expr: NullCheckExpr,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n const rendered = renderExpr(expr.expr, contract, pim);\n const renderedExpr = isAtomicExpressionKind(expr.expr.kind) ? rendered : `(${rendered})`;\n return expr.isNull ? `${renderedExpr} IS NULL` : `${renderedExpr} IS NOT NULL`;\n}\n\n/**\n * Atomic expression kinds whose rendered SQL is already self-delimited (a column reference, parameter, literal, function call, aggregate, etc.) and therefore does not need surrounding parentheses when used as the left operand of a postfix predicate like `IS NULL` or `IS NOT NULL`, or as either operand of a binary infix operator.\n *\n * Anything not in this set is treated as composite (binary, AND/OR/NOT, EXISTS, nested IS NULL, subqueries, operation templates) and gets wrapped to preserve grouping.\n */\nfunction isAtomicExpressionKind(kind: AnyExpression['kind']): boolean {\n switch (kind) {\n case 'column-ref':\n case 'identifier-ref':\n case 'param-ref':\n case 'prepared-param-ref':\n case 'literal':\n case 'aggregate':\n case 'json-object':\n case 'json-array-agg':\n case 'list':\n return true;\n case 'subquery':\n case 'operation':\n case 'binary':\n case 'and':\n case 'or':\n case 'exists':\n case 'null-check':\n case 'not':\n return false;\n }\n}\n\nfunction renderBinary(expr: BinaryExpr, contract: PostgresContract, pim: ParamIndexMap): string {\n if (expr.right.kind === 'list' && expr.right.values.length === 0) {\n if (expr.op === 'in') {\n return 'FALSE';\n }\n if (expr.op === 'notIn') {\n return 'TRUE';\n }\n }\n\n const leftExpr = expr.left;\n const left = renderExpr(leftExpr, contract, pim);\n const leftRendered =\n leftExpr.kind === 'operation' || leftExpr.kind === 'subquery' ? `(${left})` : left;\n\n const rightNode = expr.right;\n let right: string;\n switch (rightNode.kind) {\n case 'list':\n right = renderListLiteral(rightNode, contract, pim);\n break;\n case 'literal':\n right = renderLiteral(rightNode);\n break;\n case 'column-ref':\n right = renderColumn(rightNode);\n break;\n case 'param-ref':\n case 'prepared-param-ref':\n right = renderParamRef(rightNode, pim);\n break;\n default:\n right = renderExpr(rightNode, contract, pim);\n break;\n }\n\n const operatorMap: Record<BinaryExpr['op'], string> = {\n eq: '=',\n neq: '!=',\n gt: '>',\n lt: '<',\n gte: '>=',\n lte: '<=',\n like: 'LIKE',\n in: 'IN',\n notIn: 'NOT IN',\n };\n\n return `${leftRendered} ${operatorMap[expr.op]} ${right}`;\n}\n\nfunction renderListLiteral(\n expr: ListExpression,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n if (expr.values.length === 0) {\n return '(NULL)';\n }\n const values = expr.values\n .map((v) => {\n if (v.kind === 'param-ref' || v.kind === 'prepared-param-ref') {\n return renderParamRef(v, pim);\n }\n if (v.kind === 'literal') return renderLiteral(v);\n return renderExpr(v, contract, pim);\n })\n .join(', ');\n return `(${values})`;\n}\n\nfunction renderColumn(ref: ColumnRef): string {\n if (ref.table === 'excluded') {\n return `excluded.${quoteIdentifier(ref.column)}`;\n }\n return `${quoteIdentifier(ref.table)}.${quoteIdentifier(ref.column)}`;\n}\n\nfunction renderAggregateExpr(\n expr: AggregateExpr,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n const fn = expr.fn.toUpperCase();\n if (!expr.expr) {\n return `${fn}(*)`;\n }\n return `${fn}(${renderExpr(expr.expr, contract, pim)})`;\n}\n\nfunction renderJsonObjectExpr(\n expr: JsonObjectExpr,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n const args = expr.entries\n .flatMap((entry): [string, string] => {\n const key = `'${escapeLiteral(entry.key)}'`;\n if (entry.value.kind === 'literal') {\n return [key, renderLiteral(entry.value)];\n }\n return [key, renderExpr(entry.value, contract, pim)];\n })\n .join(', ');\n return `json_build_object(${args})`;\n}\n\nfunction renderOrderByItems(\n items: ReadonlyArray<OrderByItem>,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n return items\n .map((item) => `${renderExpr(item.expr, contract, pim)} ${item.dir.toUpperCase()}`)\n .join(', ');\n}\n\nfunction renderJsonArrayAggExpr(\n expr: JsonArrayAggExpr,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n const aggregateOrderBy =\n expr.orderBy && expr.orderBy.length > 0\n ? ` ORDER BY ${renderOrderByItems(expr.orderBy, contract, pim)}`\n : '';\n const aggregated = `json_agg(${renderExpr(expr.expr, contract, pim)}${aggregateOrderBy})`;\n if (expr.onEmpty === 'emptyArray') {\n return `coalesce(${aggregated}, json_build_array())`;\n }\n return aggregated;\n}\n\nfunction renderExpr(expr: AnyExpression, contract: PostgresContract, pim: ParamIndexMap): string {\n const node = expr;\n switch (node.kind) {\n case 'column-ref':\n return renderColumn(node);\n case 'identifier-ref':\n return quoteIdentifier(node.name);\n case 'operation':\n return renderOperation(node, contract, pim);\n case 'subquery':\n return renderSubqueryExpr(node, contract, pim);\n case 'aggregate':\n return renderAggregateExpr(node, contract, pim);\n case 'json-object':\n return renderJsonObjectExpr(node, contract, pim);\n case 'json-array-agg':\n return renderJsonArrayAggExpr(node, contract, pim);\n case 'binary':\n return renderBinary(node, contract, pim);\n case 'and':\n if (node.exprs.length === 0) {\n return 'TRUE';\n }\n return `(${node.exprs.map((part) => renderExpr(part, contract, pim)).join(' AND ')})`;\n case 'or':\n if (node.exprs.length === 0) {\n return 'FALSE';\n }\n return `(${node.exprs.map((part) => renderExpr(part, contract, pim)).join(' OR ')})`;\n case 'exists': {\n const notKeyword = node.notExists ? 'NOT ' : '';\n const subquery = renderSelect(node.subquery, contract, pim);\n return `${notKeyword}EXISTS (${subquery})`;\n }\n case 'null-check':\n return renderNullCheck(node, contract, pim);\n case 'not':\n return `NOT (${renderExpr(node.expr, contract, pim)})`;\n case 'param-ref':\n case 'prepared-param-ref':\n return renderParamRef(node, pim);\n case 'literal':\n return renderLiteral(node);\n case 'list':\n return renderListLiteral(node, contract, pim);\n // v8 ignore next 4\n default:\n throw new Error(\n `Unsupported expression node kind: ${(node satisfies never as { kind: string }).kind}`,\n );\n }\n}\n\nfunction renderParamRef(ref: AnyParamRef, pim: ParamIndexMap): string {\n const index = pim.indexMap.get(ref);\n if (index === undefined) {\n throw new Error('ParamRef not found in index map');\n }\n if (ref.kind === 'prepared-param-ref') {\n return renderTypedParam(index, ref.codec.codecId, pim.codecLookup);\n }\n if (ref.codec === undefined) {\n throw runtimeError(\n 'RUNTIME.PARAM_REF_MISSING_CODEC',\n 'Postgres renderer: ParamRef reached lowering without a bound CodecRef. ' +\n 'Every column-bound ParamRef must carry a codec under the AST-bound codec contract. ' +\n 'This usually indicates a builder path that constructed a ParamRef without threading the column codec.',\n { paramIndex: index, ...ifDefined('name', ref.name) },\n );\n }\n return renderTypedParam(index, ref.codec.codecId, pim.codecLookup);\n}\n\nfunction renderLiteral(expr: LiteralExpr): string {\n if (typeof expr.value === 'string') {\n return `'${escapeLiteral(expr.value)}'`;\n }\n if (typeof expr.value === 'number' || typeof expr.value === 'boolean') {\n return String(expr.value);\n }\n if (typeof expr.value === 'bigint') {\n return String(expr.value);\n }\n if (expr.value === null) {\n return 'NULL';\n }\n if (expr.value === undefined) {\n return 'NULL';\n }\n if (expr.value instanceof Date) {\n return `'${escapeLiteral(expr.value.toISOString())}'`;\n }\n if (Array.isArray(expr.value)) {\n return `ARRAY[${expr.value.map((v: unknown) => renderLiteral(new LiteralExpr(v))).join(', ')}]`;\n }\n const json = JSON.stringify(expr.value);\n if (json === undefined) {\n return 'NULL';\n }\n return `'${escapeLiteral(json)}'`;\n}\n\nfunction renderOperation(\n expr: OperationExpr,\n contract: PostgresContract,\n pim: ParamIndexMap,\n): string {\n const self = renderExpr(expr.self, contract, pim);\n const args = expr.args.map((arg) => {\n return renderExpr(arg, contract, pim);\n });\n\n // Resolve `{{self}}` and `{{argN}}` from the original template in a single pass. Doing this with sequential `String.prototype.replace` calls is unsafe: a substituted fragment can itself contain text that matches a later token (e.g. an arg literal containing the substring `{{arg1}}`), and the next iteration would corrupt it. A single regex callback never re-scans already-substituted output.\n return expr.lowering.template.replace(\n /\\{\\{self\\}\\}|\\{\\{arg(\\d+)\\}\\}/g,\n (token, argIndex: string | undefined) => {\n if (token === '{{self}}') {\n return self;\n }\n const arg = args[Number(argIndex)];\n if (arg === undefined) {\n throw new Error(\n `Operation lowering template for \"${expr.method}\" referenced missing argument {{arg${argIndex}}}; template has ${args.length} arg(s)`,\n );\n }\n return arg;\n },\n );\n}\n\nfunction renderJoin(join: JoinAst, contract: PostgresContract, pim: ParamIndexMap): string {\n const joinType = join.joinType.toUpperCase();\n const lateral = join.lateral ? 'LATERAL ' : '';\n const source = renderSource(join.source, contract, pim);\n const onClause = renderJoinOn(join.on, contract, pim);\n return `${joinType} JOIN ${lateral}${source} ON ${onClause}`;\n}\n\nfunction renderJoinOn(on: JoinOnExpr, contract: PostgresContract, pim: ParamIndexMap): string {\n if (on.kind === 'eq-col-join-on') {\n const left = renderColumn(on.left);\n const right = renderColumn(on.right);\n return `${left} = ${right}`;\n }\n return renderWhere(on, contract, pim);\n}\n\nfunction getInsertColumnOrder(\n rows: ReadonlyArray<Record<string, InsertValue>>,\n contract: PostgresContract,\n tableName: string,\n): string[] {\n const orderedColumns: string[] = [];\n const seenColumns = new Set<string>();\n\n for (const row of rows) {\n for (const column of Object.keys(row)) {\n if (seenColumns.has(column)) {\n continue;\n }\n seenColumns.add(column);\n orderedColumns.push(column);\n }\n }\n\n if (orderedColumns.length > 0) {\n return orderedColumns;\n }\n\n let table: { columns: Record<string, unknown> } | undefined;\n for (const ns of Object.values(contract.storage.namespaces)) {\n // Namespace.tables is Record<string, IRNode> at the interface level;\n // SQL family namespaces hold StorageTable instances which have .columns.\n const found = ns.tables[tableName] as { columns: Record<string, unknown> } | undefined;\n if (found !== undefined) {\n table = found;\n break;\n }\n }\n if (!table) {\n throw new Error(`INSERT target table not found in contract storage: ${tableName}`);\n }\n return Object.keys(table.columns);\n}\n\nfunction renderInsertValue(value: InsertValue | undefined, pim: ParamIndexMap): string {\n if (!value || value.kind === 'default-value') {\n return 'DEFAULT';\n }\n\n switch (value.kind) {\n case 'param-ref':\n case 'prepared-param-ref':\n return renderParamRef(value, pim);\n case 'column-ref':\n return renderColumn(value);\n // v8 ignore next 4\n default:\n throw new Error(\n `Unsupported value node in INSERT: ${(value satisfies never as { kind: string }).kind}`,\n );\n }\n}\n\nfunction renderInsert(ast: InsertAst, contract: PostgresContract, pim: ParamIndexMap): string {\n const table = quoteIdentifier(ast.table.name);\n const rows = ast.rows;\n if (rows.length === 0) {\n throw new Error('INSERT requires at least one row');\n }\n const hasExplicitValues = rows.some((row) => Object.keys(row).length > 0);\n const insertClause = (() => {\n if (!hasExplicitValues) {\n if (rows.length === 1) {\n return `INSERT INTO ${table} DEFAULT VALUES`;\n }\n\n const defaultColumns = getInsertColumnOrder(rows, contract, ast.table.name);\n if (defaultColumns.length === 0) {\n return `INSERT INTO ${table} VALUES ${rows.map(() => '()').join(', ')}`;\n }\n\n const quotedColumns = defaultColumns.map((column) => quoteIdentifier(column));\n const defaultRow = `(${defaultColumns.map(() => 'DEFAULT').join(', ')})`;\n return `INSERT INTO ${table} (${quotedColumns.join(', ')}) VALUES ${rows\n .map(() => defaultRow)\n .join(', ')}`;\n }\n\n const columnOrder = getInsertColumnOrder(rows, contract, ast.table.name);\n const columns = columnOrder.map((column) => quoteIdentifier(column));\n const values = rows\n .map((row) => {\n const renderedRow = columnOrder.map((column) => renderInsertValue(row[column], pim));\n return `(${renderedRow.join(', ')})`;\n })\n .join(', ');\n\n return `INSERT INTO ${table} (${columns.join(', ')}) VALUES ${values}`;\n })();\n const onConflictClause = ast.onConflict\n ? (() => {\n const conflictColumns = ast.onConflict.columns.map((col) => quoteIdentifier(col.column));\n if (conflictColumns.length === 0) {\n throw new Error('INSERT onConflict requires at least one conflict column');\n }\n\n const action = ast.onConflict.action;\n switch (action.kind) {\n case 'do-nothing':\n return ` ON CONFLICT (${conflictColumns.join(', ')}) DO NOTHING`;\n case 'do-update-set': {\n const updateEntries = Object.entries(action.set);\n if (updateEntries.length === 0) {\n throw new Error('INSERT onConflict do-update-set requires at least one assignment');\n }\n const updates = updateEntries.map(([colName, value]) => {\n return `${quoteIdentifier(colName)} = ${renderExpr(value, contract, pim)}`;\n });\n return ` ON CONFLICT (${conflictColumns.join(', ')}) DO UPDATE SET ${updates.join(', ')}`;\n }\n // v8 ignore next 4\n default:\n throw new Error(\n `Unsupported onConflict action: ${(action satisfies never as { kind: string }).kind}`,\n );\n }\n })()\n : '';\n const returningClause = ast.returning?.length\n ? ` RETURNING ${renderReturning(ast.returning, contract, pim)}`\n : '';\n\n return `${insertClause}${onConflictClause}${returningClause}`;\n}\n\nfunction renderUpdate(ast: UpdateAst, contract: PostgresContract, pim: ParamIndexMap): string {\n const table = quoteIdentifier(ast.table.name);\n const setEntries = Object.entries(ast.set);\n if (setEntries.length === 0) {\n throw new Error('UPDATE requires at least one SET assignment');\n }\n const setClauses = setEntries.map(([col, val]) => {\n const column = quoteIdentifier(col);\n return `${column} = ${renderExpr(val, contract, pim)}`;\n });\n\n const whereClause = ast.where ? ` WHERE ${renderWhere(ast.where, contract, pim)}` : '';\n const returningClause = ast.returning?.length\n ? ` RETURNING ${renderReturning(ast.returning, contract, pim)}`\n : '';\n\n return `UPDATE ${table} SET ${setClauses.join(', ')}${whereClause}${returningClause}`;\n}\n\nfunction renderDelete(ast: DeleteAst, contract: PostgresContract, pim: ParamIndexMap): string {\n const table = quoteIdentifier(ast.table.name);\n const whereClause = ast.where ? ` WHERE ${renderWhere(ast.where, contract, pim)}` : '';\n const returningClause = ast.returning?.length\n ? ` RETURNING ${renderReturning(ast.returning, contract, pim)}`\n : '';\n\n return `DELETE FROM ${table}${whereClause}${returningClause}`;\n}\n\nfunction renderRawSql(ast: RawSqlExpr, contract: PostgresContract, pim: ParamIndexMap): string {\n const out: string[] = [];\n for (let i = 0; i < ast.fragments.length; i++) {\n out.push(ast.fragments[i] ?? '');\n if (i < ast.args.length) {\n const arg = ast.args[i];\n if (arg !== undefined) {\n out.push(renderExpr(arg, contract, pim));\n }\n }\n }\n return out.join('');\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma-next/adapter-postgres",
3
- "version": "0.10.0-dev.9",
3
+ "version": "0.11.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -9,30 +9,30 @@
9
9
  "src"
10
10
  ],
11
11
  "dependencies": {
12
- "@prisma-next/contract": "0.10.0-dev.9",
13
- "@prisma-next/contract-authoring": "0.10.0-dev.9",
14
- "@prisma-next/family-sql": "0.10.0-dev.9",
15
- "@prisma-next/framework-components": "0.10.0-dev.9",
16
- "@prisma-next/ids": "0.10.0-dev.9",
17
- "@prisma-next/sql-contract": "0.10.0-dev.9",
18
- "@prisma-next/sql-contract-psl": "0.10.0-dev.9",
19
- "@prisma-next/sql-contract-ts": "0.10.0-dev.9",
20
- "@prisma-next/sql-operations": "0.10.0-dev.9",
21
- "@prisma-next/sql-relational-core": "0.10.0-dev.9",
22
- "@prisma-next/sql-runtime": "0.10.0-dev.9",
23
- "@prisma-next/sql-schema-ir": "0.10.0-dev.9",
24
- "@prisma-next/target-postgres": "0.10.0-dev.9",
25
- "@prisma-next/utils": "0.10.0-dev.9",
12
+ "@prisma-next/contract": "0.11.0",
13
+ "@prisma-next/contract-authoring": "0.11.0",
14
+ "@prisma-next/errors": "0.11.0",
15
+ "@prisma-next/family-sql": "0.11.0",
16
+ "@prisma-next/framework-components": "0.11.0",
17
+ "@prisma-next/ids": "0.11.0",
18
+ "@prisma-next/sql-contract": "0.11.0",
19
+ "@prisma-next/sql-contract-psl": "0.11.0",
20
+ "@prisma-next/sql-contract-ts": "0.11.0",
21
+ "@prisma-next/sql-operations": "0.11.0",
22
+ "@prisma-next/sql-relational-core": "0.11.0",
23
+ "@prisma-next/sql-runtime": "0.11.0",
24
+ "@prisma-next/sql-schema-ir": "0.11.0",
25
+ "@prisma-next/target-postgres": "0.11.0",
26
+ "@prisma-next/utils": "0.11.0",
26
27
  "arktype": "^2.2.0"
27
28
  },
28
29
  "devDependencies": {
29
- "@prisma-next/cli": "0.10.0-dev.9",
30
- "@prisma-next/driver-postgres": "0.10.0-dev.9",
31
- "@prisma-next/errors": "0.10.0-dev.9",
32
- "@prisma-next/migration-tools": "0.10.0-dev.9",
33
- "@prisma-next/test-utils": "0.10.0-dev.9",
34
- "@prisma-next/tsconfig": "0.10.0-dev.9",
35
- "@prisma-next/tsdown": "0.10.0-dev.9",
30
+ "@prisma-next/cli": "0.11.0",
31
+ "@prisma-next/driver-postgres": "0.11.0",
32
+ "@prisma-next/migration-tools": "0.11.0",
33
+ "@prisma-next/test-utils": "0.11.0",
34
+ "@prisma-next/tsconfig": "0.11.0",
35
+ "@prisma-next/tsdown": "0.11.0",
36
36
  "pathe": "^2.0.3",
37
37
  "tsdown": "0.22.0",
38
38
  "typescript": "5.9.3",
@@ -1,8 +1,12 @@
1
1
  import type { ContractMarkerRecord } from '@prisma-next/contract/types';
2
+ import { parseMarkerRowSafely, withMarkerReadErrorHandling } from '@prisma-next/errors/execution';
2
3
  import type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';
3
4
  import { parseContractMarkerRow } from '@prisma-next/family-sql/verify';
4
5
  import type { CodecLookup } from '@prisma-next/framework-components/codec';
5
- import type { ControlDriverInstance } from '@prisma-next/framework-components/control';
6
+ import {
7
+ APP_SPACE_ID,
8
+ type ControlDriverInstance,
9
+ } from '@prisma-next/framework-components/control';
6
10
  import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
7
11
  import type { PostgresEnumStorageEntry } from '@prisma-next/sql-contract/types';
8
12
  import type {
@@ -29,6 +33,8 @@ import { introspectPostgresEnumTypes } from './enum-control-hooks';
29
33
  import { renderLoweredSql } from './sql-renderer';
30
34
  import type { PostgresContract } from './types';
31
35
 
36
+ const POSTGRES_MARKER_TABLE = 'prisma_contract.marker';
37
+
32
38
  /**
33
39
  * Postgres control plane adapter for control-plane operations like introspection.
34
40
  * Provides target-specific implementations for control-plane domain actions.
@@ -98,27 +104,34 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
98
104
  driver: ControlDriverInstance<'sql', 'postgres'>,
99
105
  space: string,
100
106
  ): Promise<ContractMarkerRecord | null> {
101
- const exists = await driver.query(
102
- `select 1
107
+ const markerContext = { space, markerLocation: POSTGRES_MARKER_TABLE };
108
+ const exists = await withMarkerReadErrorHandling(
109
+ () =>
110
+ driver.query(
111
+ `select 1
103
112
  from information_schema.tables
104
113
  where table_schema = $1 and table_name = $2`,
105
- ['prisma_contract', 'marker'],
114
+ ['prisma_contract', 'marker'],
115
+ ),
116
+ markerContext,
106
117
  );
107
118
  if (exists.rows.length === 0) {
108
119
  return null;
109
120
  }
110
121
 
111
- const result = await driver.query<{
112
- core_hash: string;
113
- profile_hash: string;
114
- contract_json: unknown | null;
115
- canonical_version: number | null;
116
- updated_at: Date | string;
117
- app_tag: string | null;
118
- meta: unknown | null;
119
- invariants: readonly string[];
120
- }>(
121
- `select
122
+ const result = await withMarkerReadErrorHandling(
123
+ () =>
124
+ driver.query<{
125
+ core_hash: string;
126
+ profile_hash: string;
127
+ contract_json: unknown | null;
128
+ canonical_version: number | null;
129
+ updated_at: Date | string;
130
+ app_tag: string | null;
131
+ meta: unknown | null;
132
+ invariants: readonly string[];
133
+ }>(
134
+ `select
122
135
  core_hash,
123
136
  profile_hash,
124
137
  contract_json,
@@ -129,12 +142,14 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
129
142
  invariants
130
143
  from prisma_contract.marker
131
144
  where space = $1`,
132
- [space],
145
+ [space],
146
+ ),
147
+ markerContext,
133
148
  );
134
149
 
135
150
  const row = result.rows[0];
136
151
  if (!row) return null;
137
- return parseContractMarkerRow(row);
152
+ return parseMarkerRowSafely(row, parseContractMarkerRow, markerContext);
138
153
  }
139
154
 
140
155
  /**
@@ -146,28 +161,35 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
146
161
  async readAllMarkers(
147
162
  driver: ControlDriverInstance<'sql', 'postgres'>,
148
163
  ): Promise<ReadonlyMap<string, ContractMarkerRecord>> {
149
- const exists = await driver.query(
150
- `select 1
164
+ const markerContext = { space: APP_SPACE_ID, markerLocation: POSTGRES_MARKER_TABLE };
165
+ const exists = await withMarkerReadErrorHandling(
166
+ () =>
167
+ driver.query(
168
+ `select 1
151
169
  from information_schema.tables
152
170
  where table_schema = $1 and table_name = $2`,
153
- ['prisma_contract', 'marker'],
171
+ ['prisma_contract', 'marker'],
172
+ ),
173
+ markerContext,
154
174
  );
155
175
  if (exists.rows.length === 0) {
156
176
  return new Map();
157
177
  }
158
178
 
159
- const result = await driver.query<{
160
- space: string;
161
- core_hash: string;
162
- profile_hash: string;
163
- contract_json: unknown | null;
164
- canonical_version: number | null;
165
- updated_at: Date | string;
166
- app_tag: string | null;
167
- meta: unknown | null;
168
- invariants: readonly string[];
169
- }>(
170
- `select
179
+ const result = await withMarkerReadErrorHandling(
180
+ () =>
181
+ driver.query<{
182
+ space: string;
183
+ core_hash: string;
184
+ profile_hash: string;
185
+ contract_json: unknown | null;
186
+ canonical_version: number | null;
187
+ updated_at: Date | string;
188
+ app_tag: string | null;
189
+ meta: unknown | null;
190
+ invariants: readonly string[];
191
+ }>(
192
+ `select
171
193
  space,
172
194
  core_hash,
173
195
  profile_hash,
@@ -178,11 +200,19 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
178
200
  meta,
179
201
  invariants
180
202
  from prisma_contract.marker`,
203
+ ),
204
+ markerContext,
181
205
  );
182
206
 
183
207
  const rows = new Map<string, ContractMarkerRecord>();
184
208
  for (const row of result.rows) {
185
- rows.set(row.space, parseContractMarkerRow(row));
209
+ rows.set(
210
+ row.space,
211
+ parseMarkerRowSafely(row, parseContractMarkerRow, {
212
+ space: row.space,
213
+ markerLocation: POSTGRES_MARKER_TABLE,
214
+ }),
215
+ );
186
216
  }
187
217
  return rows;
188
218
  }
@@ -739,11 +739,7 @@ function renderInsert(ast: InsertAst, contract: PostgresContract, pim: ParamInde
739
739
  throw new Error('INSERT onConflict do-update-set requires at least one assignment');
740
740
  }
741
741
  const updates = updateEntries.map(([colName, value]) => {
742
- const target = quoteIdentifier(colName);
743
- if (value.kind === 'param-ref' || value.kind === 'prepared-param-ref') {
744
- return `${target} = ${renderParamRef(value, pim)}`;
745
- }
746
- return `${target} = ${renderColumn(value)}`;
742
+ return `${quoteIdentifier(colName)} = ${renderExpr(value, contract, pim)}`;
747
743
  });
748
744
  return ` ON CONFLICT (${conflictColumns.join(', ')}) DO UPDATE SET ${updates.join(', ')}`;
749
745
  }
@@ -770,22 +766,7 @@ function renderUpdate(ast: UpdateAst, contract: PostgresContract, pim: ParamInde
770
766
  }
771
767
  const setClauses = setEntries.map(([col, val]) => {
772
768
  const column = quoteIdentifier(col);
773
- let value: string;
774
- switch (val.kind) {
775
- case 'param-ref':
776
- case 'prepared-param-ref':
777
- value = renderParamRef(val, pim);
778
- break;
779
- case 'column-ref':
780
- value = renderColumn(val);
781
- break;
782
- // v8 ignore next 4
783
- default:
784
- throw new Error(
785
- `Unsupported value node in UPDATE: ${(val satisfies never as { kind: string }).kind}`,
786
- );
787
- }
788
- return `${column} = ${value}`;
769
+ return `${column} = ${renderExpr(val, contract, pim)}`;
789
770
  });
790
771
 
791
772
  const whereClause = ast.where ? ` WHERE ${renderWhere(ast.where, contract, pim)}` : '';