@dbsp/adapter-pgsql 1.11.2 → 2.0.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.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ExpressionRef, IndexInfo, TruncateOptions, VacuumOptions, AlterColumnOptions, CreateIndexOptions, DropIndexOptions, ModelIR as ModelIR$1 } from '@dbsp/core';
2
2
  export { normalizeSQL } from '@dbsp/core';
3
3
  import * as _dbsp_types from '@dbsp/types';
4
- import { ColumnListInput, ParamIntent, JsonAggOrderByEntry, DialectCapabilities, ModelIR, DbCasing, ColumnIR, HierarchyIR, MutationReturningItem, WhereIntent, Adapter, AdapterLogger, AdapterCapabilities, PlanReport, CompiledNqlQuery, CompileOptions, CompiledQuery, CompileResultWithIncludes, SubqueryIncludeInfo, ExpressionIntent, InsertIntent, InsertFromIntent, UpdateIntent, BatchUpdateIntent, DeleteIntent, UpsertIntent, UpsertFromIntent, RecursivePlanReport, CteQueryIntent, SetOperationIntent, DumpMeta, Dump, AdapterStreamOptions, CompileOnlyAdapter, QueryIntent } from '@dbsp/types';
4
+ import { DialectCapabilities, ModelIR, ColumnListInput, ParamIntent, JsonAggOrderByEntry, IndexIR, DbCasing, ColumnIR, HierarchyIR, MutationReturningItem, WhereIntent, Adapter, AdapterLogger, AdapterCapabilities, PlanReport, CompiledNqlQuery, CompileOptions, CompiledQuery, CompileResultWithIncludes, SubqueryIncludeInfo, ExpressionIntent, InsertIntent, InsertFromIntent, UpdateIntent, BatchUpdateIntent, DeleteIntent, UpsertIntent, UpsertFromIntent, RecursivePlanReport, CteQueryIntent, SetOperationIntent, DumpMeta, Dump, AdapterStreamOptions, CompileOnlyAdapter, QueryIntent } from '@dbsp/types';
5
5
  import * as _pgsql_types from '@pgsql/types';
6
6
  import { Node, OnConflictClause, ParamRef } from '@pgsql/types';
7
7
  import { Pool, PoolClient } from 'pg';
