metal-orm 1.1.23 → 1.1.25
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.cjs +832 -583
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +281 -144
- package/dist/index.d.ts +281 -144
- package/dist/index.js +807 -583
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/dialect/base/returning-strategy.ts +40 -39
- package/src/core/dialect/base/sql-compiler-set.ts +33 -0
- package/src/core/dialect/base/sql-dialect.ts +125 -222
- package/src/core/dialect/base/standard-delete-compiler.ts +37 -0
- package/src/core/dialect/base/standard-insert-compiler.ts +49 -0
- package/src/core/dialect/base/standard-select-compiler.ts +82 -0
- package/src/core/dialect/base/standard-sql-services.ts +44 -0
- package/src/core/dialect/base/standard-sql-source-compiler.ts +88 -0
- package/src/core/dialect/base/standard-update-compiler.ts +53 -0
- package/src/core/dialect/base/upsert-strategy.ts +45 -0
- package/src/core/dialect/capabilities/procedure-compiler.ts +10 -8
- package/src/core/dialect/mssql/compiler-factory.ts +12 -0
- package/src/core/dialect/mssql/delete-compiler.ts +40 -0
- package/src/core/dialect/mssql/index.ts +24 -371
- package/src/core/dialect/mssql/insert-compiler.ts +112 -0
- package/src/core/dialect/mssql/output.ts +46 -0
- package/src/core/dialect/mssql/procedure-compiler.ts +81 -0
- package/src/core/dialect/mssql/select-compiler.ts +116 -0
- package/src/core/dialect/mssql/update-compiler.ts +37 -0
- package/src/core/dialect/mysql/index.ts +24 -117
- package/src/core/dialect/mysql/procedure-compiler.ts +67 -0
- package/src/core/dialect/mysql/upsert.ts +42 -0
- package/src/core/dialect/postgres/index.ts +34 -101
- package/src/core/dialect/postgres/procedure-compiler.ts +41 -0
- package/src/core/dialect/postgres/returning.ts +4 -0
- package/src/core/dialect/postgres/upsert.ts +43 -0
- package/src/core/dialect/sqlite/index.ts +15 -70
- package/src/core/dialect/sqlite/returning.ts +30 -0
- package/src/core/dialect/sqlite/upsert.ts +43 -0
- package/src/index.ts +28 -10
package/dist/index.cjs
CHANGED
|
@@ -92,13 +92,26 @@ __export(index_exports, {
|
|
|
92
92
|
MorphMany: () => MorphMany,
|
|
93
93
|
MorphOne: () => MorphOne,
|
|
94
94
|
MorphTo: () => MorphTo,
|
|
95
|
+
MssqlDeleteCompiler: () => MssqlDeleteCompiler,
|
|
96
|
+
MssqlInsertCompiler: () => MssqlInsertCompiler,
|
|
97
|
+
MssqlOutputStrategy: () => MssqlOutputStrategy,
|
|
98
|
+
MssqlProcedureCompiler: () => MssqlProcedureCompiler,
|
|
99
|
+
MssqlSelectCompiler: () => MssqlSelectCompiler,
|
|
100
|
+
MssqlUpdateCompiler: () => MssqlUpdateCompiler,
|
|
95
101
|
MySqlDialect: () => MySqlDialect,
|
|
102
|
+
MySqlProcedureCompiler: () => MySqlProcedureCompiler,
|
|
103
|
+
MySqlUpsertStrategy: () => MySqlUpsertStrategy,
|
|
96
104
|
NestedSetStrategy: () => NestedSetStrategy,
|
|
105
|
+
NoReturningStrategy: () => NoReturningStrategy,
|
|
106
|
+
NoUpsertStrategy: () => NoUpsertStrategy,
|
|
97
107
|
Orm: () => Orm,
|
|
98
108
|
OrmSession: () => OrmSession,
|
|
99
109
|
Pattern: () => Pattern,
|
|
100
110
|
Pool: () => Pool,
|
|
101
111
|
PostgresDialect: () => PostgresDialect,
|
|
112
|
+
PostgresProcedureCompiler: () => PostgresProcedureCompiler,
|
|
113
|
+
PostgresReturningStrategy: () => PostgresReturningStrategy,
|
|
114
|
+
PostgresUpsertStrategy: () => PostgresUpsertStrategy,
|
|
102
115
|
PrimaryKey: () => PrimaryKey,
|
|
103
116
|
ProcedureCallBuilder: () => ProcedureCallBuilder,
|
|
104
117
|
PrototypeMaterializationStrategy: () => PrototypeMaterializationStrategy,
|
|
@@ -107,8 +120,19 @@ __export(index_exports, {
|
|
|
107
120
|
RelationKinds: () => RelationKinds,
|
|
108
121
|
STANDARD_COLUMN_TYPES: () => STANDARD_COLUMN_TYPES,
|
|
109
122
|
SelectQueryBuilder: () => SelectQueryBuilder,
|
|
123
|
+
SqlDialectBase: () => SqlDialectBase,
|
|
110
124
|
SqlServerDialect: () => SqlServerDialect,
|
|
111
125
|
SqliteDialect: () => SqliteDialect,
|
|
126
|
+
SqliteReturningStrategy: () => SqliteReturningStrategy,
|
|
127
|
+
SqliteUpsertStrategy: () => SqliteUpsertStrategy,
|
|
128
|
+
StandardDeleteCompiler: () => StandardDeleteCompiler,
|
|
129
|
+
StandardInsertCompiler: () => StandardInsertCompiler,
|
|
130
|
+
StandardLimitOffsetPagination: () => StandardLimitOffsetPagination,
|
|
131
|
+
StandardReturningStrategy: () => StandardReturningStrategy,
|
|
132
|
+
StandardSelectCompiler: () => StandardSelectCompiler,
|
|
133
|
+
StandardSqlSourceCompiler: () => StandardSqlSourceCompiler,
|
|
134
|
+
StandardTableFunctionStrategy: () => StandardTableFunctionStrategy,
|
|
135
|
+
StandardUpdateCompiler: () => StandardUpdateCompiler,
|
|
112
136
|
StringTypeStrategy: () => StringTypeStrategy,
|
|
113
137
|
TagIndex: () => TagIndex,
|
|
114
138
|
Title: () => Title,
|
|
@@ -195,6 +219,7 @@ __export(index_exports, {
|
|
|
195
219
|
createEntityFromRow: () => createEntityFromRow,
|
|
196
220
|
createEntityProxy: () => createEntityProxy,
|
|
197
221
|
createExecutorFromQueryRunner: () => createExecutorFromQueryRunner,
|
|
222
|
+
createMssqlCompilerSet: () => createMssqlCompilerSet,
|
|
198
223
|
createMssqlExecutor: () => createMssqlExecutor,
|
|
199
224
|
createMysqlExecutor: () => createMysqlExecutor,
|
|
200
225
|
createPooledExecutorFactory: () => createPooledExecutorFactory,
|
|
@@ -2132,6 +2157,57 @@ var DialectBase = class _DialectBase {
|
|
|
2132
2157
|
}
|
|
2133
2158
|
};
|
|
2134
2159
|
|
|
2160
|
+
// src/core/dialect/base/pagination-strategy.ts
|
|
2161
|
+
var StandardLimitOffsetPagination = class {
|
|
2162
|
+
/**
|
|
2163
|
+
* Compiles LIMIT/OFFSET pagination clause.
|
|
2164
|
+
* @param limit - The maximum number of rows to return.
|
|
2165
|
+
* @param offset - The number of rows to skip.
|
|
2166
|
+
* @returns SQL pagination clause with LIMIT and/or OFFSET.
|
|
2167
|
+
*/
|
|
2168
|
+
compilePagination(limit, offset) {
|
|
2169
|
+
const parts = [];
|
|
2170
|
+
if (limit !== void 0) parts.push(`LIMIT ${limit}`);
|
|
2171
|
+
if (offset !== void 0) parts.push(`OFFSET ${offset}`);
|
|
2172
|
+
return parts.length ? ` ${parts.join(" ")}` : "";
|
|
2173
|
+
}
|
|
2174
|
+
};
|
|
2175
|
+
|
|
2176
|
+
// src/core/dialect/base/returning-strategy.ts
|
|
2177
|
+
var NoReturningStrategy = class {
|
|
2178
|
+
compileReturning(returning, _ctx, _quoteIdentifier) {
|
|
2179
|
+
void _ctx;
|
|
2180
|
+
void _quoteIdentifier;
|
|
2181
|
+
if (!returning || returning.length === 0) return "";
|
|
2182
|
+
throw new Error("RETURNING is not supported by this dialect.");
|
|
2183
|
+
}
|
|
2184
|
+
formatReturningColumns(returning, quoteIdentifier) {
|
|
2185
|
+
return returning.map((column) => {
|
|
2186
|
+
const tablePart = column.table ? `${quoteIdentifier(column.table)}.` : "";
|
|
2187
|
+
const aliasPart = column.alias ? ` AS ${quoteIdentifier(column.alias)}` : "";
|
|
2188
|
+
return `${tablePart}${quoteIdentifier(column.name)}${aliasPart}`;
|
|
2189
|
+
}).join(", ");
|
|
2190
|
+
}
|
|
2191
|
+
};
|
|
2192
|
+
var StandardReturningStrategy = class extends NoReturningStrategy {
|
|
2193
|
+
compileReturning(returning, _ctx, quoteIdentifier) {
|
|
2194
|
+
void _ctx;
|
|
2195
|
+
if (!returning || returning.length === 0) return "";
|
|
2196
|
+
return ` RETURNING ${this.formatReturningColumns(returning, quoteIdentifier)}`;
|
|
2197
|
+
}
|
|
2198
|
+
};
|
|
2199
|
+
|
|
2200
|
+
// src/core/dialect/base/upsert-strategy.ts
|
|
2201
|
+
var NoUpsertStrategy = class {
|
|
2202
|
+
compile(ast, _ctx, services) {
|
|
2203
|
+
void _ctx;
|
|
2204
|
+
if (!ast.onConflict) return "";
|
|
2205
|
+
throw new Error(
|
|
2206
|
+
`UPSERT/ON CONFLICT is not supported by dialect "${services.getDialectName()}".`
|
|
2207
|
+
);
|
|
2208
|
+
}
|
|
2209
|
+
};
|
|
2210
|
+
|
|
2135
2211
|
// src/core/dialect/base/function-table-formatter.ts
|
|
2136
2212
|
var FunctionTableFormatter = class {
|
|
2137
2213
|
static format(fn9, ctx, formatter) {
|
|
@@ -2168,19 +2244,71 @@ var FunctionTableFormatter = class {
|
|
|
2168
2244
|
}
|
|
2169
2245
|
};
|
|
2170
2246
|
|
|
2171
|
-
// src/core/dialect/base/
|
|
2172
|
-
var
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2247
|
+
// src/core/dialect/base/standard-sql-source-compiler.ts
|
|
2248
|
+
var StandardSqlSourceCompiler = class {
|
|
2249
|
+
constructor(services) {
|
|
2250
|
+
this.services = services;
|
|
2251
|
+
}
|
|
2252
|
+
compileFrom(source, ctx) {
|
|
2253
|
+
if (source.type === "FunctionTable") return this.compileFunctionTable(source, ctx);
|
|
2254
|
+
if (source.type === "DerivedTable") return this.compileDerivedTable(source, ctx);
|
|
2255
|
+
return this.compileTableSource(source);
|
|
2256
|
+
}
|
|
2257
|
+
compileFunctionTable(fn9, ctx) {
|
|
2258
|
+
const key = fn9.key ?? fn9.name;
|
|
2259
|
+
if (ctx) {
|
|
2260
|
+
const renderer = this.services.getTableFunctionStrategy().getRenderer(key);
|
|
2261
|
+
if (renderer) {
|
|
2262
|
+
const compiledArgs = (fn9.args ?? []).map((arg) => this.services.compileOperand(arg, ctx));
|
|
2263
|
+
return renderer({
|
|
2264
|
+
node: fn9,
|
|
2265
|
+
compiledArgs,
|
|
2266
|
+
compileOperand: (operand) => this.services.compileOperand(operand, ctx),
|
|
2267
|
+
quoteIdentifier: (id) => this.services.quoteIdentifier(id)
|
|
2268
|
+
});
|
|
2269
|
+
}
|
|
2270
|
+
if (fn9.key) {
|
|
2271
|
+
throw new Error(
|
|
2272
|
+
`Table function "${key}" is not supported by dialect "${this.services.getDialectName()}".`
|
|
2273
|
+
);
|
|
2274
|
+
}
|
|
2275
|
+
}
|
|
2276
|
+
return FunctionTableFormatter.format(fn9, ctx, {
|
|
2277
|
+
quoteIdentifier: (id) => this.services.quoteIdentifier(id),
|
|
2278
|
+
compileOperand: (node, compilerContext) => this.services.compileOperand(node, compilerContext)
|
|
2279
|
+
});
|
|
2280
|
+
}
|
|
2281
|
+
compileDerivedTable(table, ctx) {
|
|
2282
|
+
if (!table.alias) throw new Error("Derived tables must have an alias.");
|
|
2283
|
+
if (!ctx) throw new Error("Derived table compilation requires a compiler context.");
|
|
2284
|
+
const normalized = this.services.normalizeSelectAst(table.query);
|
|
2285
|
+
const subquery = this.services.compileSelectAst(normalized, ctx).trim().replace(/;$/, "");
|
|
2286
|
+
const columns = table.columnAliases?.length ? ` (${table.columnAliases.map((column) => this.services.quoteIdentifier(column)).join(", ")})` : "";
|
|
2287
|
+
return `(${subquery}) AS ${this.services.quoteIdentifier(table.alias)}${columns}`;
|
|
2288
|
+
}
|
|
2289
|
+
compileTableSource(table) {
|
|
2290
|
+
if (table.type === "FunctionTable") return this.compileFunctionTable(table);
|
|
2291
|
+
if (table.type === "DerivedTable") {
|
|
2292
|
+
throw new Error("Derived table compilation requires a compiler context.");
|
|
2293
|
+
}
|
|
2294
|
+
const base = this.compileTableName(table);
|
|
2295
|
+
return table.alias ? `${base} AS ${this.services.quoteIdentifier(table.alias)}` : base;
|
|
2296
|
+
}
|
|
2297
|
+
compileTableName(table) {
|
|
2298
|
+
if (table.schema) {
|
|
2299
|
+
return `${this.services.quoteIdentifier(table.schema)}.${this.services.quoteIdentifier(table.name)}`;
|
|
2300
|
+
}
|
|
2301
|
+
return this.services.quoteIdentifier(table.name);
|
|
2302
|
+
}
|
|
2303
|
+
compileTableReference(table) {
|
|
2304
|
+
const base = this.compileTableName(table);
|
|
2305
|
+
return table.alias ? `${base} AS ${this.services.quoteIdentifier(table.alias)}` : base;
|
|
2306
|
+
}
|
|
2307
|
+
stripTrailingSemicolon(sql) {
|
|
2308
|
+
return sql.trim().replace(/;$/, "");
|
|
2309
|
+
}
|
|
2310
|
+
wrapSetOperand(sql) {
|
|
2311
|
+
return `(${this.stripTrailingSemicolon(sql)})`;
|
|
2184
2312
|
}
|
|
2185
2313
|
};
|
|
2186
2314
|
|
|
@@ -2210,34 +2338,6 @@ var CteCompiler = class {
|
|
|
2210
2338
|
}
|
|
2211
2339
|
};
|
|
2212
2340
|
|
|
2213
|
-
// src/core/dialect/base/returning-strategy.ts
|
|
2214
|
-
var NoReturningStrategy = class {
|
|
2215
|
-
/**
|
|
2216
|
-
* Throws an error as RETURNING is not supported.
|
|
2217
|
-
* @param returning - Columns to return (causes error if non-empty).
|
|
2218
|
-
* @param _ctx - Compiler context (unused).
|
|
2219
|
-
* @throws Error indicating RETURNING is not supported.
|
|
2220
|
-
*/
|
|
2221
|
-
compileReturning(returning, _ctx) {
|
|
2222
|
-
void _ctx;
|
|
2223
|
-
if (!returning || returning.length === 0) return "";
|
|
2224
|
-
throw new Error("RETURNING is not supported by this dialect.");
|
|
2225
|
-
}
|
|
2226
|
-
/**
|
|
2227
|
-
* Formats column names for RETURNING clause.
|
|
2228
|
-
* @param returning - Columns to format.
|
|
2229
|
-
* @param quoteIdentifier - Function to quote identifiers according to dialect rules.
|
|
2230
|
-
* @returns Simple comma-separated column names.
|
|
2231
|
-
*/
|
|
2232
|
-
formatReturningColumns(returning, quoteIdentifier) {
|
|
2233
|
-
return returning.map((column) => {
|
|
2234
|
-
const tablePart = column.table ? `${quoteIdentifier(column.table)}.` : "";
|
|
2235
|
-
const aliasPart = column.alias ? ` AS ${quoteIdentifier(column.alias)}` : "";
|
|
2236
|
-
return `${tablePart}${quoteIdentifier(column.name)}${aliasPart}`;
|
|
2237
|
-
}).join(", ");
|
|
2238
|
-
}
|
|
2239
|
-
};
|
|
2240
|
-
|
|
2241
2341
|
// src/core/dialect/base/join-compiler.ts
|
|
2242
2342
|
var JoinCompiler = class {
|
|
2243
2343
|
static compileJoins(joins, ctx, compileFrom, compileExpression) {
|
|
@@ -2288,108 +2388,254 @@ var OrderByCompiler = class {
|
|
|
2288
2388
|
}
|
|
2289
2389
|
};
|
|
2290
2390
|
|
|
2291
|
-
// src/core/dialect/base/
|
|
2292
|
-
var
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2391
|
+
// src/core/dialect/base/standard-select-compiler.ts
|
|
2392
|
+
var StandardSelectCompiler = class {
|
|
2393
|
+
constructor(services, sources) {
|
|
2394
|
+
this.services = services;
|
|
2395
|
+
this.sources = sources;
|
|
2396
|
+
}
|
|
2397
|
+
compile(ast, ctx) {
|
|
2296
2398
|
const hasSetOps = !!(ast.setOps && ast.setOps.length);
|
|
2297
2399
|
const ctes = CteCompiler.compileCtes(
|
|
2298
2400
|
ast,
|
|
2299
2401
|
ctx,
|
|
2300
|
-
this.quoteIdentifier
|
|
2301
|
-
this.compileSelectAst
|
|
2302
|
-
this.normalizeSelectAst
|
|
2303
|
-
this.stripTrailingSemicolon
|
|
2402
|
+
(id) => this.services.quoteIdentifier(id),
|
|
2403
|
+
(query, compilerContext) => this.services.compileSelectAst(query, compilerContext),
|
|
2404
|
+
(query) => this.services.normalizeSelectAst(query),
|
|
2405
|
+
(sql) => this.sources.stripTrailingSemicolon(sql)
|
|
2304
2406
|
);
|
|
2305
2407
|
const baseAst = hasSetOps ? { ...ast, setOps: void 0, orderBy: void 0, limit: void 0, offset: void 0 } : ast;
|
|
2306
|
-
const baseSelect = this.
|
|
2408
|
+
const baseSelect = this.compileCore(baseAst, ctx);
|
|
2307
2409
|
if (!hasSetOps) return `${ctes}${baseSelect}`;
|
|
2308
|
-
|
|
2410
|
+
const compound = ast.setOps.map((op) => `${op.operator} ${this.sources.wrapSetOperand(this.services.compileSelectAst(op.query, ctx))}`).join(" ");
|
|
2411
|
+
const orderBy = this.compileOrderBy(ast, ctx);
|
|
2412
|
+
const pagination = this.services.getPaginationStrategy().compilePagination(ast.limit, ast.offset);
|
|
2413
|
+
const combined = `${this.sources.wrapSetOperand(baseSelect)} ${compound}`;
|
|
2414
|
+
return `${ctes}${combined}${orderBy}${pagination}`;
|
|
2415
|
+
}
|
|
2416
|
+
compileCore(ast, ctx) {
|
|
2417
|
+
const columns = this.compileColumns(ast, ctx);
|
|
2418
|
+
const from = this.sources.compileFrom(ast.from, ctx);
|
|
2419
|
+
const joins = JoinCompiler.compileJoins(
|
|
2420
|
+
ast.joins,
|
|
2421
|
+
ctx,
|
|
2422
|
+
(source, compilerContext) => this.sources.compileFrom(source, compilerContext),
|
|
2423
|
+
(expression, compilerContext) => this.services.compileExpression(expression, compilerContext)
|
|
2424
|
+
);
|
|
2425
|
+
const where = ast.where ? ` WHERE ${this.services.compileExpression(ast.where, ctx)}` : "";
|
|
2426
|
+
const groupBy = GroupByCompiler.compileGroupBy(
|
|
2427
|
+
ast,
|
|
2428
|
+
(term) => this.services.compileOrderingTerm(term, ctx)
|
|
2429
|
+
);
|
|
2430
|
+
const having = ast.having ? ` HAVING ${this.services.compileExpression(ast.having, ctx)}` : "";
|
|
2431
|
+
const orderBy = this.compileOrderBy(ast, ctx);
|
|
2432
|
+
const pagination = this.services.getPaginationStrategy().compilePagination(ast.limit, ast.offset);
|
|
2433
|
+
return `SELECT ${ast.distinct ? "DISTINCT " : ""}${columns} FROM ${from}${joins}${where}${groupBy}${having}${orderBy}${pagination}`;
|
|
2309
2434
|
}
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2435
|
+
compileColumns(ast, ctx) {
|
|
2436
|
+
if (!ast.columns || ast.columns.length === 0) return "*";
|
|
2437
|
+
return ast.columns.map((column) => {
|
|
2438
|
+
const expr = this.services.compileOperand(column, ctx);
|
|
2439
|
+
if (!column.alias) return expr;
|
|
2440
|
+
if (column.alias.includes("(")) return column.alias;
|
|
2441
|
+
return `${expr} AS ${this.services.quoteIdentifier(column.alias)}`;
|
|
2442
|
+
}).join(", ");
|
|
2443
|
+
}
|
|
2444
|
+
compileOrderBy(ast, ctx) {
|
|
2445
|
+
return OrderByCompiler.compileOrderBy(
|
|
2313
2446
|
ast,
|
|
2314
|
-
(term) => this.compileOrderingTerm(term, ctx),
|
|
2315
|
-
this.renderOrderByNulls
|
|
2316
|
-
this.renderOrderByCollation
|
|
2447
|
+
(term) => this.services.compileOrderingTerm(term, ctx),
|
|
2448
|
+
(order) => this.services.renderOrderByNulls(order),
|
|
2449
|
+
(order) => this.services.renderOrderByCollation(order)
|
|
2317
2450
|
);
|
|
2318
|
-
const pagination = this.paginationStrategy.compilePagination(ast.limit, ast.offset);
|
|
2319
|
-
const combined = `${this.wrapSetOperand(baseSelect)} ${compound}`;
|
|
2320
|
-
return `${ctes}${combined}${orderBy}${pagination}`;
|
|
2321
2451
|
}
|
|
2322
|
-
|
|
2452
|
+
};
|
|
2453
|
+
|
|
2454
|
+
// src/core/dialect/base/standard-insert-compiler.ts
|
|
2455
|
+
var StandardInsertCompiler = class {
|
|
2456
|
+
constructor(services, sources) {
|
|
2457
|
+
this.services = services;
|
|
2458
|
+
this.sources = sources;
|
|
2459
|
+
}
|
|
2460
|
+
compile(ast, ctx) {
|
|
2323
2461
|
if (!ast.columns.length) {
|
|
2324
2462
|
throw new Error("INSERT queries must specify columns.");
|
|
2325
2463
|
}
|
|
2326
|
-
const table = this.compileTableName(ast.into);
|
|
2327
|
-
const columnList = this.
|
|
2328
|
-
const source = this.
|
|
2329
|
-
const upsert = this.compileUpsertClause(ast, ctx);
|
|
2330
|
-
const returning = this.compileReturning(ast.returning, ctx);
|
|
2464
|
+
const table = this.sources.compileTableName(ast.into);
|
|
2465
|
+
const columnList = this.compileColumnList(ast.columns);
|
|
2466
|
+
const source = this.compileSource(ast.source, ctx);
|
|
2467
|
+
const upsert = this.services.compileUpsertClause(ast, ctx);
|
|
2468
|
+
const returning = this.services.compileReturning(ast.returning, ctx);
|
|
2331
2469
|
return `INSERT INTO ${table} (${columnList}) ${source}${upsert}${returning}`;
|
|
2332
2470
|
}
|
|
2333
|
-
|
|
2334
|
-
void _ctx;
|
|
2335
|
-
if (!ast.onConflict) return "";
|
|
2336
|
-
throw new Error(`UPSERT/ON CONFLICT is not supported by dialect "${this.dialect}".`);
|
|
2337
|
-
}
|
|
2338
|
-
compileReturning(returning, ctx) {
|
|
2339
|
-
return this.returningStrategy.compileReturning(returning, ctx);
|
|
2340
|
-
}
|
|
2341
|
-
compileInsertSource(source, ctx) {
|
|
2471
|
+
compileSource(source, ctx) {
|
|
2342
2472
|
if (source.type === "InsertValues") {
|
|
2343
2473
|
if (!source.rows.length) {
|
|
2344
2474
|
throw new Error("INSERT ... VALUES requires at least one row.");
|
|
2345
2475
|
}
|
|
2346
|
-
const values = source.rows.map((row) => `(${row.map((value) => this.compileOperand(value, ctx)).join(", ")})`).join(", ");
|
|
2476
|
+
const values = source.rows.map((row) => `(${row.map((value) => this.services.compileOperand(value, ctx)).join(", ")})`).join(", ");
|
|
2347
2477
|
return `VALUES ${values}`;
|
|
2348
2478
|
}
|
|
2349
|
-
const normalized = this.normalizeSelectAst(source.query);
|
|
2350
|
-
return this.compileSelectAst(normalized, ctx).trim();
|
|
2479
|
+
const normalized = this.services.normalizeSelectAst(source.query);
|
|
2480
|
+
return this.services.compileSelectAst(normalized, ctx).trim();
|
|
2351
2481
|
}
|
|
2352
|
-
|
|
2353
|
-
return columns.map((column) => this.quoteIdentifier(column.name)).join(", ");
|
|
2482
|
+
compileColumnList(columns) {
|
|
2483
|
+
return columns.map((column) => this.services.quoteIdentifier(column.name)).join(", ");
|
|
2354
2484
|
}
|
|
2355
2485
|
ensureConflictColumns(clause, message) {
|
|
2356
2486
|
if (!clause.target.columns.length) throw new Error(message);
|
|
2357
2487
|
}
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2488
|
+
};
|
|
2489
|
+
|
|
2490
|
+
// src/core/dialect/base/standard-update-compiler.ts
|
|
2491
|
+
var StandardUpdateCompiler = class {
|
|
2492
|
+
constructor(services, sources) {
|
|
2493
|
+
this.services = services;
|
|
2494
|
+
this.sources = sources;
|
|
2495
|
+
}
|
|
2496
|
+
compile(ast, ctx) {
|
|
2497
|
+
const target = this.sources.compileTableReference(ast.table);
|
|
2498
|
+
const assignments = this.compileAssignments(ast.set, ast.table, ctx);
|
|
2499
|
+
const from = this.compileFromClause(ast, ctx);
|
|
2500
|
+
const where = ast.where ? ` WHERE ${this.services.compileExpression(ast.where, ctx)}` : "";
|
|
2501
|
+
const returning = this.services.compileReturning(ast.returning, ctx);
|
|
2502
|
+
return `UPDATE ${target} SET ${assignments}${from}${where}${returning}`;
|
|
2503
|
+
}
|
|
2504
|
+
compileAssignments(assignments, table, ctx) {
|
|
2505
|
+
return assignments.map((assignment) => {
|
|
2506
|
+
const target = this.services.compileSetTarget(assignment.column, table);
|
|
2507
|
+
const value = this.services.compileOperand(assignment.value, ctx);
|
|
2508
|
+
return `${target} = ${value}`;
|
|
2509
|
+
}).join(", ");
|
|
2510
|
+
}
|
|
2511
|
+
compileFromClause(ast, ctx) {
|
|
2512
|
+
if (!ast.from && (!ast.joins || ast.joins.length === 0)) return "";
|
|
2513
|
+
if (!ast.from) {
|
|
2514
|
+
throw new Error("UPDATE with JOINs requires an explicit FROM clause.");
|
|
2515
|
+
}
|
|
2516
|
+
const from = this.sources.compileFrom(ast.from, ctx);
|
|
2361
2517
|
const joins = JoinCompiler.compileJoins(
|
|
2362
2518
|
ast.joins,
|
|
2363
2519
|
ctx,
|
|
2364
|
-
this.compileFrom
|
|
2365
|
-
this.compileExpression
|
|
2520
|
+
(source, compilerContext) => this.sources.compileFrom(source, compilerContext),
|
|
2521
|
+
(expression, compilerContext) => this.services.compileExpression(expression, compilerContext)
|
|
2366
2522
|
);
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2523
|
+
return ` FROM ${from}${joins}`;
|
|
2524
|
+
}
|
|
2525
|
+
};
|
|
2526
|
+
|
|
2527
|
+
// src/core/dialect/base/standard-delete-compiler.ts
|
|
2528
|
+
var StandardDeleteCompiler = class {
|
|
2529
|
+
constructor(services, sources) {
|
|
2530
|
+
this.services = services;
|
|
2531
|
+
this.sources = sources;
|
|
2532
|
+
}
|
|
2533
|
+
compile(ast, ctx) {
|
|
2534
|
+
const target = this.sources.compileTableReference(ast.from);
|
|
2535
|
+
const using = this.compileUsingClause(ast, ctx);
|
|
2536
|
+
const where = ast.where ? ` WHERE ${this.services.compileExpression(ast.where, ctx)}` : "";
|
|
2537
|
+
const returning = this.services.compileReturning(ast.returning, ctx);
|
|
2538
|
+
return `DELETE FROM ${target}${using}${where}${returning}`;
|
|
2539
|
+
}
|
|
2540
|
+
compileUsingClause(ast, ctx) {
|
|
2541
|
+
if (!ast.using && (!ast.joins || ast.joins.length === 0)) return "";
|
|
2542
|
+
if (!ast.using) {
|
|
2543
|
+
throw new Error("DELETE with JOINs requires a USING clause.");
|
|
2544
|
+
}
|
|
2545
|
+
const usingTable = this.sources.compileFrom(ast.using, ctx);
|
|
2546
|
+
const joins = JoinCompiler.compileJoins(
|
|
2547
|
+
ast.joins,
|
|
2548
|
+
ctx,
|
|
2549
|
+
(source, compilerContext) => this.sources.compileFrom(source, compilerContext),
|
|
2550
|
+
(expression, compilerContext) => this.services.compileExpression(expression, compilerContext)
|
|
2375
2551
|
);
|
|
2376
|
-
|
|
2377
|
-
|
|
2552
|
+
return ` USING ${usingTable}${joins}`;
|
|
2553
|
+
}
|
|
2554
|
+
};
|
|
2555
|
+
|
|
2556
|
+
// src/core/dialect/base/sql-dialect.ts
|
|
2557
|
+
var SqlDialectBase = class extends DialectBase {
|
|
2558
|
+
paginationStrategy;
|
|
2559
|
+
returningStrategy;
|
|
2560
|
+
upsertStrategy;
|
|
2561
|
+
dmlReturningSupported;
|
|
2562
|
+
sourceCompiler;
|
|
2563
|
+
standardUpdateCompiler;
|
|
2564
|
+
compilerSet;
|
|
2565
|
+
constructor(options = {}) {
|
|
2566
|
+
super(options.functionStrategy, options.tableFunctionStrategy);
|
|
2567
|
+
this.paginationStrategy = options.paginationStrategy ?? new StandardLimitOffsetPagination();
|
|
2568
|
+
this.returningStrategy = options.returningStrategy ?? new NoReturningStrategy();
|
|
2569
|
+
this.upsertStrategy = options.upsertStrategy ?? new NoUpsertStrategy();
|
|
2570
|
+
this.dmlReturningSupported = options.supportsDmlReturning ?? false;
|
|
2571
|
+
const services = {
|
|
2572
|
+
getDialectName: () => this.dialect,
|
|
2573
|
+
getPaginationStrategy: () => this.paginationStrategy,
|
|
2574
|
+
getTableFunctionStrategy: () => this.tableFunctionStrategy,
|
|
2575
|
+
quoteIdentifier: (id) => this.quoteIdentifier(id),
|
|
2576
|
+
compileOperand: (node, ctx) => this.compileOperand(node, ctx),
|
|
2577
|
+
compileExpression: (node, ctx) => this.compileExpression(node, ctx),
|
|
2578
|
+
compileOrderingTerm: (term, ctx) => this.compileOrderingTerm(term, ctx),
|
|
2579
|
+
normalizeSelectAst: (ast) => this.normalizeSelectAst(ast),
|
|
2580
|
+
compileSelectAst: (ast, ctx) => this.compileSelectAst(ast, ctx),
|
|
2581
|
+
compileReturning: (returning, ctx) => this.compileReturning(returning, ctx),
|
|
2582
|
+
compileUpsertClause: (ast, ctx) => this.compileUpsertClause(ast, ctx),
|
|
2583
|
+
compileSetTarget: (column, table) => this.compileSetTarget(column, table),
|
|
2584
|
+
renderOrderByNulls: (order) => this.renderOrderByNulls(order),
|
|
2585
|
+
renderOrderByCollation: (order) => this.renderOrderByCollation(order)
|
|
2586
|
+
};
|
|
2587
|
+
this.sourceCompiler = new StandardSqlSourceCompiler(services);
|
|
2588
|
+
const standardSelect = new StandardSelectCompiler(services, this.sourceCompiler);
|
|
2589
|
+
const standardInsert = new StandardInsertCompiler(services, this.sourceCompiler);
|
|
2590
|
+
this.standardUpdateCompiler = new StandardUpdateCompiler(services, this.sourceCompiler);
|
|
2591
|
+
const standardDelete = new StandardDeleteCompiler(services, this.sourceCompiler);
|
|
2592
|
+
const overrides = options.compilerFactory?.({
|
|
2593
|
+
services,
|
|
2594
|
+
sources: this.sourceCompiler
|
|
2595
|
+
}) ?? {};
|
|
2596
|
+
this.compilerSet = {
|
|
2597
|
+
select: overrides.select ?? standardSelect,
|
|
2598
|
+
insert: overrides.insert ?? standardInsert,
|
|
2599
|
+
update: overrides.update ?? this.standardUpdateCompiler,
|
|
2600
|
+
delete: overrides.delete ?? standardDelete
|
|
2601
|
+
};
|
|
2602
|
+
}
|
|
2603
|
+
supportsDmlReturningClause() {
|
|
2604
|
+
return this.dmlReturningSupported;
|
|
2605
|
+
}
|
|
2606
|
+
compileSelectAst(ast, ctx) {
|
|
2607
|
+
return this.compilerSet.select.compile(ast, ctx);
|
|
2608
|
+
}
|
|
2609
|
+
compileInsertAst(ast, ctx) {
|
|
2610
|
+
return this.compilerSet.insert.compile(ast, ctx);
|
|
2378
2611
|
}
|
|
2379
2612
|
compileUpdateAst(ast, ctx) {
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2613
|
+
return this.compilerSet.update.compile(ast, ctx);
|
|
2614
|
+
}
|
|
2615
|
+
compileDeleteAst(ast, ctx) {
|
|
2616
|
+
return this.compilerSet.delete.compile(ast, ctx);
|
|
2617
|
+
}
|
|
2618
|
+
compileUpsertClause(ast, ctx) {
|
|
2619
|
+
return this.upsertStrategy.compile(ast, ctx, {
|
|
2620
|
+
getDialectName: () => this.dialect,
|
|
2621
|
+
quoteIdentifier: (id) => this.quoteIdentifier(id),
|
|
2622
|
+
compileOperand: (node, compilerContext) => this.compileOperand(node, compilerContext),
|
|
2623
|
+
compileExpression: (node, compilerContext) => this.compileExpression(node, compilerContext),
|
|
2624
|
+
compileUpdateAssignments: (assignments, table, compilerContext) => this.standardUpdateCompiler.compileAssignments(assignments, table, compilerContext)
|
|
2625
|
+
});
|
|
2626
|
+
}
|
|
2627
|
+
compileReturning(returning, ctx) {
|
|
2628
|
+
return this.returningStrategy.compileReturning(
|
|
2629
|
+
returning,
|
|
2630
|
+
ctx,
|
|
2631
|
+
(id) => this.quoteIdentifier(id)
|
|
2632
|
+
);
|
|
2633
|
+
}
|
|
2634
|
+
ensureConflictColumns(clause, message) {
|
|
2635
|
+
if (!clause.target.columns.length) throw new Error(message);
|
|
2386
2636
|
}
|
|
2387
2637
|
compileUpdateAssignments(assignments, table, ctx) {
|
|
2388
|
-
return
|
|
2389
|
-
const target = this.compileSetTarget(assignment.column, table);
|
|
2390
|
-
const value = this.compileOperand(assignment.value, ctx);
|
|
2391
|
-
return `${target} = ${value}`;
|
|
2392
|
-
}).join(", ");
|
|
2638
|
+
return this.standardUpdateCompiler.compileAssignments(assignments, table, ctx);
|
|
2393
2639
|
}
|
|
2394
2640
|
compileSetTarget(column, table) {
|
|
2395
2641
|
return this.compileQualifiedColumn(column, table);
|
|
@@ -2402,112 +2648,35 @@ var SqlDialectBase = class extends DialectBase {
|
|
|
2402
2648
|
if (!tableQualifier) return this.quoteIdentifier(column.name);
|
|
2403
2649
|
return `${this.quoteIdentifier(tableQualifier)}.${this.quoteIdentifier(column.name)}`;
|
|
2404
2650
|
}
|
|
2405
|
-
compileDeleteAst(ast, ctx) {
|
|
2406
|
-
const target = this.compileTableReference(ast.from);
|
|
2407
|
-
const usingClause = this.compileDeleteUsingClause(ast, ctx);
|
|
2408
|
-
const whereClause = this.compileWhere(ast.where, ctx);
|
|
2409
|
-
const returning = this.compileReturning(ast.returning, ctx);
|
|
2410
|
-
return `DELETE FROM ${target}${usingClause}${whereClause}${returning}`;
|
|
2411
|
-
}
|
|
2412
2651
|
formatReturningColumns(returning) {
|
|
2413
|
-
return this.returningStrategy.formatReturningColumns(
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
}
|
|
2418
|
-
compileSelectColumns(ast, ctx) {
|
|
2419
|
-
if (!ast.columns || ast.columns.length === 0) return "*";
|
|
2420
|
-
return ast.columns.map((column) => {
|
|
2421
|
-
const expr = this.compileOperand(column, ctx);
|
|
2422
|
-
if (column.alias) {
|
|
2423
|
-
if (column.alias.includes("(")) return column.alias;
|
|
2424
|
-
return `${expr} AS ${this.quoteIdentifier(column.alias)}`;
|
|
2425
|
-
}
|
|
2426
|
-
return expr;
|
|
2427
|
-
}).join(", ");
|
|
2652
|
+
return this.returningStrategy.formatReturningColumns(
|
|
2653
|
+
returning,
|
|
2654
|
+
(id) => this.quoteIdentifier(id)
|
|
2655
|
+
);
|
|
2428
2656
|
}
|
|
2429
|
-
compileFrom(
|
|
2430
|
-
|
|
2431
|
-
if (ast.type === "DerivedTable") return this.compileDerivedTable(ast, ctx);
|
|
2432
|
-
return this.compileTableSource(ast);
|
|
2657
|
+
compileFrom(source, ctx) {
|
|
2658
|
+
return this.sourceCompiler.compileFrom(source, ctx);
|
|
2433
2659
|
}
|
|
2434
2660
|
compileFunctionTable(fn9, ctx) {
|
|
2435
|
-
|
|
2436
|
-
if (ctx) {
|
|
2437
|
-
const renderer = this.tableFunctionStrategy.getRenderer(key);
|
|
2438
|
-
if (renderer) {
|
|
2439
|
-
const compiledArgs = (fn9.args ?? []).map((arg) => this.compileOperand(arg, ctx));
|
|
2440
|
-
return renderer({
|
|
2441
|
-
node: fn9,
|
|
2442
|
-
compiledArgs,
|
|
2443
|
-
compileOperand: (operand) => this.compileOperand(operand, ctx),
|
|
2444
|
-
quoteIdentifier: this.quoteIdentifier.bind(this)
|
|
2445
|
-
});
|
|
2446
|
-
}
|
|
2447
|
-
if (fn9.key) {
|
|
2448
|
-
throw new Error(`Table function "${key}" is not supported by dialect "${this.dialect}".`);
|
|
2449
|
-
}
|
|
2450
|
-
}
|
|
2451
|
-
return FunctionTableFormatter.format(fn9, ctx, {
|
|
2452
|
-
quoteIdentifier: (id) => this.quoteIdentifier(id),
|
|
2453
|
-
compileOperand: (node, compilerContext) => this.compileOperand(node, compilerContext)
|
|
2454
|
-
});
|
|
2661
|
+
return this.sourceCompiler.compileFunctionTable(fn9, ctx);
|
|
2455
2662
|
}
|
|
2456
2663
|
compileDerivedTable(table, ctx) {
|
|
2457
|
-
|
|
2458
|
-
const subquery = this.compileSelectAst(this.normalizeSelectAst(table.query), ctx).trim().replace(/;$/, "");
|
|
2459
|
-
const columns = table.columnAliases?.length ? ` (${table.columnAliases.map((c) => this.quoteIdentifier(c)).join(", ")})` : "";
|
|
2460
|
-
return `(${subquery}) AS ${this.quoteIdentifier(table.alias)}${columns}`;
|
|
2664
|
+
return this.sourceCompiler.compileDerivedTable(table, ctx);
|
|
2461
2665
|
}
|
|
2462
2666
|
compileTableSource(table) {
|
|
2463
|
-
|
|
2464
|
-
if (table.type === "DerivedTable") return this.compileDerivedTable(table);
|
|
2465
|
-
const base = this.compileTableName(table);
|
|
2466
|
-
return table.alias ? `${base} AS ${this.quoteIdentifier(table.alias)}` : base;
|
|
2667
|
+
return this.sourceCompiler.compileTableSource(table);
|
|
2467
2668
|
}
|
|
2468
2669
|
compileTableName(table) {
|
|
2469
|
-
|
|
2470
|
-
return `${this.quoteIdentifier(table.schema)}.${this.quoteIdentifier(table.name)}`;
|
|
2471
|
-
}
|
|
2472
|
-
return this.quoteIdentifier(table.name);
|
|
2670
|
+
return this.sourceCompiler.compileTableName(table);
|
|
2473
2671
|
}
|
|
2474
2672
|
compileTableReference(table) {
|
|
2475
|
-
|
|
2476
|
-
return table.alias ? `${base} AS ${this.quoteIdentifier(table.alias)}` : base;
|
|
2477
|
-
}
|
|
2478
|
-
compileUpdateFromClause(ast, ctx) {
|
|
2479
|
-
if (!ast.from && (!ast.joins || ast.joins.length === 0)) return "";
|
|
2480
|
-
if (!ast.from) throw new Error("UPDATE with JOINs requires an explicit FROM clause.");
|
|
2481
|
-
const from = this.compileFrom(ast.from, ctx);
|
|
2482
|
-
const joins = JoinCompiler.compileJoins(
|
|
2483
|
-
ast.joins,
|
|
2484
|
-
ctx,
|
|
2485
|
-
this.compileFrom.bind(this),
|
|
2486
|
-
this.compileExpression.bind(this)
|
|
2487
|
-
);
|
|
2488
|
-
return ` FROM ${from}${joins}`;
|
|
2489
|
-
}
|
|
2490
|
-
compileDeleteUsingClause(ast, ctx) {
|
|
2491
|
-
if (!ast.using && (!ast.joins || ast.joins.length === 0)) return "";
|
|
2492
|
-
if (!ast.using) throw new Error("DELETE with JOINs requires a USING clause.");
|
|
2493
|
-
const usingTable = this.compileFrom(ast.using, ctx);
|
|
2494
|
-
const joins = JoinCompiler.compileJoins(
|
|
2495
|
-
ast.joins,
|
|
2496
|
-
ctx,
|
|
2497
|
-
this.compileFrom.bind(this),
|
|
2498
|
-
this.compileExpression.bind(this)
|
|
2499
|
-
);
|
|
2500
|
-
return ` USING ${usingTable}${joins}`;
|
|
2501
|
-
}
|
|
2502
|
-
compileHaving(ast, ctx) {
|
|
2503
|
-
if (!ast.having) return "";
|
|
2504
|
-
return ` HAVING ${this.compileExpression(ast.having, ctx)}`;
|
|
2673
|
+
return this.sourceCompiler.compileTableReference(table);
|
|
2505
2674
|
}
|
|
2506
2675
|
stripTrailingSemicolon(sql) {
|
|
2507
|
-
return
|
|
2676
|
+
return this.sourceCompiler.stripTrailingSemicolon(sql);
|
|
2508
2677
|
}
|
|
2509
2678
|
wrapSetOperand(sql) {
|
|
2510
|
-
return
|
|
2679
|
+
return this.sourceCompiler.wrapSetOperand(sql);
|
|
2511
2680
|
}
|
|
2512
2681
|
renderOrderByNulls(order) {
|
|
2513
2682
|
return order.nulls ? ` NULLS ${order.nulls}` : "";
|
|
@@ -2692,105 +2861,112 @@ var PostgresTableFunctionStrategy = class extends StandardTableFunctionStrategy
|
|
|
2692
2861
|
}
|
|
2693
2862
|
};
|
|
2694
2863
|
|
|
2864
|
+
// src/core/dialect/postgres/procedure-compiler.ts
|
|
2865
|
+
var PostgresProcedureCompiler = class {
|
|
2866
|
+
constructor(services) {
|
|
2867
|
+
this.services = services;
|
|
2868
|
+
}
|
|
2869
|
+
compileProcedureCall(ast) {
|
|
2870
|
+
const ctx = this.services.createCompilerContext();
|
|
2871
|
+
const qualifiedName = ast.ref.schema ? `${this.services.quoteIdentifier(ast.ref.schema)}.${this.services.quoteIdentifier(ast.ref.name)}` : this.services.quoteIdentifier(ast.ref.name);
|
|
2872
|
+
const args = [];
|
|
2873
|
+
for (const param of ast.params) {
|
|
2874
|
+
if (param.direction === "out") continue;
|
|
2875
|
+
if (!param.value) {
|
|
2876
|
+
throw new Error(
|
|
2877
|
+
`Procedure parameter "${param.name}" requires a value for direction "${param.direction}".`
|
|
2878
|
+
);
|
|
2879
|
+
}
|
|
2880
|
+
args.push(this.services.compileOperand(param.value, ctx));
|
|
2881
|
+
}
|
|
2882
|
+
const outNames = ast.params.filter((param) => param.direction === "out" || param.direction === "inout").map((param) => param.name);
|
|
2883
|
+
return {
|
|
2884
|
+
sql: `CALL ${qualifiedName}(${args.join(", ")});`,
|
|
2885
|
+
params: [...ctx.params],
|
|
2886
|
+
outParams: {
|
|
2887
|
+
source: outNames.length ? "firstResultSet" : "none",
|
|
2888
|
+
names: outNames
|
|
2889
|
+
}
|
|
2890
|
+
};
|
|
2891
|
+
}
|
|
2892
|
+
};
|
|
2893
|
+
|
|
2894
|
+
// src/core/dialect/postgres/returning.ts
|
|
2895
|
+
var PostgresReturningStrategy = class extends StandardReturningStrategy {
|
|
2896
|
+
};
|
|
2897
|
+
|
|
2898
|
+
// src/core/dialect/postgres/upsert.ts
|
|
2899
|
+
var PostgresUpsertStrategy = class {
|
|
2900
|
+
compile(ast, ctx, services) {
|
|
2901
|
+
if (!ast.onConflict) return "";
|
|
2902
|
+
const clause = ast.onConflict;
|
|
2903
|
+
const target = clause.target.constraint ? ` ON CONFLICT ON CONSTRAINT ${services.quoteIdentifier(clause.target.constraint)}` : (() => {
|
|
2904
|
+
if (!clause.target.columns.length) {
|
|
2905
|
+
throw new Error("PostgreSQL ON CONFLICT requires conflict columns or a constraint name.");
|
|
2906
|
+
}
|
|
2907
|
+
const columns = clause.target.columns.map((column) => services.quoteIdentifier(column.name)).join(", ");
|
|
2908
|
+
return ` ON CONFLICT (${columns})`;
|
|
2909
|
+
})();
|
|
2910
|
+
if (clause.action.type === "DoNothing") {
|
|
2911
|
+
return `${target} DO NOTHING`;
|
|
2912
|
+
}
|
|
2913
|
+
if (!clause.action.set.length) {
|
|
2914
|
+
throw new Error("PostgreSQL ON CONFLICT DO UPDATE requires at least one assignment.");
|
|
2915
|
+
}
|
|
2916
|
+
const assignments = services.compileUpdateAssignments(clause.action.set, ast.into, ctx);
|
|
2917
|
+
const where = clause.action.where ? ` WHERE ${services.compileExpression(clause.action.where, ctx)}` : "";
|
|
2918
|
+
return `${target} DO UPDATE SET ${assignments}${where}`;
|
|
2919
|
+
}
|
|
2920
|
+
};
|
|
2921
|
+
|
|
2695
2922
|
// src/core/dialect/postgres/index.ts
|
|
2696
2923
|
var PostgresDialect = class extends SqlDialectBase {
|
|
2697
2924
|
dialect = "postgres";
|
|
2698
|
-
|
|
2699
|
-
* Creates a new PostgresDialect instance
|
|
2700
|
-
*/
|
|
2925
|
+
procedureCompiler;
|
|
2701
2926
|
constructor() {
|
|
2702
|
-
super(
|
|
2927
|
+
super({
|
|
2928
|
+
functionStrategy: new PostgresFunctionStrategy(),
|
|
2929
|
+
tableFunctionStrategy: new PostgresTableFunctionStrategy(),
|
|
2930
|
+
returningStrategy: new PostgresReturningStrategy(),
|
|
2931
|
+
upsertStrategy: new PostgresUpsertStrategy(),
|
|
2932
|
+
supportsDmlReturning: true
|
|
2933
|
+
});
|
|
2934
|
+
this.procedureCompiler = new PostgresProcedureCompiler({
|
|
2935
|
+
quoteIdentifier: (id) => this.quoteIdentifier(id),
|
|
2936
|
+
createCompilerContext: () => this.createCompilerContext(),
|
|
2937
|
+
compileOperand: (node, ctx) => this.compileOperand(node, ctx)
|
|
2938
|
+
});
|
|
2703
2939
|
this.registerExpressionCompiler("BitwiseExpression", (node, ctx) => {
|
|
2704
2940
|
const left2 = this.compileOperand(node.left, ctx);
|
|
2705
2941
|
const right2 = this.compileOperand(node.right, ctx);
|
|
2706
|
-
const
|
|
2707
|
-
return `${left2} ${
|
|
2942
|
+
const operator = node.operator === "^" ? "#" : node.operator;
|
|
2943
|
+
return `${left2} ${operator} ${right2}`;
|
|
2708
2944
|
});
|
|
2709
2945
|
this.registerOperandCompiler("BitwiseExpression", (node, ctx) => {
|
|
2710
2946
|
const left2 = this.compileOperand(node.left, ctx);
|
|
2711
2947
|
const right2 = this.compileOperand(node.right, ctx);
|
|
2712
|
-
const
|
|
2713
|
-
return `(${left2} ${
|
|
2948
|
+
const operator = node.operator === "^" ? "#" : node.operator;
|
|
2949
|
+
return `(${left2} ${operator} ${right2})`;
|
|
2714
2950
|
});
|
|
2715
2951
|
}
|
|
2716
|
-
/**
|
|
2717
|
-
* Quotes an identifier using PostgreSQL double-quote syntax
|
|
2718
|
-
* @param id - Identifier to quote
|
|
2719
|
-
* @returns Quoted identifier
|
|
2720
|
-
*/
|
|
2721
2952
|
quoteIdentifier(id) {
|
|
2722
2953
|
return `"${id}"`;
|
|
2723
2954
|
}
|
|
2724
2955
|
formatPlaceholder(index) {
|
|
2725
2956
|
return `$${index}`;
|
|
2726
2957
|
}
|
|
2727
|
-
/**
|
|
2728
|
-
* Compiles JSON path expression using PostgreSQL syntax
|
|
2729
|
-
* @param node - JSON path node
|
|
2730
|
-
* @returns PostgreSQL JSON path expression
|
|
2731
|
-
*/
|
|
2732
2958
|
compileJsonPath(node) {
|
|
2733
|
-
const
|
|
2734
|
-
return `${
|
|
2735
|
-
}
|
|
2736
|
-
compileReturning(returning, ctx) {
|
|
2737
|
-
void ctx;
|
|
2738
|
-
if (!returning || returning.length === 0) return "";
|
|
2739
|
-
const columns = this.formatReturningColumns(returning);
|
|
2740
|
-
return ` RETURNING ${columns}`;
|
|
2741
|
-
}
|
|
2742
|
-
compileUpsertClause(ast, ctx) {
|
|
2743
|
-
if (!ast.onConflict) return "";
|
|
2744
|
-
const clause = ast.onConflict;
|
|
2745
|
-
const target = clause.target.constraint ? ` ON CONFLICT ON CONSTRAINT ${this.quoteIdentifier(clause.target.constraint)}` : (() => {
|
|
2746
|
-
this.ensureConflictColumns(
|
|
2747
|
-
clause,
|
|
2748
|
-
"PostgreSQL ON CONFLICT requires conflict columns or a constraint name."
|
|
2749
|
-
);
|
|
2750
|
-
const cols = clause.target.columns.map((col2) => this.quoteIdentifier(col2.name)).join(", ");
|
|
2751
|
-
return ` ON CONFLICT (${cols})`;
|
|
2752
|
-
})();
|
|
2753
|
-
if (clause.action.type === "DoNothing") {
|
|
2754
|
-
return `${target} DO NOTHING`;
|
|
2755
|
-
}
|
|
2756
|
-
if (!clause.action.set.length) {
|
|
2757
|
-
throw new Error("PostgreSQL ON CONFLICT DO UPDATE requires at least one assignment.");
|
|
2758
|
-
}
|
|
2759
|
-
const assignments = this.compileUpdateAssignments(clause.action.set, ast.into, ctx);
|
|
2760
|
-
const where = clause.action.where ? ` WHERE ${this.compileExpression(clause.action.where, ctx)}` : "";
|
|
2761
|
-
return `${target} DO UPDATE SET ${assignments}${where}`;
|
|
2762
|
-
}
|
|
2763
|
-
supportsDmlReturningClause() {
|
|
2764
|
-
return true;
|
|
2765
|
-
}
|
|
2766
|
-
compileProcedureCall(ast) {
|
|
2767
|
-
const ctx = this.createCompilerContext();
|
|
2768
|
-
const qualifiedName = ast.ref.schema ? `${this.quoteIdentifier(ast.ref.schema)}.${this.quoteIdentifier(ast.ref.name)}` : this.quoteIdentifier(ast.ref.name);
|
|
2769
|
-
const args = [];
|
|
2770
|
-
for (const param of ast.params) {
|
|
2771
|
-
if (param.direction === "out") continue;
|
|
2772
|
-
if (!param.value) {
|
|
2773
|
-
throw new Error(`Procedure parameter "${param.name}" requires a value for direction "${param.direction}".`);
|
|
2774
|
-
}
|
|
2775
|
-
args.push(this.compileOperand(param.value, ctx));
|
|
2776
|
-
}
|
|
2777
|
-
const outNames = ast.params.filter((param) => param.direction === "out" || param.direction === "inout").map((param) => param.name);
|
|
2778
|
-
const rawSql = `CALL ${qualifiedName}(${args.join(", ")})`;
|
|
2779
|
-
return {
|
|
2780
|
-
sql: `${rawSql};`,
|
|
2781
|
-
params: [...ctx.params],
|
|
2782
|
-
outParams: {
|
|
2783
|
-
source: outNames.length ? "firstResultSet" : "none",
|
|
2784
|
-
names: outNames
|
|
2785
|
-
}
|
|
2786
|
-
};
|
|
2959
|
+
const column = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
|
|
2960
|
+
return `${column}->>'${node.path}'`;
|
|
2787
2961
|
}
|
|
2788
|
-
/**
|
|
2789
|
-
* PostgreSQL requires unqualified column names in SET clause
|
|
2790
|
-
*/
|
|
2962
|
+
/** PostgreSQL requires unqualified column names in SET clauses. */
|
|
2791
2963
|
compileSetTarget(column, _table) {
|
|
2964
|
+
void _table;
|
|
2792
2965
|
return this.quoteIdentifier(column.name);
|
|
2793
2966
|
}
|
|
2967
|
+
compileProcedureCall(ast) {
|
|
2968
|
+
return this.procedureCompiler.compileProcedureCall(ast);
|
|
2969
|
+
}
|
|
2794
2970
|
};
|
|
2795
2971
|
|
|
2796
2972
|
// src/core/dialect/mysql/functions.ts
|
|
@@ -2891,72 +3067,15 @@ var MysqlFunctionStrategy = class extends StandardFunctionStrategy {
|
|
|
2891
3067
|
}
|
|
2892
3068
|
};
|
|
2893
3069
|
|
|
2894
|
-
// src/core/dialect/mysql/
|
|
3070
|
+
// src/core/dialect/mysql/procedure-compiler.ts
|
|
2895
3071
|
var sanitizeVariableSuffix = (value) => value.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
2896
|
-
var
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
* Creates a new MySqlDialect instance
|
|
2900
|
-
*/
|
|
2901
|
-
constructor() {
|
|
2902
|
-
super(new MysqlFunctionStrategy());
|
|
2903
|
-
this.registerExpressionCompiler(
|
|
2904
|
-
"IsDistinctExpression",
|
|
2905
|
-
(node, ctx) => {
|
|
2906
|
-
const left2 = this.compileOperand(node.left, ctx);
|
|
2907
|
-
const right2 = this.compileOperand(node.right, ctx);
|
|
2908
|
-
const spaceship = `${left2} <=> ${right2}`;
|
|
2909
|
-
if (node.operator === "IS NOT DISTINCT FROM") {
|
|
2910
|
-
return spaceship;
|
|
2911
|
-
}
|
|
2912
|
-
return `NOT (${spaceship})`;
|
|
2913
|
-
}
|
|
2914
|
-
);
|
|
2915
|
-
}
|
|
2916
|
-
/**
|
|
2917
|
-
* Quotes an identifier using MySQL backtick syntax
|
|
2918
|
-
* @param id - Identifier to quote
|
|
2919
|
-
* @returns Quoted identifier
|
|
2920
|
-
*/
|
|
2921
|
-
quoteIdentifier(id) {
|
|
2922
|
-
return `\`${id}\``;
|
|
2923
|
-
}
|
|
2924
|
-
/**
|
|
2925
|
-
* Compiles JSON path expression using MySQL syntax
|
|
2926
|
-
* @param node - JSON path node
|
|
2927
|
-
* @returns MySQL JSON path expression
|
|
2928
|
-
*/
|
|
2929
|
-
compileJsonPath(node) {
|
|
2930
|
-
const col2 = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
|
|
2931
|
-
return `${col2}->'${node.path}'`;
|
|
2932
|
-
}
|
|
2933
|
-
compileUpsertClause(ast, ctx) {
|
|
2934
|
-
if (!ast.onConflict) return "";
|
|
2935
|
-
const clause = ast.onConflict;
|
|
2936
|
-
if (clause.action.type === "DoNothing") {
|
|
2937
|
-
const noOpColumn = clause.target.columns[0] ?? ast.columns[0];
|
|
2938
|
-
if (!noOpColumn) {
|
|
2939
|
-
throw new Error("MySQL ON DUPLICATE KEY UPDATE requires at least one target column.");
|
|
2940
|
-
}
|
|
2941
|
-
const col2 = this.quoteIdentifier(noOpColumn.name);
|
|
2942
|
-
return ` ON DUPLICATE KEY UPDATE ${col2} = ${col2}`;
|
|
2943
|
-
}
|
|
2944
|
-
if (clause.action.where) {
|
|
2945
|
-
throw new Error("MySQL ON DUPLICATE KEY UPDATE does not support a WHERE clause.");
|
|
2946
|
-
}
|
|
2947
|
-
if (!clause.action.set.length) {
|
|
2948
|
-
throw new Error("MySQL ON DUPLICATE KEY UPDATE requires at least one assignment.");
|
|
2949
|
-
}
|
|
2950
|
-
const assignments = clause.action.set.map((assignment) => {
|
|
2951
|
-
const target = this.quoteIdentifier(assignment.column.name);
|
|
2952
|
-
const value = this.compileOperand(assignment.value, ctx);
|
|
2953
|
-
return `${target} = ${value}`;
|
|
2954
|
-
}).join(", ");
|
|
2955
|
-
return ` ON DUPLICATE KEY UPDATE ${assignments}`;
|
|
3072
|
+
var MySqlProcedureCompiler = class {
|
|
3073
|
+
constructor(services) {
|
|
3074
|
+
this.services = services;
|
|
2956
3075
|
}
|
|
2957
3076
|
compileProcedureCall(ast) {
|
|
2958
|
-
const ctx = this.createCompilerContext();
|
|
2959
|
-
const qualifiedName = ast.ref.schema ? `${this.quoteIdentifier(ast.ref.schema)}.${this.quoteIdentifier(ast.ref.name)}` : this.quoteIdentifier(ast.ref.name);
|
|
3077
|
+
const ctx = this.services.createCompilerContext();
|
|
3078
|
+
const qualifiedName = ast.ref.schema ? `${this.services.quoteIdentifier(ast.ref.schema)}.${this.services.quoteIdentifier(ast.ref.name)}` : this.services.quoteIdentifier(ast.ref.name);
|
|
2960
3079
|
const prelude = [];
|
|
2961
3080
|
const callArgs = [];
|
|
2962
3081
|
const outVars = [];
|
|
@@ -2967,35 +3086,97 @@ var MySqlDialect = class extends SqlDialectBase {
|
|
|
2967
3086
|
if (!param.value) {
|
|
2968
3087
|
throw new Error(`Procedure parameter "${param.name}" requires a value for direction "in".`);
|
|
2969
3088
|
}
|
|
2970
|
-
callArgs.push(this.compileOperand(param.value, ctx));
|
|
3089
|
+
callArgs.push(this.services.compileOperand(param.value, ctx));
|
|
2971
3090
|
return;
|
|
2972
3091
|
}
|
|
2973
3092
|
if (param.direction === "inout") {
|
|
2974
3093
|
if (!param.value) {
|
|
2975
3094
|
throw new Error(`Procedure parameter "${param.name}" requires a value for direction "inout".`);
|
|
2976
3095
|
}
|
|
2977
|
-
prelude.push(`SET ${variable} = ${this.compileOperand(param.value, ctx)};`);
|
|
3096
|
+
prelude.push(`SET ${variable} = ${this.services.compileOperand(param.value, ctx)};`);
|
|
2978
3097
|
}
|
|
2979
3098
|
callArgs.push(variable);
|
|
2980
3099
|
outVars.push({ variable, name: param.name });
|
|
2981
3100
|
});
|
|
2982
3101
|
const statements = [];
|
|
2983
|
-
if (prelude.length)
|
|
2984
|
-
|
|
3102
|
+
if (prelude.length) statements.push(...prelude);
|
|
3103
|
+
statements.push(`CALL ${qualifiedName}(${callArgs.join(", ")});`);
|
|
3104
|
+
if (outVars.length) {
|
|
3105
|
+
const selectOut = outVars.map(({ variable, name }) => `${variable} AS ${this.services.quoteIdentifier(name)}`).join(", ");
|
|
3106
|
+
statements.push(`SELECT ${selectOut};`);
|
|
3107
|
+
}
|
|
3108
|
+
return {
|
|
3109
|
+
sql: statements.join(" "),
|
|
3110
|
+
params: [...ctx.params],
|
|
3111
|
+
outParams: {
|
|
3112
|
+
source: outVars.length ? "lastResultSet" : "none",
|
|
3113
|
+
names: outVars.map((item) => item.name)
|
|
3114
|
+
}
|
|
3115
|
+
};
|
|
3116
|
+
}
|
|
3117
|
+
};
|
|
3118
|
+
|
|
3119
|
+
// src/core/dialect/mysql/upsert.ts
|
|
3120
|
+
var MySqlUpsertStrategy = class {
|
|
3121
|
+
compile(ast, ctx, services) {
|
|
3122
|
+
if (!ast.onConflict) return "";
|
|
3123
|
+
const clause = ast.onConflict;
|
|
3124
|
+
if (clause.action.type === "DoNothing") {
|
|
3125
|
+
const noOpColumn = clause.target.columns[0] ?? ast.columns[0];
|
|
3126
|
+
if (!noOpColumn) {
|
|
3127
|
+
throw new Error("MySQL ON DUPLICATE KEY UPDATE requires at least one target column.");
|
|
3128
|
+
}
|
|
3129
|
+
const col2 = services.quoteIdentifier(noOpColumn.name);
|
|
3130
|
+
return ` ON DUPLICATE KEY UPDATE ${col2} = ${col2}`;
|
|
3131
|
+
}
|
|
3132
|
+
if (clause.action.where) {
|
|
3133
|
+
throw new Error("MySQL ON DUPLICATE KEY UPDATE does not support a WHERE clause.");
|
|
2985
3134
|
}
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
const selectOut = outVars.map(({ variable, name }) => `${variable} AS ${this.quoteIdentifier(name)}`).join(", ");
|
|
2989
|
-
statements.push(`SELECT ${selectOut};`);
|
|
3135
|
+
if (!clause.action.set.length) {
|
|
3136
|
+
throw new Error("MySQL ON DUPLICATE KEY UPDATE requires at least one assignment.");
|
|
2990
3137
|
}
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
3138
|
+
const assignments = clause.action.set.map((assignment) => {
|
|
3139
|
+
const target = services.quoteIdentifier(assignment.column.name);
|
|
3140
|
+
const value = services.compileOperand(assignment.value, ctx);
|
|
3141
|
+
return `${target} = ${value}`;
|
|
3142
|
+
}).join(", ");
|
|
3143
|
+
return ` ON DUPLICATE KEY UPDATE ${assignments}`;
|
|
3144
|
+
}
|
|
3145
|
+
};
|
|
3146
|
+
|
|
3147
|
+
// src/core/dialect/mysql/index.ts
|
|
3148
|
+
var MySqlDialect = class extends SqlDialectBase {
|
|
3149
|
+
dialect = "mysql";
|
|
3150
|
+
procedureCompiler;
|
|
3151
|
+
constructor() {
|
|
3152
|
+
super({
|
|
3153
|
+
functionStrategy: new MysqlFunctionStrategy(),
|
|
3154
|
+
upsertStrategy: new MySqlUpsertStrategy()
|
|
3155
|
+
});
|
|
3156
|
+
this.procedureCompiler = new MySqlProcedureCompiler({
|
|
3157
|
+
quoteIdentifier: (id) => this.quoteIdentifier(id),
|
|
3158
|
+
createCompilerContext: () => this.createCompilerContext(),
|
|
3159
|
+
compileOperand: (node, ctx) => this.compileOperand(node, ctx)
|
|
3160
|
+
});
|
|
3161
|
+
this.registerExpressionCompiler(
|
|
3162
|
+
"IsDistinctExpression",
|
|
3163
|
+
(node, ctx) => {
|
|
3164
|
+
const left2 = this.compileOperand(node.left, ctx);
|
|
3165
|
+
const right2 = this.compileOperand(node.right, ctx);
|
|
3166
|
+
const spaceship = `${left2} <=> ${right2}`;
|
|
3167
|
+
return node.operator === "IS NOT DISTINCT FROM" ? spaceship : `NOT (${spaceship})`;
|
|
2997
3168
|
}
|
|
2998
|
-
|
|
3169
|
+
);
|
|
3170
|
+
}
|
|
3171
|
+
quoteIdentifier(id) {
|
|
3172
|
+
return `\`${id}\``;
|
|
3173
|
+
}
|
|
3174
|
+
compileJsonPath(node) {
|
|
3175
|
+
const column = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
|
|
3176
|
+
return `${column}->'${node.path}'`;
|
|
3177
|
+
}
|
|
3178
|
+
compileProcedureCall(ast) {
|
|
3179
|
+
return this.procedureCompiler.compileProcedureCall(ast);
|
|
2999
3180
|
}
|
|
3000
3181
|
};
|
|
3001
3182
|
|
|
@@ -3136,14 +3317,56 @@ var SqliteFunctionStrategy = class extends StandardFunctionStrategy {
|
|
|
3136
3317
|
}
|
|
3137
3318
|
};
|
|
3138
3319
|
|
|
3320
|
+
// src/core/dialect/sqlite/returning.ts
|
|
3321
|
+
var SqliteReturningStrategy = class {
|
|
3322
|
+
compileReturning(returning, _ctx, quoteIdentifier) {
|
|
3323
|
+
void _ctx;
|
|
3324
|
+
if (!returning || returning.length === 0) return "";
|
|
3325
|
+
return ` RETURNING ${this.formatReturningColumns(returning, quoteIdentifier)}`;
|
|
3326
|
+
}
|
|
3327
|
+
formatReturningColumns(returning, quoteIdentifier) {
|
|
3328
|
+
return returning.map((column) => {
|
|
3329
|
+
const alias = column.alias ? ` AS ${quoteIdentifier(column.alias)}` : "";
|
|
3330
|
+
return `${quoteIdentifier(column.name)}${alias}`;
|
|
3331
|
+
}).join(", ");
|
|
3332
|
+
}
|
|
3333
|
+
};
|
|
3334
|
+
|
|
3335
|
+
// src/core/dialect/sqlite/upsert.ts
|
|
3336
|
+
var SqliteUpsertStrategy = class {
|
|
3337
|
+
compile(ast, ctx, services) {
|
|
3338
|
+
if (!ast.onConflict) return "";
|
|
3339
|
+
const clause = ast.onConflict;
|
|
3340
|
+
if (clause.target.constraint) {
|
|
3341
|
+
throw new Error("SQLite ON CONFLICT does not support named constraints.");
|
|
3342
|
+
}
|
|
3343
|
+
if (!clause.target.columns.length) {
|
|
3344
|
+
throw new Error("SQLite ON CONFLICT requires conflict columns.");
|
|
3345
|
+
}
|
|
3346
|
+
const columns = clause.target.columns.map((column) => services.quoteIdentifier(column.name)).join(", ");
|
|
3347
|
+
const target = ` ON CONFLICT (${columns})`;
|
|
3348
|
+
if (clause.action.type === "DoNothing") {
|
|
3349
|
+
return `${target} DO NOTHING`;
|
|
3350
|
+
}
|
|
3351
|
+
if (!clause.action.set.length) {
|
|
3352
|
+
throw new Error("SQLite ON CONFLICT DO UPDATE requires at least one assignment.");
|
|
3353
|
+
}
|
|
3354
|
+
const assignments = services.compileUpdateAssignments(clause.action.set, ast.into, ctx);
|
|
3355
|
+
const where = clause.action.where ? ` WHERE ${services.compileExpression(clause.action.where, ctx)}` : "";
|
|
3356
|
+
return `${target} DO UPDATE SET ${assignments}${where}`;
|
|
3357
|
+
}
|
|
3358
|
+
};
|
|
3359
|
+
|
|
3139
3360
|
// src/core/dialect/sqlite/index.ts
|
|
3140
3361
|
var SqliteDialect = class extends SqlDialectBase {
|
|
3141
3362
|
dialect = "sqlite";
|
|
3142
|
-
/**
|
|
3143
|
-
* Creates a new SqliteDialect instance
|
|
3144
|
-
*/
|
|
3145
3363
|
constructor() {
|
|
3146
|
-
super(
|
|
3364
|
+
super({
|
|
3365
|
+
functionStrategy: new SqliteFunctionStrategy(),
|
|
3366
|
+
returningStrategy: new SqliteReturningStrategy(),
|
|
3367
|
+
upsertStrategy: new SqliteUpsertStrategy(),
|
|
3368
|
+
supportsDmlReturning: true
|
|
3369
|
+
});
|
|
3147
3370
|
this.registerExpressionCompiler("BitwiseExpression", (node, ctx) => {
|
|
3148
3371
|
const left2 = this.compileOperand(node.left, ctx);
|
|
3149
3372
|
const right2 = this.compileOperand(node.right, ctx);
|
|
@@ -3161,61 +3384,17 @@ var SqliteDialect = class extends SqlDialectBase {
|
|
|
3161
3384
|
return `(${left2} ${node.operator} ${right2})`;
|
|
3162
3385
|
});
|
|
3163
3386
|
}
|
|
3164
|
-
/**
|
|
3165
|
-
* Quotes an identifier using SQLite double-quote syntax
|
|
3166
|
-
* @param id - Identifier to quote
|
|
3167
|
-
* @returns Quoted identifier
|
|
3168
|
-
*/
|
|
3169
3387
|
quoteIdentifier(id) {
|
|
3170
3388
|
return `"${id}"`;
|
|
3171
3389
|
}
|
|
3172
|
-
/**
|
|
3173
|
-
* Compiles JSON path expression using SQLite syntax
|
|
3174
|
-
* @param node - JSON path node
|
|
3175
|
-
* @returns SQLite JSON path expression
|
|
3176
|
-
*/
|
|
3177
3390
|
compileJsonPath(node) {
|
|
3178
|
-
const
|
|
3179
|
-
return `json_extract(${
|
|
3391
|
+
const column = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
|
|
3392
|
+
return `json_extract(${column}, '${node.path}')`;
|
|
3180
3393
|
}
|
|
3181
3394
|
compileQualifiedColumn(column, _table) {
|
|
3182
3395
|
void _table;
|
|
3183
3396
|
return this.quoteIdentifier(column.name);
|
|
3184
3397
|
}
|
|
3185
|
-
compileReturning(returning, ctx) {
|
|
3186
|
-
void ctx;
|
|
3187
|
-
if (!returning || returning.length === 0) return "";
|
|
3188
|
-
const columns = this.formatReturningColumns(returning);
|
|
3189
|
-
return ` RETURNING ${columns}`;
|
|
3190
|
-
}
|
|
3191
|
-
formatReturningColumns(returning) {
|
|
3192
|
-
return returning.map((column) => {
|
|
3193
|
-
const alias = column.alias ? ` AS ${this.quoteIdentifier(column.alias)}` : "";
|
|
3194
|
-
return `${this.quoteIdentifier(column.name)}${alias}`;
|
|
3195
|
-
}).join(", ");
|
|
3196
|
-
}
|
|
3197
|
-
compileUpsertClause(ast, ctx) {
|
|
3198
|
-
if (!ast.onConflict) return "";
|
|
3199
|
-
const clause = ast.onConflict;
|
|
3200
|
-
if (clause.target.constraint) {
|
|
3201
|
-
throw new Error("SQLite ON CONFLICT does not support named constraints.");
|
|
3202
|
-
}
|
|
3203
|
-
this.ensureConflictColumns(clause, "SQLite ON CONFLICT requires conflict columns.");
|
|
3204
|
-
const cols = clause.target.columns.map((col2) => this.quoteIdentifier(col2.name)).join(", ");
|
|
3205
|
-
const target = ` ON CONFLICT (${cols})`;
|
|
3206
|
-
if (clause.action.type === "DoNothing") {
|
|
3207
|
-
return `${target} DO NOTHING`;
|
|
3208
|
-
}
|
|
3209
|
-
if (!clause.action.set.length) {
|
|
3210
|
-
throw new Error("SQLite ON CONFLICT DO UPDATE requires at least one assignment.");
|
|
3211
|
-
}
|
|
3212
|
-
const assignments = this.compileUpdateAssignments(clause.action.set, ast.into, ctx);
|
|
3213
|
-
const where = clause.action.where ? ` WHERE ${this.compileExpression(clause.action.where, ctx)}` : "";
|
|
3214
|
-
return `${target} DO UPDATE SET ${assignments}${where}`;
|
|
3215
|
-
}
|
|
3216
|
-
supportsDmlReturningClause() {
|
|
3217
|
-
return true;
|
|
3218
|
-
}
|
|
3219
3398
|
};
|
|
3220
3399
|
|
|
3221
3400
|
// src/core/dialect/mssql/functions.ts
|
|
@@ -3342,202 +3521,107 @@ var MssqlFunctionStrategy = class extends StandardFunctionStrategy {
|
|
|
3342
3521
|
}
|
|
3343
3522
|
};
|
|
3344
3523
|
|
|
3345
|
-
// src/core/dialect/mssql/
|
|
3346
|
-
var
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
/**
|
|
3351
|
-
* Creates a new SqlServerDialect instance
|
|
3352
|
-
*/
|
|
3353
|
-
constructor() {
|
|
3354
|
-
super(new MssqlFunctionStrategy());
|
|
3355
|
-
}
|
|
3356
|
-
/**
|
|
3357
|
-
* Quotes an identifier using SQL Server bracket syntax
|
|
3358
|
-
* @param id - Identifier to quote
|
|
3359
|
-
* @returns Quoted identifier
|
|
3360
|
-
*/
|
|
3361
|
-
quoteIdentifier(id) {
|
|
3362
|
-
return `[${id}]`;
|
|
3363
|
-
}
|
|
3364
|
-
/**
|
|
3365
|
-
* Compiles JSON path expression using SQL Server syntax
|
|
3366
|
-
* @param node - JSON path node
|
|
3367
|
-
* @returns SQL Server JSON path expression
|
|
3368
|
-
*/
|
|
3369
|
-
compileJsonPath(node) {
|
|
3370
|
-
const col2 = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
|
|
3371
|
-
return `JSON_VALUE(${col2}, '${node.path}')`;
|
|
3524
|
+
// src/core/dialect/mssql/output.ts
|
|
3525
|
+
var MssqlOutputStrategy = class {
|
|
3526
|
+
compileReturning(returning, _ctx, quoteIdentifier) {
|
|
3527
|
+
void _ctx;
|
|
3528
|
+
return this.compileOutput(returning, "inserted", quoteIdentifier);
|
|
3372
3529
|
}
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
return
|
|
3530
|
+
compileOutput(returning, prefix, quoteIdentifier) {
|
|
3531
|
+
if (!returning || returning.length === 0) return "";
|
|
3532
|
+
const columns = returning.map((column) => {
|
|
3533
|
+
const alias = column.alias ? ` AS ${quoteIdentifier(column.alias)}` : "";
|
|
3534
|
+
return `${prefix}.${quoteIdentifier(column.name)}${alias}`;
|
|
3535
|
+
}).join(", ");
|
|
3536
|
+
return ` OUTPUT ${columns}`;
|
|
3380
3537
|
}
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
*/
|
|
3387
|
-
compileSelectAst(ast, ctx) {
|
|
3388
|
-
const hasSetOps = !!(ast.setOps && ast.setOps.length);
|
|
3389
|
-
const ctes = this.compileCtes(ast, ctx);
|
|
3390
|
-
const baseAst = hasSetOps ? { ...ast, setOps: void 0, orderBy: void 0, limit: void 0, offset: void 0 } : ast;
|
|
3391
|
-
const baseSelect = this.compileSelectCoreForMssql(baseAst, ctx);
|
|
3392
|
-
if (!hasSetOps) {
|
|
3393
|
-
return `${ctes}${baseSelect}`;
|
|
3394
|
-
}
|
|
3395
|
-
const compound = ast.setOps.map((op) => `${op.operator} ${this.wrapSetOperand(this.compileSelectAst(op.query, ctx))}`).join(" ");
|
|
3396
|
-
const orderBy = this.compileOrderBy(ast, ctx);
|
|
3397
|
-
const pagination = this.compilePagination(ast, orderBy);
|
|
3398
|
-
const combined = `${this.wrapSetOperand(baseSelect)} ${compound}`;
|
|
3399
|
-
const tail = pagination || orderBy;
|
|
3400
|
-
return `${ctes}${combined}${tail}`;
|
|
3538
|
+
formatReturningColumns(returning, quoteIdentifier) {
|
|
3539
|
+
return returning.map((column) => {
|
|
3540
|
+
const alias = column.alias ? ` AS ${quoteIdentifier(column.alias)}` : "";
|
|
3541
|
+
return `${quoteIdentifier(column.name)}${alias}`;
|
|
3542
|
+
}).join(", ");
|
|
3401
3543
|
}
|
|
3402
|
-
|
|
3544
|
+
};
|
|
3545
|
+
|
|
3546
|
+
// src/core/dialect/mssql/delete-compiler.ts
|
|
3547
|
+
var MssqlDeleteCompiler = class {
|
|
3548
|
+
constructor(services, sources) {
|
|
3549
|
+
this.services = services;
|
|
3550
|
+
this.sources = sources;
|
|
3551
|
+
}
|
|
3552
|
+
output = new MssqlOutputStrategy();
|
|
3553
|
+
compile(ast, ctx) {
|
|
3403
3554
|
if (ast.using) {
|
|
3404
3555
|
throw new Error("DELETE ... USING is not supported in the MSSQL dialect; use join() instead.");
|
|
3405
3556
|
}
|
|
3406
|
-
if (ast.from.type !== "Table") {
|
|
3407
|
-
throw new Error("DELETE only supports base tables in the MSSQL dialect.");
|
|
3408
|
-
}
|
|
3409
3557
|
const alias = ast.from.alias ?? ast.from.name;
|
|
3410
|
-
const target = this.compileTableReference(ast.from);
|
|
3558
|
+
const target = this.sources.compileTableReference(ast.from);
|
|
3411
3559
|
const joins = JoinCompiler.compileJoins(
|
|
3412
3560
|
ast.joins,
|
|
3413
3561
|
ctx,
|
|
3414
|
-
this.compileFrom
|
|
3415
|
-
this.compileExpression
|
|
3562
|
+
(source, compilerContext) => this.sources.compileFrom(source, compilerContext),
|
|
3563
|
+
(expression, compilerContext) => this.services.compileExpression(expression, compilerContext)
|
|
3416
3564
|
);
|
|
3417
|
-
const
|
|
3418
|
-
const returning = this.
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
const target = this.compileTableReference(ast.table);
|
|
3423
|
-
const assignments = this.compileUpdateAssignments(ast.set, ast.table, ctx);
|
|
3424
|
-
const output = this.compileReturning(ast.returning, ctx);
|
|
3425
|
-
const fromClause = ast.from ? ` FROM ${this.compileFrom(ast.from, ctx)}` : "";
|
|
3426
|
-
const joins = ast.joins ? ast.joins.map((j) => {
|
|
3427
|
-
const table = this.compileFrom(j.table, ctx);
|
|
3428
|
-
const cond = this.compileExpression(j.condition, ctx);
|
|
3429
|
-
return ` ${j.kind} JOIN ${table} ON ${cond}`;
|
|
3430
|
-
}).join("") : "";
|
|
3431
|
-
const whereClause = this.compileWhere(ast.where, ctx);
|
|
3432
|
-
return `UPDATE ${target} SET ${assignments}${output}${fromClause}${joins}${whereClause}`;
|
|
3433
|
-
}
|
|
3434
|
-
compileSelectCoreForMssql(ast, ctx) {
|
|
3435
|
-
const columns = ast.columns.map((c) => {
|
|
3436
|
-
const expr = c.type === "Column" ? `${this.quoteIdentifier(c.table)}.${this.quoteIdentifier(c.name)}` : this.compileOperand(c, ctx);
|
|
3437
|
-
if (c.alias) {
|
|
3438
|
-
if (c.alias.includes("(")) return c.alias;
|
|
3439
|
-
return `${expr} AS ${this.quoteIdentifier(c.alias)}`;
|
|
3440
|
-
}
|
|
3441
|
-
return expr;
|
|
3442
|
-
}).join(", ");
|
|
3443
|
-
const distinct = ast.distinct ? "DISTINCT " : "";
|
|
3444
|
-
const from = this.compileFrom(ast.from, ctx);
|
|
3445
|
-
const joins = ast.joins.map((j) => {
|
|
3446
|
-
const table = this.compileFrom(j.table, ctx);
|
|
3447
|
-
const cond = this.compileExpression(j.condition, ctx);
|
|
3448
|
-
return `${j.kind} JOIN ${table} ON ${cond}`;
|
|
3449
|
-
}).join(" ");
|
|
3450
|
-
const whereClause = this.compileWhere(ast.where, ctx);
|
|
3451
|
-
const groupBy = ast.groupBy && ast.groupBy.length > 0 ? " GROUP BY " + ast.groupBy.map((term) => this.compileOrderingTerm(term, ctx)).join(", ") : "";
|
|
3452
|
-
const having = ast.having ? ` HAVING ${this.compileExpression(ast.having, ctx)}` : "";
|
|
3453
|
-
const orderBy = this.compileOrderBy(ast, ctx);
|
|
3454
|
-
const pagination = this.compilePagination(ast, orderBy);
|
|
3455
|
-
if (pagination) {
|
|
3456
|
-
return `SELECT ${distinct}${columns} FROM ${from}${joins ? " " + joins : ""}${whereClause}${groupBy}${having}${pagination}`;
|
|
3457
|
-
}
|
|
3458
|
-
return `SELECT ${distinct}${columns} FROM ${from}${joins ? " " + joins : ""}${whereClause}${groupBy}${having}${orderBy}`;
|
|
3459
|
-
}
|
|
3460
|
-
compileOrderBy(ast, ctx) {
|
|
3461
|
-
return OrderByCompiler.compileOrderBy(
|
|
3462
|
-
ast,
|
|
3463
|
-
(term) => this.compileOrderingTerm(term, ctx),
|
|
3464
|
-
this.renderOrderByNulls.bind(this),
|
|
3465
|
-
this.renderOrderByCollation.bind(this)
|
|
3565
|
+
const where = ast.where ? ` WHERE ${this.services.compileExpression(ast.where, ctx)}` : "";
|
|
3566
|
+
const returning = this.output.compileOutput(
|
|
3567
|
+
ast.returning,
|
|
3568
|
+
"deleted",
|
|
3569
|
+
(id) => this.services.quoteIdentifier(id)
|
|
3466
3570
|
);
|
|
3571
|
+
return `DELETE ${this.services.quoteIdentifier(alias)}${returning} FROM ${target}${joins}${where}`;
|
|
3467
3572
|
}
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
orderClause = ast.distinct && ast.distinct.length > 0 ? " ORDER BY 1" : " ORDER BY (SELECT NULL)";
|
|
3476
|
-
}
|
|
3477
|
-
let pagination = `${orderClause} OFFSET ${off} ROWS`;
|
|
3478
|
-
if (hasLimit) {
|
|
3479
|
-
pagination += ` FETCH NEXT ${ast.limit} ROWS ONLY`;
|
|
3480
|
-
}
|
|
3481
|
-
return pagination;
|
|
3482
|
-
}
|
|
3483
|
-
supportsDmlReturningClause() {
|
|
3484
|
-
return true;
|
|
3485
|
-
}
|
|
3486
|
-
compileReturning(returning, _ctx) {
|
|
3487
|
-
void _ctx;
|
|
3488
|
-
return this.compileOutputClause(returning, "inserted");
|
|
3489
|
-
}
|
|
3490
|
-
compileOutputClause(returning, prefix) {
|
|
3491
|
-
if (!returning || returning.length === 0) return "";
|
|
3492
|
-
const columns = returning.map((column) => {
|
|
3493
|
-
const colName = this.quoteIdentifier(column.name);
|
|
3494
|
-
const alias = column.alias ? ` AS ${this.quoteIdentifier(column.alias)}` : "";
|
|
3495
|
-
return `${prefix}.${colName}${alias}`;
|
|
3496
|
-
}).join(", ");
|
|
3497
|
-
return ` OUTPUT ${columns}`;
|
|
3573
|
+
};
|
|
3574
|
+
|
|
3575
|
+
// src/core/dialect/mssql/insert-compiler.ts
|
|
3576
|
+
var MssqlInsertCompiler = class {
|
|
3577
|
+
constructor(services, sources) {
|
|
3578
|
+
this.services = services;
|
|
3579
|
+
this.sources = sources;
|
|
3498
3580
|
}
|
|
3499
|
-
|
|
3581
|
+
compile(ast, ctx) {
|
|
3500
3582
|
if (!ast.columns.length) {
|
|
3501
3583
|
throw new Error("INSERT queries must specify columns.");
|
|
3502
3584
|
}
|
|
3503
|
-
if (ast.onConflict)
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
const
|
|
3507
|
-
const
|
|
3508
|
-
|
|
3509
|
-
const source = this.compileInsertValues(ast, ctx);
|
|
3510
|
-
return `INSERT INTO ${table} (${columnList})${output} ${source}`;
|
|
3585
|
+
if (ast.onConflict) return this.compileMerge(ast, ctx);
|
|
3586
|
+
const table = this.sources.compileTableName(ast.into);
|
|
3587
|
+
const columns = ast.columns.map((column) => this.services.quoteIdentifier(column.name)).join(", ");
|
|
3588
|
+
const output = this.services.compileReturning(ast.returning, ctx);
|
|
3589
|
+
const source = this.compileInsertSource(ast, ctx);
|
|
3590
|
+
return `INSERT INTO ${table} (${columns})${output} ${source}`;
|
|
3511
3591
|
}
|
|
3512
|
-
|
|
3592
|
+
compileMerge(ast, ctx) {
|
|
3513
3593
|
const clause = ast.onConflict;
|
|
3514
3594
|
if (clause.target.constraint) {
|
|
3515
3595
|
throw new Error("MSSQL MERGE does not support conflict target by constraint name.");
|
|
3516
3596
|
}
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
const
|
|
3521
|
-
const
|
|
3597
|
+
if (!clause.target.columns.length) {
|
|
3598
|
+
throw new Error("MSSQL MERGE requires conflict columns for the ON clause.");
|
|
3599
|
+
}
|
|
3600
|
+
const table = this.sources.compileTableName(ast.into);
|
|
3601
|
+
const targetRef = this.services.quoteIdentifier(ast.into.alias ?? ast.into.name);
|
|
3602
|
+
const sourceAlias = this.services.quoteIdentifier("src");
|
|
3603
|
+
const sourceColumns = ast.columns.map((column) => this.services.quoteIdentifier(column.name)).join(", ");
|
|
3522
3604
|
const usingSource = this.compileMergeUsingSource(ast, ctx);
|
|
3523
|
-
const onClause = clause.target.columns.map(
|
|
3605
|
+
const onClause = clause.target.columns.map(
|
|
3606
|
+
(column) => `${targetRef}.${this.services.quoteIdentifier(column.name)} = ${sourceAlias}.${this.services.quoteIdentifier(column.name)}`
|
|
3607
|
+
).join(" AND ");
|
|
3524
3608
|
const branches = [];
|
|
3525
3609
|
if (clause.action.type === "DoUpdate") {
|
|
3526
3610
|
if (!clause.action.set.length) {
|
|
3527
3611
|
throw new Error("MSSQL MERGE WHEN MATCHED UPDATE requires at least one assignment.");
|
|
3528
3612
|
}
|
|
3529
3613
|
const assignments = clause.action.set.map((assignment) => {
|
|
3530
|
-
const target = `${targetRef}.${this.quoteIdentifier(assignment.column.name)}`;
|
|
3531
|
-
const value = this.compileOperand(assignment.value, ctx);
|
|
3614
|
+
const target = `${targetRef}.${this.services.quoteIdentifier(assignment.column.name)}`;
|
|
3615
|
+
const value = this.services.compileOperand(assignment.value, ctx);
|
|
3532
3616
|
return `${target} = ${value}`;
|
|
3533
3617
|
}).join(", ");
|
|
3534
|
-
const guard = clause.action.where ? ` AND ${this.compileExpression(clause.action.where, ctx)}` : "";
|
|
3618
|
+
const guard = clause.action.where ? ` AND ${this.services.compileExpression(clause.action.where, ctx)}` : "";
|
|
3535
3619
|
branches.push(`WHEN MATCHED${guard} THEN UPDATE SET ${assignments}`);
|
|
3536
3620
|
}
|
|
3537
|
-
const insertColumns = ast.columns.map((column) => this.quoteIdentifier(column.name)).join(", ");
|
|
3538
|
-
const insertValues = ast.columns.map((column) => `${sourceAlias}.${this.quoteIdentifier(column.name)}`).join(", ");
|
|
3621
|
+
const insertColumns = ast.columns.map((column) => this.services.quoteIdentifier(column.name)).join(", ");
|
|
3622
|
+
const insertValues = ast.columns.map((column) => `${sourceAlias}.${this.services.quoteIdentifier(column.name)}`).join(", ");
|
|
3539
3623
|
branches.push(`WHEN NOT MATCHED THEN INSERT (${insertColumns}) VALUES (${insertValues})`);
|
|
3540
|
-
const output = this.compileReturning(ast.returning, ctx);
|
|
3624
|
+
const output = this.services.compileReturning(ast.returning, ctx);
|
|
3541
3625
|
return `MERGE INTO ${table} USING ${usingSource} AS ${sourceAlias} (${sourceColumns}) ON ${onClause} ${branches.join(" ")}${output}`;
|
|
3542
3626
|
}
|
|
3543
3627
|
compileMergeUsingSource(ast, ctx) {
|
|
@@ -3545,38 +3629,146 @@ var SqlServerDialect = class extends SqlDialectBase {
|
|
|
3545
3629
|
if (!ast.source.rows.length) {
|
|
3546
3630
|
throw new Error("INSERT ... VALUES requires at least one row.");
|
|
3547
3631
|
}
|
|
3548
|
-
const rows = ast.source.rows.map((row) => `(${row.map((value) => this.compileOperand(value, ctx)).join(", ")})`).join(", ");
|
|
3632
|
+
const rows = ast.source.rows.map((row) => `(${row.map((value) => this.services.compileOperand(value, ctx)).join(", ")})`).join(", ");
|
|
3549
3633
|
return `(VALUES ${rows})`;
|
|
3550
3634
|
}
|
|
3551
|
-
const normalized = this.normalizeSelectAst(ast.source.query);
|
|
3552
|
-
const selectSql = this.
|
|
3635
|
+
const normalized = this.services.normalizeSelectAst(ast.source.query);
|
|
3636
|
+
const selectSql = this.sources.stripTrailingSemicolon(
|
|
3637
|
+
this.services.compileSelectAst(normalized, ctx)
|
|
3638
|
+
);
|
|
3553
3639
|
return `(${selectSql})`;
|
|
3554
3640
|
}
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
if (!source.rows.length) {
|
|
3641
|
+
compileInsertSource(ast, ctx) {
|
|
3642
|
+
if (ast.source.type === "InsertValues") {
|
|
3643
|
+
if (!ast.source.rows.length) {
|
|
3559
3644
|
throw new Error("INSERT ... VALUES requires at least one row.");
|
|
3560
3645
|
}
|
|
3561
|
-
const values = source.rows.map((row) => `(${row.map((value) => this.compileOperand(value, ctx)).join(", ")})`).join(", ");
|
|
3646
|
+
const values = ast.source.rows.map((row) => `(${row.map((value) => this.services.compileOperand(value, ctx)).join(", ")})`).join(", ");
|
|
3562
3647
|
return `VALUES ${values}`;
|
|
3563
3648
|
}
|
|
3564
|
-
const normalized = this.normalizeSelectAst(source.query);
|
|
3565
|
-
return this.compileSelectAst(normalized, ctx).trim();
|
|
3649
|
+
const normalized = this.services.normalizeSelectAst(ast.source.query);
|
|
3650
|
+
return this.services.compileSelectAst(normalized, ctx).trim();
|
|
3651
|
+
}
|
|
3652
|
+
};
|
|
3653
|
+
|
|
3654
|
+
// src/core/dialect/mssql/select-compiler.ts
|
|
3655
|
+
var MssqlSelectCompiler = class {
|
|
3656
|
+
constructor(services, sources) {
|
|
3657
|
+
this.services = services;
|
|
3658
|
+
this.sources = sources;
|
|
3659
|
+
}
|
|
3660
|
+
compile(ast, ctx) {
|
|
3661
|
+
const hasSetOps = !!(ast.setOps && ast.setOps.length);
|
|
3662
|
+
const ctes = this.compileCtes(ast, ctx);
|
|
3663
|
+
const baseAst = hasSetOps ? { ...ast, setOps: void 0, orderBy: void 0, limit: void 0, offset: void 0 } : ast;
|
|
3664
|
+
const baseSelect = this.compileCore(baseAst, ctx);
|
|
3665
|
+
if (!hasSetOps) return `${ctes}${baseSelect}`;
|
|
3666
|
+
const compound = ast.setOps.map((op) => `${op.operator} ${this.sources.wrapSetOperand(this.services.compileSelectAst(op.query, ctx))}`).join(" ");
|
|
3667
|
+
const orderBy = this.compileOrderBy(ast, ctx);
|
|
3668
|
+
const pagination = this.compilePagination(ast, orderBy);
|
|
3669
|
+
const combined = `${this.sources.wrapSetOperand(baseSelect)} ${compound}`;
|
|
3670
|
+
return `${ctes}${combined}${pagination || orderBy}`;
|
|
3671
|
+
}
|
|
3672
|
+
compileCore(ast, ctx) {
|
|
3673
|
+
const columns = ast.columns.map((column) => {
|
|
3674
|
+
const expr = column.type === "Column" ? `${this.services.quoteIdentifier(column.table)}.${this.services.quoteIdentifier(column.name)}` : this.services.compileOperand(column, ctx);
|
|
3675
|
+
if (!column.alias) return expr;
|
|
3676
|
+
if (column.alias.includes("(")) return column.alias;
|
|
3677
|
+
return `${expr} AS ${this.services.quoteIdentifier(column.alias)}`;
|
|
3678
|
+
}).join(", ");
|
|
3679
|
+
const distinct = ast.distinct ? "DISTINCT " : "";
|
|
3680
|
+
const from = this.sources.compileFrom(ast.from, ctx);
|
|
3681
|
+
const joins = ast.joins.map((join) => {
|
|
3682
|
+
const table = this.sources.compileFrom(join.table, ctx);
|
|
3683
|
+
const condition = this.services.compileExpression(join.condition, ctx);
|
|
3684
|
+
return `${join.kind} JOIN ${table} ON ${condition}`;
|
|
3685
|
+
}).join(" ");
|
|
3686
|
+
const where = ast.where ? ` WHERE ${this.services.compileExpression(ast.where, ctx)}` : "";
|
|
3687
|
+
const groupBy = ast.groupBy && ast.groupBy.length > 0 ? ` GROUP BY ${ast.groupBy.map((term) => this.services.compileOrderingTerm(term, ctx)).join(", ")}` : "";
|
|
3688
|
+
const having = ast.having ? ` HAVING ${this.services.compileExpression(ast.having, ctx)}` : "";
|
|
3689
|
+
const orderBy = this.compileOrderBy(ast, ctx);
|
|
3690
|
+
const pagination = this.compilePagination(ast, orderBy);
|
|
3691
|
+
if (pagination) {
|
|
3692
|
+
return `SELECT ${distinct}${columns} FROM ${from}${joins ? ` ${joins}` : ""}${where}${groupBy}${having}${pagination}`;
|
|
3693
|
+
}
|
|
3694
|
+
return `SELECT ${distinct}${columns} FROM ${from}${joins ? ` ${joins}` : ""}${where}${groupBy}${having}${orderBy}`;
|
|
3695
|
+
}
|
|
3696
|
+
compileOrderBy(ast, ctx) {
|
|
3697
|
+
return OrderByCompiler.compileOrderBy(
|
|
3698
|
+
ast,
|
|
3699
|
+
(term) => this.services.compileOrderingTerm(term, ctx),
|
|
3700
|
+
(order) => this.services.renderOrderByNulls(order),
|
|
3701
|
+
(order) => this.services.renderOrderByCollation(order)
|
|
3702
|
+
);
|
|
3703
|
+
}
|
|
3704
|
+
compilePagination(ast, orderBy) {
|
|
3705
|
+
const hasLimit = ast.limit !== void 0;
|
|
3706
|
+
const hasOffset = ast.offset !== void 0;
|
|
3707
|
+
if (!hasLimit && !hasOffset) return "";
|
|
3708
|
+
const offset = ast.offset ?? 0;
|
|
3709
|
+
let orderClause = orderBy;
|
|
3710
|
+
if (!orderClause) {
|
|
3711
|
+
orderClause = ast.distinct && ast.distinct.length > 0 ? " ORDER BY 1" : " ORDER BY (SELECT NULL)";
|
|
3712
|
+
}
|
|
3713
|
+
let pagination = `${orderClause} OFFSET ${offset} ROWS`;
|
|
3714
|
+
if (hasLimit) pagination += ` FETCH NEXT ${ast.limit} ROWS ONLY`;
|
|
3715
|
+
return pagination;
|
|
3566
3716
|
}
|
|
3567
3717
|
compileCtes(ast, ctx) {
|
|
3568
3718
|
if (!ast.ctes || ast.ctes.length === 0) return "";
|
|
3569
|
-
const
|
|
3570
|
-
const name = this.quoteIdentifier(cte.name);
|
|
3571
|
-
const
|
|
3572
|
-
const query = this.
|
|
3573
|
-
|
|
3719
|
+
const definitions = ast.ctes.map((cte) => {
|
|
3720
|
+
const name = this.services.quoteIdentifier(cte.name);
|
|
3721
|
+
const columns = cte.columns ? `(${cte.columns.map((column) => this.services.quoteIdentifier(column)).join(", ")})` : "";
|
|
3722
|
+
const query = this.sources.stripTrailingSemicolon(
|
|
3723
|
+
this.services.compileSelectAst(this.services.normalizeSelectAst(cte.query), ctx)
|
|
3724
|
+
);
|
|
3725
|
+
return `${name}${columns} AS (${query})`;
|
|
3574
3726
|
}).join(", ");
|
|
3575
|
-
return `WITH ${
|
|
3727
|
+
return `WITH ${definitions} `;
|
|
3728
|
+
}
|
|
3729
|
+
};
|
|
3730
|
+
|
|
3731
|
+
// src/core/dialect/mssql/update-compiler.ts
|
|
3732
|
+
var MssqlUpdateCompiler = class {
|
|
3733
|
+
constructor(services, sources) {
|
|
3734
|
+
this.services = services;
|
|
3735
|
+
this.sources = sources;
|
|
3736
|
+
this.standardUpdate = new StandardUpdateCompiler(services, sources);
|
|
3737
|
+
}
|
|
3738
|
+
standardUpdate;
|
|
3739
|
+
compile(ast, ctx) {
|
|
3740
|
+
const target = this.sources.compileTableReference(ast.table);
|
|
3741
|
+
const assignments = this.standardUpdate.compileAssignments(ast.set, ast.table, ctx);
|
|
3742
|
+
const output = this.services.compileReturning(ast.returning, ctx);
|
|
3743
|
+
const from = ast.from ? ` FROM ${this.sources.compileFrom(ast.from, ctx)}` : "";
|
|
3744
|
+
const joins = ast.joins ? ast.joins.map((join) => {
|
|
3745
|
+
const table = this.sources.compileFrom(join.table, ctx);
|
|
3746
|
+
const condition = this.services.compileExpression(join.condition, ctx);
|
|
3747
|
+
return ` ${join.kind} JOIN ${table} ON ${condition}`;
|
|
3748
|
+
}).join("") : "";
|
|
3749
|
+
const where = ast.where ? ` WHERE ${this.services.compileExpression(ast.where, ctx)}` : "";
|
|
3750
|
+
return `UPDATE ${target} SET ${assignments}${output}${from}${joins}${where}`;
|
|
3751
|
+
}
|
|
3752
|
+
};
|
|
3753
|
+
|
|
3754
|
+
// src/core/dialect/mssql/compiler-factory.ts
|
|
3755
|
+
var createMssqlCompilerSet = ({ services, sources }) => ({
|
|
3756
|
+
select: new MssqlSelectCompiler(services, sources),
|
|
3757
|
+
insert: new MssqlInsertCompiler(services, sources),
|
|
3758
|
+
update: new MssqlUpdateCompiler(services, sources),
|
|
3759
|
+
delete: new MssqlDeleteCompiler(services, sources)
|
|
3760
|
+
});
|
|
3761
|
+
|
|
3762
|
+
// src/core/dialect/mssql/procedure-compiler.ts
|
|
3763
|
+
var sanitizeVariableSuffix2 = (value) => value.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
3764
|
+
var toProcedureParamReference = (value) => value.startsWith("@") ? value : `@${value}`;
|
|
3765
|
+
var MssqlProcedureCompiler = class {
|
|
3766
|
+
constructor(services) {
|
|
3767
|
+
this.services = services;
|
|
3576
3768
|
}
|
|
3577
3769
|
compileProcedureCall(ast) {
|
|
3578
|
-
const ctx = this.createCompilerContext();
|
|
3579
|
-
const qualifiedName = ast.ref.schema ? `${this.quoteIdentifier(ast.ref.schema)}.${this.quoteIdentifier(ast.ref.name)}` : this.quoteIdentifier(ast.ref.name);
|
|
3770
|
+
const ctx = this.services.createCompilerContext();
|
|
3771
|
+
const qualifiedName = ast.ref.schema ? `${this.services.quoteIdentifier(ast.ref.schema)}.${this.services.quoteIdentifier(ast.ref.name)}` : this.services.quoteIdentifier(ast.ref.name);
|
|
3580
3772
|
const declarations = [];
|
|
3581
3773
|
const assignments = [];
|
|
3582
3774
|
const execArgs = [];
|
|
@@ -3587,7 +3779,7 @@ var SqlServerDialect = class extends SqlDialectBase {
|
|
|
3587
3779
|
if (!param.value) {
|
|
3588
3780
|
throw new Error(`Procedure parameter "${param.name}" requires a value for direction "in".`);
|
|
3589
3781
|
}
|
|
3590
|
-
execArgs.push(`${targetParam} = ${this.compileOperand(param.value, ctx)}`);
|
|
3782
|
+
execArgs.push(`${targetParam} = ${this.services.compileOperand(param.value, ctx)}`);
|
|
3591
3783
|
return;
|
|
3592
3784
|
}
|
|
3593
3785
|
if (!param.dbType) {
|
|
@@ -3602,7 +3794,7 @@ var SqlServerDialect = class extends SqlDialectBase {
|
|
|
3602
3794
|
if (!param.value) {
|
|
3603
3795
|
throw new Error(`Procedure parameter "${param.name}" requires a value for direction "inout".`);
|
|
3604
3796
|
}
|
|
3605
|
-
assignments.push(`SET ${variable} = ${this.compileOperand(param.value, ctx)};`);
|
|
3797
|
+
assignments.push(`SET ${variable} = ${this.services.compileOperand(param.value, ctx)};`);
|
|
3606
3798
|
}
|
|
3607
3799
|
execArgs.push(`${targetParam} = ${variable} OUTPUT`);
|
|
3608
3800
|
outVars.push({ variable, name: param.name });
|
|
@@ -3613,7 +3805,7 @@ var SqlServerDialect = class extends SqlDialectBase {
|
|
|
3613
3805
|
const argsSql = execArgs.length ? ` ${execArgs.join(", ")}` : "";
|
|
3614
3806
|
statements.push(`EXEC ${qualifiedName}${argsSql};`);
|
|
3615
3807
|
if (outVars.length) {
|
|
3616
|
-
const selectOut = outVars.map(({ variable, name }) => `${variable} AS ${this.quoteIdentifier(name)}`).join(", ");
|
|
3808
|
+
const selectOut = outVars.map(({ variable, name }) => `${variable} AS ${this.services.quoteIdentifier(name)}`).join(", ");
|
|
3617
3809
|
statements.push(`SELECT ${selectOut};`);
|
|
3618
3810
|
}
|
|
3619
3811
|
return {
|
|
@@ -3627,6 +3819,38 @@ var SqlServerDialect = class extends SqlDialectBase {
|
|
|
3627
3819
|
}
|
|
3628
3820
|
};
|
|
3629
3821
|
|
|
3822
|
+
// src/core/dialect/mssql/index.ts
|
|
3823
|
+
var SqlServerDialect = class extends SqlDialectBase {
|
|
3824
|
+
dialect = "mssql";
|
|
3825
|
+
procedureCompiler;
|
|
3826
|
+
constructor() {
|
|
3827
|
+
super({
|
|
3828
|
+
functionStrategy: new MssqlFunctionStrategy(),
|
|
3829
|
+
returningStrategy: new MssqlOutputStrategy(),
|
|
3830
|
+
compilerFactory: createMssqlCompilerSet,
|
|
3831
|
+
supportsDmlReturning: true
|
|
3832
|
+
});
|
|
3833
|
+
this.procedureCompiler = new MssqlProcedureCompiler({
|
|
3834
|
+
quoteIdentifier: (id) => this.quoteIdentifier(id),
|
|
3835
|
+
createCompilerContext: () => this.createCompilerContext(),
|
|
3836
|
+
compileOperand: (node, ctx) => this.compileOperand(node, ctx)
|
|
3837
|
+
});
|
|
3838
|
+
}
|
|
3839
|
+
quoteIdentifier(id) {
|
|
3840
|
+
return `[${id}]`;
|
|
3841
|
+
}
|
|
3842
|
+
compileJsonPath(node) {
|
|
3843
|
+
const column = `${this.quoteIdentifier(node.column.table)}.${this.quoteIdentifier(node.column.name)}`;
|
|
3844
|
+
return `JSON_VALUE(${column}, '${node.path}')`;
|
|
3845
|
+
}
|
|
3846
|
+
formatPlaceholder(index) {
|
|
3847
|
+
return `@p${index}`;
|
|
3848
|
+
}
|
|
3849
|
+
compileProcedureCall(ast) {
|
|
3850
|
+
return this.procedureCompiler.compileProcedureCall(ast);
|
|
3851
|
+
}
|
|
3852
|
+
};
|
|
3853
|
+
|
|
3630
3854
|
// src/core/dialect/dialect-factory.ts
|
|
3631
3855
|
var DialectFactory = class {
|
|
3632
3856
|
static registry = /* @__PURE__ */ new Map();
|
|
@@ -22105,13 +22329,26 @@ async function bulkUpsert(session, table, rows, options = {}) {
|
|
|
22105
22329
|
MorphMany,
|
|
22106
22330
|
MorphOne,
|
|
22107
22331
|
MorphTo,
|
|
22332
|
+
MssqlDeleteCompiler,
|
|
22333
|
+
MssqlInsertCompiler,
|
|
22334
|
+
MssqlOutputStrategy,
|
|
22335
|
+
MssqlProcedureCompiler,
|
|
22336
|
+
MssqlSelectCompiler,
|
|
22337
|
+
MssqlUpdateCompiler,
|
|
22108
22338
|
MySqlDialect,
|
|
22339
|
+
MySqlProcedureCompiler,
|
|
22340
|
+
MySqlUpsertStrategy,
|
|
22109
22341
|
NestedSetStrategy,
|
|
22342
|
+
NoReturningStrategy,
|
|
22343
|
+
NoUpsertStrategy,
|
|
22110
22344
|
Orm,
|
|
22111
22345
|
OrmSession,
|
|
22112
22346
|
Pattern,
|
|
22113
22347
|
Pool,
|
|
22114
22348
|
PostgresDialect,
|
|
22349
|
+
PostgresProcedureCompiler,
|
|
22350
|
+
PostgresReturningStrategy,
|
|
22351
|
+
PostgresUpsertStrategy,
|
|
22115
22352
|
PrimaryKey,
|
|
22116
22353
|
ProcedureCallBuilder,
|
|
22117
22354
|
PrototypeMaterializationStrategy,
|
|
@@ -22120,8 +22357,19 @@ async function bulkUpsert(session, table, rows, options = {}) {
|
|
|
22120
22357
|
RelationKinds,
|
|
22121
22358
|
STANDARD_COLUMN_TYPES,
|
|
22122
22359
|
SelectQueryBuilder,
|
|
22360
|
+
SqlDialectBase,
|
|
22123
22361
|
SqlServerDialect,
|
|
22124
22362
|
SqliteDialect,
|
|
22363
|
+
SqliteReturningStrategy,
|
|
22364
|
+
SqliteUpsertStrategy,
|
|
22365
|
+
StandardDeleteCompiler,
|
|
22366
|
+
StandardInsertCompiler,
|
|
22367
|
+
StandardLimitOffsetPagination,
|
|
22368
|
+
StandardReturningStrategy,
|
|
22369
|
+
StandardSelectCompiler,
|
|
22370
|
+
StandardSqlSourceCompiler,
|
|
22371
|
+
StandardTableFunctionStrategy,
|
|
22372
|
+
StandardUpdateCompiler,
|
|
22125
22373
|
StringTypeStrategy,
|
|
22126
22374
|
TagIndex,
|
|
22127
22375
|
Title,
|
|
@@ -22208,6 +22456,7 @@ async function bulkUpsert(session, table, rows, options = {}) {
|
|
|
22208
22456
|
createEntityFromRow,
|
|
22209
22457
|
createEntityProxy,
|
|
22210
22458
|
createExecutorFromQueryRunner,
|
|
22459
|
+
createMssqlCompilerSet,
|
|
22211
22460
|
createMssqlExecutor,
|
|
22212
22461
|
createMysqlExecutor,
|
|
22213
22462
|
createPooledExecutorFactory,
|