@prisma-next/adapter-postgres 0.5.0 → 0.6.0-dev.1

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.
@@ -69,7 +69,7 @@ declare class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
69
69
  * and returns the schema structure without type mapping or contract enrichment.
70
70
  * Type mapping and enrichment are handled separately by enrichment helpers.
71
71
  *
72
- * Uses batched queries to minimize database round trips (7 queries instead of 5T+3).
72
+ * Uses batched queries to minimize database round trips (6 queries instead of 5T+1).
73
73
  *
74
74
  * @param driver - ControlDriverInstance<'sql', 'postgres'> instance for executing queries
75
75
  * @param contract - Optional contract for contract-guided introspection (filtering, optimization)
@@ -1 +1 @@
1
- {"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/control-adapter.ts","../src/exports/control.ts"],"mappings":";;;;;;;;;;;;;;;;cAiCa,sBAAA,YAAkC,iBAAA;EAAA,SACpC,QAAA;EAAA,SACA,QAAA;EAAA,iBAEQ,WAAA;EAiBQ;;;;;;;cARb,WAAA,GAAc,WAAA;EAuFhB;;;;EAAA,SA/ED,gBAAA,SAAgB,sBAAA;EA4Id;;;;;EAAA,SArIF,mBAAA,SAAmB,2BAAA;EA3BnB;;;;;;;;EAqCT,KAAA,CAAM,GAAA,EAAK,WAAA,EAAa,OAAA,EAAS,cAAA,YAA0B,gBAAA;EAV/B;;;;;;;;EAsBtB,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;;;;;;;;;;;;;;EAwDG,UAAA,CACJ,MAAA,EAAQ,qBAAA,qBACR,SAAA,YACA,MAAA,YACC,OAAA,CAAQ,WAAA;;AC3LmC;;UDslBhC,kBAAA;AAAA;;;cC7kBV,yBAAA,EAA2B,2BAAA"}
1
+ {"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/control-adapter.ts","../src/exports/control.ts"],"mappings":";;;;;;;;;;;;;;;;cAgCa,sBAAA,YAAkC,iBAAA;EAAA,SACpC,QAAA;EAAA,SACA,QAAA;EAAA,iBAEQ,WAAA;EAiBQ;;;;;;;cARb,WAAA,GAAc,WAAA;EAuFhB;;;;EAAA,SA/ED,gBAAA,SAAgB,sBAAA;EA4Id;;;;;EAAA,SArIF,mBAAA,SAAmB,2BAAA;EA3BnB;;;;;;;;EAqCT,KAAA,CAAM,GAAA,EAAK,WAAA,EAAa,OAAA,EAAS,cAAA,YAA0B,gBAAA;EAV/B;;;;;;;;EAsBtB,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;;;;;;;;;;;;;;EAwDG,UAAA,CACJ,MAAA,EAAQ,qBAAA,qBACR,SAAA,YACA,MAAA,YACC,OAAA,CAAQ,WAAA;;AC1LmC;;UDkkBhC,kBAAA;AAAA;;;cCzjBV,yBAAA,EAA2B,2BAAA"}
package/dist/control.mjs CHANGED
@@ -106,7 +106,7 @@ var PostgresControlAdapter = class {
106
106
  * and returns the schema structure without type mapping or contract enrichment.
107
107
  * Type mapping and enrichment are handled separately by enrichment helpers.
108
108
  *
109
- * Uses batched queries to minimize database round trips (7 queries instead of 5T+3).
109
+ * Uses batched queries to minimize database round trips (6 queries instead of 5T+1).
110
110
  *
111
111
  * @param driver - ControlDriverInstance<'sql', 'postgres'> instance for executing queries
112
112
  * @param contract - Optional contract for contract-guided introspection (filtering, optimization)
@@ -114,7 +114,7 @@ var PostgresControlAdapter = class {
114
114
  * @returns Promise resolving to SqlSchemaIR representing the live database schema
115
115
  */
116
116
  async introspect(driver, _contract, schema = "public") {
117
- const [tablesResult, columnsResult, pkResult, fkResult, uniqueResult, indexResult, extensionsResult] = await Promise.all([
117
+ const [tablesResult, columnsResult, pkResult, fkResult, uniqueResult, indexResult] = await Promise.all([
118
118
  driver.query(`SELECT table_name
119
119
  FROM information_schema.tables
120
120
  WHERE table_schema = $1
@@ -227,10 +227,7 @@ var PostgresControlAdapter = class {
227
227
  AND tc.table_name = i.tablename
228
228
  AND tc.constraint_name = i.indexname
229
229
  )
230
- ORDER BY i.tablename, i.indexname, array_position(ix.indkey::int[], a.attnum)`, [schema]),
231
- driver.query(`SELECT extname
232
- FROM pg_extension
233
- ORDER BY extname`, [])
230
+ ORDER BY i.tablename, i.indexname, a.attnum`, [schema])
234
231
  ]);
235
232
  const columnsByTable = groupBy(columnsResult.rows, "table_name");
236
233
  const pksByTable = groupBy(pkResult.rows, "table_name");
@@ -317,7 +314,7 @@ var PostgresControlAdapter = class {
317
314
  const existing = indexesMap.get(idxRow.indexname);
318
315
  if (existing) existing.columns.push(idxRow.attname);
319
316
  else {
320
- const indexType = idxRow.amname === "btree" ? void 0 : idxRow.amname;
317
+ const indexType = idxRow.amname && idxRow.amname !== "btree" ? idxRow.amname : void 0;
321
318
  const indexOptions = parsePgReloptions(idxRow.reloptions, idxRow.indexname);
322
319
  indexesMap.set(idxRow.indexname, {
323
320
  columns: [idxRow.attname],
@@ -344,14 +341,12 @@ var PostgresControlAdapter = class {
344
341
  indexes
345
342
  };
346
343
  }
347
- const dependencies = extensionsResult.rows.map((row) => ({ id: `postgres.extension.${row.extname}` }));
348
344
  const storageTypes = await pgEnumControlHooks.introspectTypes?.({
349
345
  driver,
350
346
  schemaName: schema
351
347
  }) ?? {};
352
348
  return {
353
349
  tables,
354
- dependencies,
355
350
  annotations: { pg: {
356
351
  schema,
357
352
  version: await this.getPostgresVersion(driver),
@@ -1 +1 @@
1
- {"version":3,"file":"control.mjs","names":["parsePostgresDefault","normalizeSchemaNativeType"],"sources":["../src/core/control-adapter.ts","../src/core/control-mutation-defaults.ts","../src/exports/control.ts"],"sourcesContent":["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 type {\n AnyQueryAst,\n LoweredStatement,\n LowererContext,\n} from '@prisma-next/sql-relational-core/ast';\nimport type {\n DependencyIR,\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 { normalizeSchemaNativeType } from '@prisma-next/target-postgres/native-type-normalizer';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { createPostgresBuiltinCodecLookup } from './codec-lookup';\nimport { pgEnumControlHooks } 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 * 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 * Uses batched queries to minimize database round trips (7 queries instead of 5T+3).\n *\n * @param driver - ControlDriverInstance<'sql', 'postgres'> instance for executing queries\n * @param contract - Optional contract for contract-guided introspection (filtering, optimization)\n * @param schema - Schema name to introspect (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 // Execute all queries in parallel for efficiency (7 queries instead of 5T+3)\n const [\n tablesResult,\n columnsResult,\n pkResult,\n fkResult,\n uniqueResult,\n indexResult,\n extensionsResult,\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 driver.query<{\n tablename: string;\n indexname: string;\n indisunique: boolean;\n attname: string;\n attnum: number;\n amname: string;\n reloptions: readonly string[] | null;\n }>(\n `SELECT\n i.tablename,\n i.indexname,\n ix.indisunique,\n a.attname,\n a.attnum,\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 LEFT JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey) 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, array_position(ix.indkey::int[], a.attnum)`,\n [schema],\n ),\n // Query extensions\n driver.query<{ extname: string }>(\n `SELECT extname\n FROM pg_extension\n ORDER BY extname`,\n [],\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 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 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 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 === 'btree' ? undefined : idxRow.amname;\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 dependencies: readonly DependencyIR[] = extensionsResult.rows.map((row) => ({\n id: `postgres.extension.${row.extname}`,\n }));\n\n const storageTypes =\n (await pgEnumControlHooks.introspectTypes?.({ 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 dependencies,\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\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 { escapeLiteral, qualifyName, quoteIdentifier, SqlEscapeError };\nexport { PostgresControlAdapter } from '../core/control-adapter';\n"],"mappings":"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"}
1
+ {"version":3,"file":"control.mjs","names":["parsePostgresDefault","normalizeSchemaNativeType"],"sources":["../src/core/control-adapter.ts","../src/core/control-mutation-defaults.ts","../src/exports/control.ts"],"sourcesContent":["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 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 { normalizeSchemaNativeType } from '@prisma-next/target-postgres/native-type-normalizer';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { createPostgresBuiltinCodecLookup } from './codec-lookup';\nimport { pgEnumControlHooks } 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 * 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 * Uses batched queries to minimize database round trips (6 queries instead of 5T+1).\n *\n * @param driver - ControlDriverInstance<'sql', 'postgres'> instance for executing queries\n * @param contract - Optional contract for contract-guided introspection (filtering, optimization)\n * @param schema - Schema name to introspect (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 // 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 driver.query<{\n tablename: string;\n indexname: string;\n indisunique: boolean;\n attname: string;\n attnum: number;\n amname: string | null;\n reloptions: string[] | null;\n }>(\n `SELECT\n i.tablename,\n i.indexname,\n ix.indisunique,\n a.attname,\n a.attnum,\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 LEFT JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey) 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, a.attnum`,\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 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 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 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 =\n (await pgEnumControlHooks.introspectTypes?.({ 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\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 { escapeLiteral, qualifyName, quoteIdentifier, SqlEscapeError };\nexport { PostgresControlAdapter } from '../core/control-adapter';\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.5.0",
3
+ "version": "0.6.0-dev.1",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -10,34 +10,33 @@
10
10
  ],
11
11
  "dependencies": {
12
12
  "arktype": "^2.1.29",
13
- "@prisma-next/contract": "0.5.0",
14
- "@prisma-next/framework-components": "0.5.0",
15
- "@prisma-next/family-sql": "0.5.0",
16
- "@prisma-next/ids": "0.5.0",
17
- "@prisma-next/contract-authoring": "0.5.0",
18
- "@prisma-next/sql-contract": "0.5.0",
19
- "@prisma-next/sql-contract-psl": "0.5.0",
20
- "@prisma-next/sql-contract-ts": "0.5.0",
21
- "@prisma-next/sql-operations": "0.5.0",
22
- "@prisma-next/sql-relational-core": "0.5.0",
23
- "@prisma-next/sql-runtime": "0.5.0",
24
- "@prisma-next/target-postgres": "0.5.0",
25
- "@prisma-next/sql-schema-ir": "0.5.0",
26
- "@prisma-next/utils": "0.5.0"
13
+ "@prisma-next/contract-authoring": "0.6.0-dev.1",
14
+ "@prisma-next/family-sql": "0.6.0-dev.1",
15
+ "@prisma-next/sql-contract": "0.6.0-dev.1",
16
+ "@prisma-next/sql-contract-psl": "0.6.0-dev.1",
17
+ "@prisma-next/sql-contract-ts": "0.6.0-dev.1",
18
+ "@prisma-next/ids": "0.6.0-dev.1",
19
+ "@prisma-next/contract": "0.6.0-dev.1",
20
+ "@prisma-next/framework-components": "0.6.0-dev.1",
21
+ "@prisma-next/sql-operations": "0.6.0-dev.1",
22
+ "@prisma-next/sql-relational-core": "0.6.0-dev.1",
23
+ "@prisma-next/sql-runtime": "0.6.0-dev.1",
24
+ "@prisma-next/sql-schema-ir": "0.6.0-dev.1",
25
+ "@prisma-next/target-postgres": "0.6.0-dev.1",
26
+ "@prisma-next/utils": "0.6.0-dev.1"
27
27
  },
28
28
  "devDependencies": {
29
29
  "pathe": "^2.0.3",
30
30
  "tsdown": "0.22.0",
31
31
  "typescript": "5.9.3",
32
32
  "vitest": "4.1.5",
33
- "@prisma-next/driver-postgres": "0.5.0",
34
- "@prisma-next/cli": "0.5.0",
35
- "@prisma-next/errors": "0.5.0",
33
+ "@prisma-next/cli": "0.6.0-dev.1",
34
+ "@prisma-next/driver-postgres": "0.6.0-dev.1",
35
+ "@prisma-next/errors": "0.6.0-dev.1",
36
+ "@prisma-next/migration-tools": "0.6.0-dev.1",
36
37
  "@prisma-next/test-utils": "0.0.1",
37
38
  "@prisma-next/tsconfig": "0.0.0",
38
- "@prisma-next/extension-pgvector": "0.5.0",
39
- "@prisma-next/tsdown": "0.0.0",
40
- "@prisma-next/migration-tools": "0.5.0"
39
+ "@prisma-next/tsdown": "0.0.0"
41
40
  },
42
41
  "exports": {
43
42
  "./adapter": "./dist/adapter.mjs",
@@ -9,7 +9,6 @@ import type {
9
9
  LowererContext,
10
10
  } from '@prisma-next/sql-relational-core/ast';
11
11
  import type {
12
- DependencyIR,
13
12
  PrimaryKey,
14
13
  SqlColumnIR,
15
14
  SqlForeignKeyIR,
@@ -181,7 +180,7 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
181
180
  * and returns the schema structure without type mapping or contract enrichment.
182
181
  * Type mapping and enrichment are handled separately by enrichment helpers.
183
182
  *
184
- * Uses batched queries to minimize database round trips (7 queries instead of 5T+3).
183
+ * Uses batched queries to minimize database round trips (6 queries instead of 5T+1).
185
184
  *
186
185
  * @param driver - ControlDriverInstance<'sql', 'postgres'> instance for executing queries
187
186
  * @param contract - Optional contract for contract-guided introspection (filtering, optimization)
@@ -193,39 +192,32 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
193
192
  _contract?: unknown,
194
193
  schema = 'public',
195
194
  ): Promise<SqlSchemaIR> {
196
- // Execute all queries in parallel for efficiency (7 queries instead of 5T+3)
197
- const [
198
- tablesResult,
199
- columnsResult,
200
- pkResult,
201
- fkResult,
202
- uniqueResult,
203
- indexResult,
204
- extensionsResult,
205
- ] = await Promise.all([
206
- // Query all tables
207
- driver.query<{ table_name: string }>(
208
- `SELECT table_name
195
+ // Execute all queries in parallel for efficiency (6 queries instead of 5T+1)
196
+ const [tablesResult, columnsResult, pkResult, fkResult, uniqueResult, indexResult] =
197
+ await Promise.all([
198
+ // Query all tables
199
+ driver.query<{ table_name: string }>(
200
+ `SELECT table_name
209
201
  FROM information_schema.tables
210
202
  WHERE table_schema = $1
211
203
  AND table_type = 'BASE TABLE'
212
204
  ORDER BY table_name`,
213
- [schema],
214
- ),
215
- // Query all columns for all tables in schema
216
- driver.query<{
217
- table_name: string;
218
- column_name: string;
219
- data_type: string;
220
- udt_name: string;
221
- is_nullable: string;
222
- character_maximum_length: number | null;
223
- numeric_precision: number | null;
224
- numeric_scale: number | null;
225
- column_default: string | null;
226
- formatted_type: string | null;
227
- }>(
228
- `SELECT
205
+ [schema],
206
+ ),
207
+ // Query all columns for all tables in schema
208
+ driver.query<{
209
+ table_name: string;
210
+ column_name: string;
211
+ data_type: string;
212
+ udt_name: string;
213
+ is_nullable: string;
214
+ character_maximum_length: number | null;
215
+ numeric_precision: number | null;
216
+ numeric_scale: number | null;
217
+ column_default: string | null;
218
+ formatted_type: string | null;
219
+ }>(
220
+ `SELECT
229
221
  c.table_name,
230
222
  column_name,
231
223
  data_type,
@@ -249,16 +241,16 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
249
241
  AND NOT a.attisdropped
250
242
  WHERE c.table_schema = $1
251
243
  ORDER BY c.table_name, c.ordinal_position`,
252
- [schema],
253
- ),
254
- // Query all primary keys for all tables in schema
255
- driver.query<{
256
- table_name: string;
257
- constraint_name: string;
258
- column_name: string;
259
- ordinal_position: number;
260
- }>(
261
- `SELECT
244
+ [schema],
245
+ ),
246
+ // Query all primary keys for all tables in schema
247
+ driver.query<{
248
+ table_name: string;
249
+ constraint_name: string;
250
+ column_name: string;
251
+ ordinal_position: number;
252
+ }>(
253
+ `SELECT
262
254
  tc.table_name,
263
255
  tc.constraint_name,
264
256
  kcu.column_name,
@@ -271,24 +263,24 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
271
263
  WHERE tc.table_schema = $1
272
264
  AND tc.constraint_type = 'PRIMARY KEY'
273
265
  ORDER BY tc.table_name, kcu.ordinal_position`,
274
- [schema],
275
- ),
276
- // Query all foreign keys for all tables in schema, including referential actions.
277
- // Uses pg_catalog for correct positional pairing of composite FK columns
278
- // (information_schema.constraint_column_usage lacks ordinal_position,
279
- // which causes Cartesian products for multi-column FKs).
280
- driver.query<{
281
- table_name: string;
282
- constraint_name: string;
283
- column_name: string;
284
- ordinal_position: number;
285
- referenced_table_schema: string;
286
- referenced_table_name: string;
287
- referenced_column_name: string;
288
- delete_rule: string;
289
- update_rule: string;
290
- }>(
291
- `SELECT
266
+ [schema],
267
+ ),
268
+ // Query all foreign keys for all tables in schema, including referential actions.
269
+ // Uses pg_catalog for correct positional pairing of composite FK columns
270
+ // (information_schema.constraint_column_usage lacks ordinal_position,
271
+ // which causes Cartesian products for multi-column FKs).
272
+ driver.query<{
273
+ table_name: string;
274
+ constraint_name: string;
275
+ column_name: string;
276
+ ordinal_position: number;
277
+ referenced_table_schema: string;
278
+ referenced_table_name: string;
279
+ referenced_column_name: string;
280
+ delete_rule: string;
281
+ update_rule: string;
282
+ }>(
283
+ `SELECT
292
284
  tc.table_name,
293
285
  tc.constraint_name,
294
286
  kcu.column_name,
@@ -321,16 +313,16 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
321
313
  WHERE tc.table_schema = $1
322
314
  AND tc.constraint_type = 'FOREIGN KEY'
323
315
  ORDER BY tc.table_name, tc.constraint_name, kcu.ordinal_position`,
324
- [schema],
325
- ),
326
- // Query all unique constraints for all tables in schema (excluding PKs)
327
- driver.query<{
328
- table_name: string;
329
- constraint_name: string;
330
- column_name: string;
331
- ordinal_position: number;
332
- }>(
333
- `SELECT
316
+ [schema],
317
+ ),
318
+ // Query all unique constraints for all tables in schema (excluding PKs)
319
+ driver.query<{
320
+ table_name: string;
321
+ constraint_name: string;
322
+ column_name: string;
323
+ ordinal_position: number;
324
+ }>(
325
+ `SELECT
334
326
  tc.table_name,
335
327
  tc.constraint_name,
336
328
  kcu.column_name,
@@ -343,19 +335,19 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
343
335
  WHERE tc.table_schema = $1
344
336
  AND tc.constraint_type = 'UNIQUE'
345
337
  ORDER BY tc.table_name, tc.constraint_name, kcu.ordinal_position`,
346
- [schema],
347
- ),
348
- // Query all indexes for all tables in schema (excluding constraints)
349
- driver.query<{
350
- tablename: string;
351
- indexname: string;
352
- indisunique: boolean;
353
- attname: string;
354
- attnum: number;
355
- amname: string;
356
- reloptions: readonly string[] | null;
357
- }>(
358
- `SELECT
338
+ [schema],
339
+ ),
340
+ // Query all indexes for all tables in schema (excluding constraints)
341
+ driver.query<{
342
+ tablename: string;
343
+ indexname: string;
344
+ indisunique: boolean;
345
+ attname: string;
346
+ attnum: number;
347
+ amname: string | null;
348
+ reloptions: string[] | null;
349
+ }>(
350
+ `SELECT
359
351
  i.tablename,
360
352
  i.indexname,
361
353
  ix.indisunique,
@@ -379,17 +371,10 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
379
371
  AND tc.table_name = i.tablename
380
372
  AND tc.constraint_name = i.indexname
381
373
  )
382
- ORDER BY i.tablename, i.indexname, array_position(ix.indkey::int[], a.attnum)`,
383
- [schema],
384
- ),
385
- // Query extensions
386
- driver.query<{ extname: string }>(
387
- `SELECT extname
388
- FROM pg_extension
389
- ORDER BY extname`,
390
- [],
391
- ),
392
- ]);
374
+ ORDER BY i.tablename, i.indexname, a.attnum`,
375
+ [schema],
376
+ ),
377
+ ]);
393
378
 
394
379
  // Group results by table name for efficient lookup
395
380
  const columnsByTable = groupBy(columnsResult.rows, 'table_name');
@@ -546,7 +531,7 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
546
531
  // Drop btree (the Postgres default) so a contract index without an
547
532
  // explicit type matches a default-method introspected index without
548
533
  // forcing DROP+CREATE on every plan.
549
- const indexType = idxRow.amname === 'btree' ? undefined : idxRow.amname;
534
+ const indexType = idxRow.amname && idxRow.amname !== 'btree' ? idxRow.amname : undefined;
550
535
  const indexOptions = parsePgReloptions(idxRow.reloptions, idxRow.indexname);
551
536
  indexesMap.set(idxRow.indexname, {
552
537
  columns: [idxRow.attname],
@@ -575,10 +560,6 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
575
560
  };
576
561
  }
577
562
 
578
- const dependencies: readonly DependencyIR[] = extensionsResult.rows.map((row) => ({
579
- id: `postgres.extension.${row.extname}`,
580
- }));
581
-
582
563
  const storageTypes =
583
564
  (await pgEnumControlHooks.introspectTypes?.({ driver, schemaName: schema })) ?? {};
584
565
 
@@ -595,7 +576,6 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
595
576
 
596
577
  return {
597
578
  tables,
598
- dependencies,
599
579
  annotations,
600
580
  };
601
581
  }