@@ -99,6 +99,253 @@ declare function getNamingPluginForDbCasing(casing: 'snake_case' | 'camelCase' |
99
99
 
100
100
  type BindingNameRegistry = ReadonlySet<string>;
101
101
 
102
+ /**
103
+ * Immutable context passed to all handlers during compilation.
104
+ */
105
+ interface CompilerContext {
106
+ /** Naming convention transformer */
107
+ readonly naming: NamingPlugin;
108
+ /** Schema name for table qualification (optional) */
109
+ readonly schema?: string;
110
+ /** Dialect capabilities for adapter-layer SQL surface gates */
111
+ readonly dialectCapabilities?: DialectCapabilities;
112
+ /** Root table name for the query */
113
+ readonly rootTable: string;
114
+ /** Current table alias (for JOINs) */
115
+ readonly currentAlias?: string;
116
+ /** Final relation path/name → SQL join alias map for relation-aware expression contexts */
117
+ readonly aliases?: ReadonlyMap<string, string>;
118
+ /** Maximum recursive depth (default: 100) */
119
+ readonly maxRecursiveDepth: number;
120
+ /** Optional callback for raw SQL audit trail */
121
+ readonly onRawSQL?: (sql: string) => void;
122
+ /** Default primary key column name for convention fallbacks (default: 'id') */
123
+ readonly defaultPkColumnName?: string;
124
+ /** Convention for deriving FK column names: (tableName, pkName) => fkColumnName */
125
+ readonly deriveFkColumnName?: FkColumnDerivation;
126
+ /** Alias of the outer (parent) query — used for FieldRef scope:'outer' resolution in EXISTS subqueries */
127
+ readonly outerAlias?: string;
128
+ /** Query-local CTE/binding names that must not be schema-qualified. */
129
+ readonly bindingNames?: BindingNameRegistry;
130
+ /**
131
+ * Optional callback to compile a QueryIntent into an AST Node (SubLink subselect).
132
+ * Set by PlanCompiler when compiling selectCustomExpression — enables SubqueryExpressionIntent
133
+ * to embed a fully compiled sub-SELECT into the parent SELECT column list.
134
+ *
135
+ * @param query - The inner QueryIntent to compile
136
+ * @param paramOffset - Current outer paramIndex; inner $N are renumbered by this offset
137
+ * @returns The compiled SelectStmt AST node and the inner parameters
138
+ */
139
+ readonly compileSubquery?: (query: _dbsp_types.QueryIntent, paramOffset: number) => {
140
+ ast: Node;
141
+ parameters: readonly unknown[];
142
+ };
143
+ /**
144
+ * Optional recursive compiler for NQL-origin SELECT expression values nested
145
+ * inside handler arguments, such as coalesce(upper(name), :fallback) or
146
+ * (price + :a) * :b.
147
+ */
148
+ readonly compileNqlSelectExpression?: (value: unknown, ctx: CompilerContext, state: CompilerState) => Node;
149
+ /**
150
+ * Optional callback to compile a custom fn() FILTER (WHERE ...) condition.
151
+ * Set by PlanCompiler to keep WHERE-dispatcher dependencies out of expression
152
+ * handlers while still applying FILTER in every expression position.
153
+ */
154
+ readonly compileCustomFnFilter?: (filterIntent: _dbsp_types.WhereIntent, ctx: CompilerContext, state: CompilerState) => Node | undefined;
155
+ /**
156
+ * Optional ModelIR for type-aware parameter casting.
157
+ * When provided, WHERE comparisons emit `$N::type` to eliminate
158
+ * PostgreSQL type inference ambiguity for nullable columns.
159
+ */
160
+ readonly model?: ModelIR;
161
+ }
162
+ /**
163
+ * Mutable state maintained during compilation.
164
+ */
165
+ interface CompilerState {
166
+ /** Collected parameters in order */
167
+ parameters: unknown[];
168
+ /** Current parameter index (1-based for PostgreSQL) */
169
+ paramIndex: number;
170
+ /** Registered CTEs for the query */
171
+ ctes: Map<string, Node>;
172
+ /** Table aliases in use */
173
+ aliases: Map<string, string>;
174
+ /** JOIN clauses accumulated */
175
+ joins: Node[];
176
+ }
177
+ /**
178
+ * Base decision interface matching core's PlanDecision structure.
179
+ */
180
+ interface Decision {
181
+ readonly type: string;
182
+ readonly table?: string;
183
+ readonly column?: string;
184
+ readonly alias?: string;
185
+ readonly operator?: string;
186
+ readonly value?: unknown;
187
+ readonly paramIndex?: number;
188
+ readonly dataType?: string;
189
+ readonly direction?: 'ASC' | 'DESC';
190
+ readonly nulls?: 'FIRST' | 'LAST';
191
+ readonly joinType?: 'inner' | 'left';
192
+ readonly sourceColumn?: ColumnListInput;
193
+ readonly targetColumn?: ColumnListInput;
194
+ readonly targetTable?: string;
195
+ readonly function?: string;
196
+ /** Apply DISTINCT to a SELECT-list aggregate (e.g. COUNT(DISTINCT col)). */
197
+ readonly distinct?: boolean;
198
+ readonly args?: readonly unknown[];
199
+ readonly conditions?: readonly Decision[];
200
+ readonly columns?: readonly string[];
201
+ readonly values?: readonly unknown[];
202
+ readonly set?: readonly {
203
+ column: string;
204
+ value: unknown;
205
+ }[];
206
+ readonly limit?: number | ParamIntent | {
207
+ paramIndex: number;
208
+ };
209
+ readonly offset?: number | ParamIntent | {
210
+ paramIndex: number;
211
+ };
212
+ readonly strategy?: 'join' | 'lateral' | 'json_agg' | 'cte';
213
+ readonly relation?: string;
214
+ readonly relationName?: string;
215
+ readonly relationPath?: string;
216
+ readonly hydrationPrefix?: string;
217
+ readonly include?: readonly Decision[];
218
+ readonly relationType?: 'belongsTo' | 'hasMany' | 'hasOne';
219
+ readonly foreignKey?: ColumnListInput;
220
+ readonly parentKey?: ColumnListInput;
221
+ readonly orderByFallback?: boolean;
222
+ readonly children?: readonly Decision[];
223
+ readonly partition?: readonly string[];
224
+ readonly orderBy?: readonly {
225
+ column: string;
226
+ direction?: 'ASC' | 'DESC';
227
+ }[] | readonly JsonAggOrderByEntry[];
228
+ readonly frame?: string;
229
+ readonly maxDepth?: number;
230
+ readonly pathColumn?: string;
231
+ readonly cycleDetection?: boolean;
232
+ readonly selectColumn?: string;
233
+ readonly aggregate?: string;
234
+ /**
235
+ * Apply DISTINCT to a scalar subquery's aggregate (e.g. AVG(DISTINCT price)).
236
+ * Deliberately NOT named `distinct` — `assertNoDroppedDecisionModifiers`
237
+ * (subquery-emission.ts) treats a top-level `distinct === true` on ANY
238
+ * subquery decision as an unsupported query-level DISTINCT modifier and
239
+ * throws. This field is scoped to the aggregate projection only, so it
240
+ * must not collide with that generic guard.
241
+ */
242
+ readonly aggregateDistinct?: boolean;
243
+ readonly subqueryOperator?: string;
244
+ readonly traversal?: string;
245
+ readonly traversals?: readonly {
246
+ traversal: string;
247
+ targetColumn?: string;
248
+ }[];
249
+ readonly isRecursive?: boolean;
250
+ readonly fkColumn?: string;
251
+ readonly pkColumn?: string;
252
+ readonly expandRelation?: string;
253
+ readonly relationColumns?: readonly string[];
254
+ readonly columnAliases?: Readonly<Record<string, string>>;
255
+ readonly jsonPath?: readonly unknown[];
256
+ readonly jsonMode?: 'json' | 'text';
257
+ readonly _compiledFilterWhere?: _pgsql_types.Node;
258
+ readonly filterWhere?: _pgsql_types.Node;
259
+ readonly expressionIntent?: unknown;
260
+ readonly escape?: string;
261
+ /**
262
+ * Provenance: the ORIGINAL QueryIntent before lowering.
263
+ * Set by every lowering site (convertIn, convertSubquery, normalizeToDecision,
264
+ * dispatchWhere, mapInSubqueryCondition) so that `buildPredicateSubquerySelect`
265
+ * (subquery-emission.ts) can validate the true caller intent rather than the
266
+ * stripped-down lowered decision fields.
267
+ *
268
+ * Required for IN / scalar / inSubquery / notInSubquery decisions.
269
+ * Optional on other decision types.
270
+ */
271
+ readonly subqueryIntent?: _dbsp_types.QueryIntent;
272
+ }
273
+ /**
274
+ * Handler for WHERE clause conditions.
275
+ * Transforms condition decisions into PostgreSQL AST expressions.
276
+ */
277
+ interface WhereHandler {
278
+ /** Operator(s) this handler supports */
279
+ readonly operators: readonly string[];
280
+ /**
281
+ * Compile a WHERE condition to AST.
282
+ * @param decision The condition decision
283
+ * @param ctx Immutable compiler context
284
+ * @param state Mutable compiler state
285
+ * @param dispatch Callback to compile nested conditions
286
+ * @returns PostgreSQL AST node for the condition
287
+ */
288
+ compile(decision: Decision, ctx: CompilerContext, state: CompilerState, dispatch: WhereDispatcher): Node;
289
+ }
290
+ /**
291
+ * Dispatcher for recursive WHERE compilation.
292
+ */
293
+ type WhereDispatcher = (decision: Decision, ctx: CompilerContext, state: CompilerState) => Node;
294
+ /**
295
+ * Handler for SELECT expressions.
296
+ * Transforms expression decisions into PostgreSQL AST nodes.
297
+ */
298
+ interface ExpressionHandler {
299
+ /** Expression type(s) this handler supports */
300
+ readonly types: readonly string[];
301
+ /**
302
+ * Safe to use when a function name comes from NQL text.
303
+ *
304
+ * Raw/escape-hatch handlers must not set this. NQL-origin function names use
305
+ * this opt-in surface only, then fall back to generic FuncCall emission.
306
+ */
307
+ readonly nqlSafe?: boolean;
308
+ /**
309
+ * Compile an expression to AST.
310
+ * @param decision The expression decision
311
+ * @param ctx Immutable compiler context
312
+ * @param state Mutable compiler state
313
+ * @returns PostgreSQL AST node for the expression
314
+ */
315
+ compile(decision: Decision, ctx: CompilerContext, state: CompilerState): Node;
316
+ }
317
+ /**
318
+ * Handler for include/relation strategies.
319
+ * Transforms include decisions into PostgreSQL constructs (JOIN, LATERAL, json_agg, CTE).
320
+ */
321
+ interface IncludeHandler {
322
+ /** Strategy this handler implements */
323
+ readonly strategy: 'join' | 'lateral' | 'json_agg' | 'cte';
324
+ /**
325
+ * Compile an include to AST.
326
+ * @param decision The include decision
327
+ * @param ctx Immutable compiler context
328
+ * @param state Mutable compiler state
329
+ * @returns Object with modifications to apply
330
+ */
331
+ compile(decision: Decision, ctx: CompilerContext, state: CompilerState): IncludeResult;
332
+ }
333
+ /**
334
+ * Result of include compilation.
335
+ */
336
+ interface IncludeResult {
337
+ /** Additional target list items (SELECT columns) */
338
+ targets?: Node[];
339
+ /** JOIN to add to FROM clause */
340
+ join?: Node;
341
+ /** Additional JOINs for cascaded includes (e.g., flat deep nesting) */
342
+ additionalJoins?: Node[];
343
+ /** CTE to add to WITH clause */
344
+ cte?: Node;
345
+ /** Subquery for LATERAL */
346
+ lateral?: Node;
347
+ }
348
+
102
349
  type PlanExpressionOrderBy = readonly {
103
350
  field: string;
104
351
  direction?: 'asc' | 'desc';
@@ -459,11 +706,9 @@ declare class PlanCompiler {
459
706
  private compileCaseValue;
460
707
  /**
461
708
  * Compile a custom ExpressionIntent (customFn, customOp, ref, cast, unary,
462
- * array, function, subquery, …) to an AST node, applying the customFn FILTER
463
- * clause. Shared by the `selectCustomExpression` target path and CASE
464
- * THEN/ELSE values so both render the full expression surface identically
465
- * (every expression kind + FILTER), rather than one path silently binding
466
- * expressions as parameters or dropping FILTER.
709
+ * array, function, subquery, …) to an AST node through the shared expression
710
+ * compiler. Shared by the `selectCustomExpression` target path and CASE
711
+ * THEN/ELSE values so both render the full expression surface identically.
467
712
  */
468
713
  private compileCustomExpressionNode;
469
714
  private compileInsert;
@@ -494,7 +739,11 @@ declare function compilePlan(plan: SimplifiedPlanReport, options?: CompilerOptio
494
739
  interface GenerateDDLOptions {
495
740
  /** Include DROP TABLE IF EXISTS statements before CREATE TABLE */
496
741
  readonly includeDropStatements?: boolean;
497
- /** Database schema name (e.g., 'public', 'tenant_123') */
742
+ /**
743
+ * Database schema name (e.g., 'public', 'tenant_123').
744
+ * Required when emitted DDL would otherwise mix non-default target-scoped
745
+ * custom types/enums with unqualified table SQL.
746
+ */
498
747
  readonly schemaName?: string;
499
748
  /**
500
749
  * Automatically create indexes on foreign key columns.
@@ -520,6 +769,15 @@ interface GenerateDDLOptions {
520
769
  * @returns Array of DDL statements in dependency order
521
770
  */
522
771
  declare function generateDDL(schema: ModelIR, options?: GenerateDDLOptions): string[];
772
+ declare function generateCreateIndex(tableName: string, idx: IndexIR, schemaName: string | undefined, naming: NamingPlugin): string;
773
+ /**
774
+ * Returns whether the PostgreSQL DDL generator can emit this IndexIR.
775
+ *
776
+ * Keep this as the single representability predicate for generated schema
777
+ * omission and destructive-drop classification: both sides must agree on the
778
+ * exact validation surface used by generateCreateIndex().
779
+ */
780
+ declare function canGenerateCreateIndex(tableName: string, idx: IndexIR, schemaName?: string | undefined, naming?: NamingPlugin): boolean;
523
781
 
524
782
  /**
525
783
  * Schema Comparison Engine (DDL-PROV Block 1)
@@ -606,7 +864,11 @@ declare function compareSchemata(schema: ModelIR, db: ModelIR, options?: Compare
606
864
  */
607
865
 
608
866
  interface MigrationSQLOptions {
609
- /** Schema namespace (default: none — unqualified) */
867
+ /**
868
+ * Schema namespace (default: none — unqualified).
869
+ * Required when emitted migration SQL would otherwise mix non-default
870
+ * target-scoped custom types/enums with unqualified table SQL.
871
+ */
610
872
  readonly schemaName?: string;
611
873
  /** Whether to include destructive changes (drops) */
612
874
  readonly includeDestructive?: boolean;
@@ -706,19 +968,6 @@ interface MigrationRecord {
706
968
  /** Whether this migration contains destructive changes */
707
969
  readonly destructive: boolean;
708
970
  }
709
- /**
710
- * Acquire a session-level advisory lock for migration operations.
711
- *
712
- * @deprecated Use {@link withMigrationLock} instead — pool.query may release
713
- * the connection (and the lock) before the migration completes.
714
- */
715
- declare function acquireMigrationLock(pool: Pool): Promise<void>;
716
- /**
717
- * Release the session-level advisory lock for migration operations.
718
- *
719
- * @deprecated Use {@link withMigrationLock} instead.
720
- */
721
- declare function releaseMigrationLock(pool: Pool): Promise<void>;
722
971
  /**
723
972
  * Execute a callback under an advisory lock using a dedicated client.
724
973
  * The lock is held for the duration of the callback.
@@ -770,7 +1019,7 @@ declare function removeMigrationRecord(pool: Pool, name: string): Promise<void>;
770
1019
  * @param col - Column definition from ModelIR
771
1020
  * @returns PostgreSQL type string (e.g., 'VARCHAR(255)', 'SERIAL', 'JSONB')
772
1021
  */
773
- declare function mapColumnType(col: ColumnIR): string;
1022
+ declare function mapColumnType(col: ColumnIR, targetSchema?: string): string;
774
1023
  /**
775
1024
  * Map OnDeleteAction to PostgreSQL syntax.
776
1025
  */
@@ -1095,247 +1344,6 @@ declare function innerProduct(column: string, vector: number[]): ExpressionRef;
1095
1344
  */
1096
1345
  declare function vectorDims(column: string): ExpressionRef;
1097
1346
 
1098
- /**
1099
- * Immutable context passed to all handlers during compilation.
1100
- */
1101
- interface CompilerContext {
1102
- /** Naming convention transformer */
1103
- readonly naming: NamingPlugin;
1104
- /** Schema name for table qualification (optional) */
1105
- readonly schema?: string;
1106
- /** Dialect capabilities for adapter-layer SQL surface gates */
1107
- readonly dialectCapabilities?: DialectCapabilities;
1108
- /** Root table name for the query */
1109
- readonly rootTable: string;
1110
- /** Current table alias (for JOINs) */
1111
- readonly currentAlias?: string;
1112
- /** Final relation path/name → SQL join alias map for relation-aware expression contexts */
1113
- readonly aliases?: ReadonlyMap<string, string>;
1114
- /** Maximum recursive depth (default: 100) */
1115
- readonly maxRecursiveDepth: number;
1116
- /** Optional callback for raw SQL audit trail */
1117
- readonly onRawSQL?: (sql: string) => void;
1118
- /** Default primary key column name for convention fallbacks (default: 'id') */
1119
- readonly defaultPkColumnName?: string;
1120
- /** Convention for deriving FK column names: (tableName, pkName) => fkColumnName */
1121
- readonly deriveFkColumnName?: FkColumnDerivation;
1122
- /** Alias of the outer (parent) query — used for FieldRef scope:'outer' resolution in EXISTS subqueries */
1123
- readonly outerAlias?: string;
1124
- /** Query-local CTE/binding names that must not be schema-qualified. */
1125
- readonly bindingNames?: BindingNameRegistry;
1126
- /**
1127
- * Optional callback to compile a QueryIntent into an AST Node (SubLink subselect).
1128
- * Set by PlanCompiler when compiling selectCustomExpression — enables SubqueryExpressionIntent
1129
- * to embed a fully compiled sub-SELECT into the parent SELECT column list.
1130
- *
1131
- * @param query - The inner QueryIntent to compile
1132
- * @param paramOffset - Current outer paramIndex; inner $N are renumbered by this offset
1133
- * @returns The compiled SelectStmt AST node and the inner parameters
1134
- */
1135
- readonly compileSubquery?: (query: _dbsp_types.QueryIntent, paramOffset: number) => {
1136
- ast: Node;
1137
- parameters: readonly unknown[];
1138
- };
1139
- /**
1140
- * Optional recursive compiler for NQL-origin SELECT expression values nested
1141
- * inside handler arguments, such as coalesce(upper(name), :fallback) or
1142
- * (price + :a) * :b.
1143
- */
1144
- readonly compileNqlSelectExpression?: (value: unknown, ctx: CompilerContext, state: CompilerState) => Node;
1145
- /**
1146
- * Optional ModelIR for type-aware parameter casting.
1147
- * When provided, WHERE comparisons emit `$N::type` to eliminate
1148
- * PostgreSQL type inference ambiguity for nullable columns.
1149
- */
1150
- readonly model?: ModelIR;
1151
- }
1152
- /**
1153
- * Mutable state maintained during compilation.
1154
- */
1155
- interface CompilerState {
1156
- /** Collected parameters in order */
1157
- parameters: unknown[];
1158
- /** Current parameter index (1-based for PostgreSQL) */
1159
- paramIndex: number;
1160
- /** Registered CTEs for the query */
1161
- ctes: Map<string, Node>;
1162
- /** Table aliases in use */
1163
- aliases: Map<string, string>;
1164
- /** JOIN clauses accumulated */
1165
- joins: Node[];
1166
- }
1167
- /**
1168
- * Base decision interface matching core's PlanDecision structure.
1169
- */
1170
- interface Decision {
1171
- readonly type: string;
1172
- readonly table?: string;
1173
- readonly column?: string;
1174
- readonly alias?: string;
1175
- readonly operator?: string;
1176
- readonly value?: unknown;
1177
- readonly paramIndex?: number;
1178
- readonly dataType?: string;
1179
- readonly direction?: 'ASC' | 'DESC';
1180
- readonly nulls?: 'FIRST' | 'LAST';
1181
- readonly joinType?: 'inner' | 'left';
1182
- readonly sourceColumn?: ColumnListInput;
1183
- readonly targetColumn?: ColumnListInput;
1184
- readonly targetTable?: string;
1185
- readonly function?: string;
1186
- /** Apply DISTINCT to a SELECT-list aggregate (e.g. COUNT(DISTINCT col)). */
1187
- readonly distinct?: boolean;
1188
- readonly args?: readonly unknown[];
1189
- readonly conditions?: readonly Decision[];
1190
- readonly columns?: readonly string[];
1191
- readonly values?: readonly unknown[];
1192
- readonly set?: readonly {
1193
- column: string;
1194
- value: unknown;
1195
- }[];
1196
- readonly limit?: number | ParamIntent | {
1197
- paramIndex: number;
1198
- };
1199
- readonly offset?: number | ParamIntent | {
1200
- paramIndex: number;
1201
- };
1202
- readonly strategy?: 'join' | 'lateral' | 'json_agg' | 'cte';
1203
- readonly relation?: string;
1204
- readonly relationName?: string;
1205
- readonly relationPath?: string;
1206
- readonly hydrationPrefix?: string;
1207
- readonly include?: readonly Decision[];
1208
- readonly relationType?: 'belongsTo' | 'hasMany' | 'hasOne';
1209
- readonly foreignKey?: ColumnListInput;
1210
- readonly parentKey?: ColumnListInput;
1211
- readonly orderByFallback?: boolean;
1212
- readonly children?: readonly Decision[];
1213
- readonly partition?: readonly string[];
1214
- readonly orderBy?: readonly {
1215
- column: string;
1216
- direction?: 'ASC' | 'DESC';
1217
- }[] | readonly JsonAggOrderByEntry[];
1218
- readonly frame?: string;
1219
- readonly maxDepth?: number;
1220
- readonly pathColumn?: string;
1221
- readonly cycleDetection?: boolean;
1222
- readonly selectColumn?: string;
1223
- readonly aggregate?: string;
1224
- /**
1225
- * Apply DISTINCT to a scalar subquery's aggregate (e.g. AVG(DISTINCT price)).
1226
- * Deliberately NOT named `distinct` — `assertNoDroppedDecisionModifiers`
1227
- * (subquery-emission.ts) treats a top-level `distinct === true` on ANY
1228
- * subquery decision as an unsupported query-level DISTINCT modifier and
1229
- * throws. This field is scoped to the aggregate projection only, so it
1230
- * must not collide with that generic guard.
1231
- */
1232
- readonly aggregateDistinct?: boolean;
1233
- readonly subqueryOperator?: string;
1234
- readonly traversal?: string;
1235
- readonly traversals?: readonly {
1236
- traversal: string;
1237
- targetColumn?: string;
1238
- }[];
1239
- readonly isRecursive?: boolean;
1240
- readonly fkColumn?: string;
1241
- readonly pkColumn?: string;
1242
- readonly expandRelation?: string;
1243
- readonly relationColumns?: readonly string[];
1244
- readonly columnAliases?: Readonly<Record<string, string>>;
1245
- readonly jsonPath?: readonly unknown[];
1246
- readonly jsonMode?: 'json' | 'text';
1247
- readonly _compiledFilterWhere?: _pgsql_types.Node;
1248
- readonly filterWhere?: _pgsql_types.Node;
1249
- readonly expressionIntent?: unknown;
1250
- readonly escape?: string;
1251
- /**
1252
- * Provenance: the ORIGINAL QueryIntent before lowering.
1253
- * Set by every lowering site (convertIn, convertSubquery, normalizeToDecision,
1254
- * dispatchWhere, mapInSubqueryCondition) so that `buildPredicateSubquerySelect`
1255
- * (subquery-emission.ts) can validate the true caller intent rather than the
1256
- * stripped-down lowered decision fields.
1257
- *
1258
- * Required for IN / scalar / inSubquery / notInSubquery decisions.
1259
- * Optional on other decision types.
1260
- */
1261
- readonly subqueryIntent?: _dbsp_types.QueryIntent;
1262
- }
1263
- /**
1264
- * Handler for WHERE clause conditions.
1265
- * Transforms condition decisions into PostgreSQL AST expressions.
1266
- */
1267
- interface WhereHandler {
1268
- /** Operator(s) this handler supports */
1269
- readonly operators: readonly string[];
1270
- /**
1271
- * Compile a WHERE condition to AST.
1272
- * @param decision The condition decision
1273
- * @param ctx Immutable compiler context
1274
- * @param state Mutable compiler state
1275
- * @param dispatch Callback to compile nested conditions
1276
- * @returns PostgreSQL AST node for the condition
1277
- */
1278
- compile(decision: Decision, ctx: CompilerContext, state: CompilerState, dispatch: WhereDispatcher): Node;
1279
- }
1280
- /**
1281
- * Dispatcher for recursive WHERE compilation.
1282
- */
1283
- type WhereDispatcher = (decision: Decision, ctx: CompilerContext, state: CompilerState) => Node;
1284
- /**
1285
- * Handler for SELECT expressions.
1286
- * Transforms expression decisions into PostgreSQL AST nodes.
1287
- */
1288
- interface ExpressionHandler {
1289
- /** Expression type(s) this handler supports */
1290
- readonly types: readonly string[];
1291
- /**
1292
- * Safe to use when a function name comes from NQL text.
1293
- *
1294
- * Raw/escape-hatch handlers must not set this. NQL-origin function names use
1295
- * this opt-in surface only, then fall back to generic FuncCall emission.
1296
- */
1297
- readonly nqlSafe?: boolean;
1298
- /**
1299
- * Compile an expression to AST.
1300
- * @param decision The expression decision
1301
- * @param ctx Immutable compiler context
1302
- * @param state Mutable compiler state
1303
- * @returns PostgreSQL AST node for the expression
1304
- */
1305
- compile(decision: Decision, ctx: CompilerContext, state: CompilerState): Node;
1306
- }
1307
- /**
1308
- * Handler for include/relation strategies.
1309
- * Transforms include decisions into PostgreSQL constructs (JOIN, LATERAL, json_agg, CTE).
1310
- */
1311
- interface IncludeHandler {
1312
- /** Strategy this handler implements */
1313
- readonly strategy: 'join' | 'lateral' | 'json_agg' | 'cte';
1314
- /**
1315
- * Compile an include to AST.
1316
- * @param decision The include decision
1317
- * @param ctx Immutable compiler context
1318
- * @param state Mutable compiler state
1319
- * @returns Object with modifications to apply
1320
- */
1321
- compile(decision: Decision, ctx: CompilerContext, state: CompilerState): IncludeResult;
1322
- }
1323
- /**
1324
- * Result of include compilation.
1325
- */
1326
- interface IncludeResult {
1327
- /** Additional target list items (SELECT columns) */
1328
- targets?: Node[];
1329
- /** JOIN to add to FROM clause */
1330
- join?: Node;
1331
- /** Additional JOINs for cascaded includes (e.g., flat deep nesting) */
1332
- additionalJoins?: Node[];
1333
- /** CTE to add to WITH clause */
1334
- cte?: Node;
1335
- /** Subquery for LATERAL */
1336
- lateral?: Node;
1337
- }
1338
-
1339
1347
  /**
1340
1348
  * PostgreSQL Schema Introspection (ADAPTER-006)
1341
1349
  *
@@ -1907,11 +1915,19 @@ declare class PgsqlAdapter<DB = unknown> implements Adapter<DB> {
1907
1915
  * @since DDL-TABLE-001
1908
1916
  */
1909
1917
  get inTransaction(): boolean;
1918
+ /**
1919
+ * Resolve the explicit schema for a catalog read: an explicit argument, else
1920
+ * the adapter's configured schema, else `undefined` (resolve in-query). NOT a
1921
+ * hard-coded 'public' — an unresolved schema is handled by the SQL, which
1922
+ * finds the table's schema search_path-aware, in the SAME session, so a
1923
+ * non-public search_path and a pooled connection both stay correct.
1924
+ */
1925
+ private explicitSchema;
1910
1926
  /**
1911
1927
  * List all indexes on a table by querying pg_indexes.
1912
1928
  *
1913
1929
  * @param table - Table name
1914
- * @param schema - Schema name (defaults to adapter schema or 'public')
1930
+ * @param schema - Schema name (defaults to the search_path-resolved schema)
1915
1931
  */
1916
1932
  listIndexes(table: string, schema?: string, options?: {
1917
1933
  namePattern?: string;
@@ -1921,23 +1937,19 @@ declare class PgsqlAdapter<DB = unknown> implements Adapter<DB> {
1921
1937
  *
1922
1938
  * @param name - Index name
1923
1939
  * @param table - Table name
1924
- * @param schema - Schema name (defaults to adapter schema or 'public')
1940
+ * @param schema - Schema name (defaults to the search_path-resolved schema)
1925
1941
  */
1926
1942
  indexExists(name: string, table: string, schema?: string): Promise<boolean>;
1927
- /**
1928
- * Return the total storage size of a table in bytes.
1929
- *
1930
- * @param table - Table name
1931
- * @param schema - Schema name (defaults to adapter schema or 'public')
1932
- */
1933
1943
  /**
1934
1944
  * Return the total storage size of a table in bytes (includes indexes and TOAST).
1935
1945
  *
1936
1946
  * The table name is a SQL identifier — it is double-quoted, not parameterized,
1937
1947
  * because PostgreSQL does not allow parameterized table names in FROM clauses.
1948
+ * With no known schema the table is left unqualified so ::regclass resolves it
1949
+ * through search_path (the same table an unqualified reference would hit).
1938
1950
  *
1939
1951
  * @param table - Table name
1940
- * @param schema - Schema name (defaults to adapter schema or 'public')
1952
+ * @param schema - Schema name (defaults to the search_path-resolved schema)
1941
1953
  */
1942
1954
  storageSize(table: string, schema?: string): Promise<number>;
1943
1955
  /**
@@ -2319,5 +2331,15 @@ declare function validateIdentifiers(identifiers: Record<string, 'table' | 'colu
2319
2331
  * NOT for use in SQL - use validateIdentifier + AST helpers for that.
2320
2332
  */
2321
2333
  declare function sanitizeForDisplay(value: string): string;
2334
+ /**
2335
+ * Validate a raw SQL expression used in DDL contexts (defaults, policy USING/CHECK).
2336
+ * Rejects injection vectors: semicolons, line-comment markers, block-comment markers.
2337
+ *
2338
+ * @security Called before any ModelIR-sourced string is interpolated into DDL.
2339
+ * @param sql The raw SQL expression string to validate.
2340
+ * @param context Human-readable context label for the error message.
2341
+ * @throws Error if the expression contains forbidden characters.
2342
+ */
2343
+ declare function validateSqlExpression(sql: string, context: string): void;
2322
2344
 
2323
- export { type BatchValuesJoinDecision, CamelCaseNamingPlugin, type ChangeKind, type CompareSchemataOptions, type CompiledResult, type CompilerContext, type CompilerOptions, type CompilerState, type ConflictAction, type ConflictTarget, type CursorHoldOption, type CursorOptions, type CursorScrollOption, DEFAULT_PK_COLUMN, DEFAULT_REDACTION_PATTERNS, type Decision, type DeleteConfig, type DetectedHierarchy, type DiffSummary, type ExplainFormat, type ExplainOptions, type ExplainPlan, type ExpressionHandler, type FetchDirection, type FetchOptions, type FkColumnDerivation, type GenerateDDLOptions, IdentityNamingPlugin, type IncludeHandler, type IncludeResult, type InsertConfig, type IntrospectedModelIR, type IntrospectionOptions, InvalidIdentifierError, type JoinDecision, type LeafCompileFn, type MigrationRecord, type MigrationSQLOptions, type NamingPlugin, type ParamRefValidationResult, type ParsedMigrationFile, PgsqlAdapter, type PgsqlAdapterOptions, PlanCompiler, type PlanDecision, type PrecompiledJoinDecision, type RedactionConfig, type RedactionPattern, type SchemaChange, type SchemaDiff, type SetOperationResult, type SimplifiedPlanReport, type StreamConfig, type UpdateConfig, type UpsertConfig, type WhereDispatcher, type WhereHandler, acquireMigrationLock, bm25Search, booleanSearch, boost, buildCloseCursor, buildDeclareCursor, buildExplain, buildExplainAnalyzeJson, buildExplainPlan, buildExplainVerbose, buildFetch, buildFetchAll, buildFetchFirst, buildFetchForward, buildFetchNext, buildOnConflictClause, buildStreamingStatements, camelCaseNaming, collectAndValidateParamRefs, compareSchemata, compileDelete, compileInsert, compileMutation, compilePlan, compileSetOperation, compileUpdate, compileUpsert, conditionalUpdate, cosineDistance, createAnyExpr, createEqualityExpr, createLeafCompileFn, createParamRef, createPgsqlAdapter, createPgsqlCompileOnlyAdapter, createTypeCastParamRef, defaultFkDerivation, ensureMigrationsTable, excludedRef, generateCursorName, generateDDL, generateDownSQL, generateMigrationFile, generateMigrationSQL, generateSeries, getAppliedMigrations, getNamingPluginForDbCasing, getNextSchemaVersion, getRowEstimates, getTotalExecutionTime, identityNaming, innerProduct, introspect, isBatchValuesJoinDecision, isDestructiveDown, isJoinDecision, isMigrationApplied, isPrecompiledJoinDecision, isReservedKeyword, l2Distance, mapColumnType, mapOnDeleteAction, nextval, parse, parseExplainJson, parseMigrationFile, rawDistance, recordMigration, redactParams, releaseMigrationLock, removeMigrationRecord, resolveLogicalName, sanitizeForDisplay, score, validateIdentifier, validateIdentifiers, validateParamRef, validateQualifiedIdentifier, vectorDims, withMigrationLock };
2345
+ export { type BatchValuesJoinDecision, CamelCaseNamingPlugin, type ChangeKind, type CompareSchemataOptions, type CompiledResult, type CompilerContext, type CompilerOptions, type CompilerState, type ConflictAction, type ConflictTarget, type CursorHoldOption, type CursorOptions, type CursorScrollOption, DEFAULT_PK_COLUMN, DEFAULT_REDACTION_PATTERNS, type Decision, type DeleteConfig, type DetectedHierarchy, type DiffSummary, type ExplainFormat, type ExplainOptions, type ExplainPlan, type ExpressionHandler, type FetchDirection, type FetchOptions, type FkColumnDerivation, type GenerateDDLOptions, IdentityNamingPlugin, type IncludeHandler, type IncludeResult, type InsertConfig, type IntrospectedModelIR, type IntrospectionOptions, InvalidIdentifierError, type JoinDecision, type LeafCompileFn, type MigrationRecord, type MigrationSQLOptions, type NamingPlugin, type ParamRefValidationResult, type ParsedMigrationFile, PgsqlAdapter, type PgsqlAdapterOptions, PlanCompiler, type PlanDecision, type PrecompiledJoinDecision, type RedactionConfig, type RedactionPattern, type SchemaChange, type SchemaDiff, type SetOperationResult, type SimplifiedPlanReport, type StreamConfig, type UpdateConfig, type UpsertConfig, type WhereDispatcher, type WhereHandler, bm25Search, booleanSearch, boost, buildCloseCursor, buildDeclareCursor, buildExplain, buildExplainAnalyzeJson, buildExplainPlan, buildExplainVerbose, buildFetch, buildFetchAll, buildFetchFirst, buildFetchForward, buildFetchNext, buildOnConflictClause, buildStreamingStatements, camelCaseNaming, canGenerateCreateIndex, collectAndValidateParamRefs, compareSchemata, compileDelete, compileInsert, compileMutation, compilePlan, compileSetOperation, compileUpdate, compileUpsert, conditionalUpdate, cosineDistance, createAnyExpr, createEqualityExpr, createLeafCompileFn, createParamRef, createPgsqlAdapter, createPgsqlCompileOnlyAdapter, createTypeCastParamRef, defaultFkDerivation, ensureMigrationsTable, excludedRef, generateCreateIndex, generateCursorName, generateDDL, generateDownSQL, generateMigrationFile, generateMigrationSQL, generateSeries, getAppliedMigrations, getNamingPluginForDbCasing, getNextSchemaVersion, getRowEstimates, getTotalExecutionTime, identityNaming, innerProduct, introspect, isBatchValuesJoinDecision, isDestructiveDown, isJoinDecision, isMigrationApplied, isPrecompiledJoinDecision, isReservedKeyword, l2Distance, mapColumnType, mapOnDeleteAction, nextval, parse, parseExplainJson, parseMigrationFile, rawDistance, recordMigration, redactParams, removeMigrationRecord, resolveLogicalName, sanitizeForDisplay, score, validateIdentifier, validateIdentifiers, validateParamRef, validateQualifiedIdentifier, validateSqlExpression, vectorDims, withMigrationLock };