@undefineds.co/drizzle-solid 0.2.11 → 0.2.13
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/README.md +255 -439
- package/dist/core/expressions.d.ts +4 -0
- package/dist/core/expressions.d.ts.map +1 -1
- package/dist/core/expressions.js +8 -1
- package/dist/core/expressions.js.map +1 -1
- package/dist/core/order-by.d.ts +9 -0
- package/dist/core/order-by.d.ts.map +1 -0
- package/dist/core/order-by.js +20 -0
- package/dist/core/order-by.js.map +1 -0
- package/dist/core/pod-database.d.ts +6 -0
- package/dist/core/pod-database.d.ts.map +1 -1
- package/dist/core/pod-database.js +121 -31
- package/dist/core/pod-database.js.map +1 -1
- package/dist/core/pod-dialect.d.ts +10 -1
- package/dist/core/pod-dialect.d.ts.map +1 -1
- package/dist/core/pod-dialect.js +81 -2
- package/dist/core/pod-dialect.js.map +1 -1
- package/dist/core/query-builders/delete-query-builder.d.ts +7 -12
- package/dist/core/query-builders/delete-query-builder.d.ts.map +1 -1
- package/dist/core/query-builders/delete-query-builder.js +47 -20
- package/dist/core/query-builders/delete-query-builder.js.map +1 -1
- package/dist/core/query-builders/helpers.d.ts +7 -0
- package/dist/core/query-builders/helpers.d.ts.map +1 -1
- package/dist/core/query-builders/helpers.js +169 -0
- package/dist/core/query-builders/helpers.js.map +1 -1
- package/dist/core/query-builders/insert-query-builder.d.ts +10 -3
- package/dist/core/query-builders/insert-query-builder.d.ts.map +1 -1
- package/dist/core/query-builders/insert-query-builder.js +50 -6
- package/dist/core/query-builders/insert-query-builder.js.map +1 -1
- package/dist/core/query-builders/select-query-builder.d.ts +29 -1
- package/dist/core/query-builders/select-query-builder.d.ts.map +1 -1
- package/dist/core/query-builders/select-query-builder.js +405 -85
- package/dist/core/query-builders/select-query-builder.js.map +1 -1
- package/dist/core/query-builders/types.d.ts +5 -3
- package/dist/core/query-builders/types.d.ts.map +1 -1
- package/dist/core/query-builders/update-query-builder.d.ts +8 -12
- package/dist/core/query-builders/update-query-builder.d.ts.map +1 -1
- package/dist/core/query-builders/update-query-builder.js +63 -21
- package/dist/core/query-builders/update-query-builder.js.map +1 -1
- package/dist/core/query-conditions.d.ts +17 -16
- package/dist/core/query-conditions.d.ts.map +1 -1
- package/dist/core/query-conditions.js.map +1 -1
- package/dist/core/resource-resolver/base-resolver.d.ts +8 -4
- package/dist/core/resource-resolver/base-resolver.d.ts.map +1 -1
- package/dist/core/resource-resolver/base-resolver.js +39 -36
- package/dist/core/resource-resolver/base-resolver.js.map +1 -1
- package/dist/core/resource-resolver/document-resolver.d.ts.map +1 -1
- package/dist/core/resource-resolver/document-resolver.js +75 -78
- package/dist/core/resource-resolver/document-resolver.js.map +1 -1
- package/dist/core/schema/pod-table.d.ts +1 -0
- package/dist/core/schema/pod-table.d.ts.map +1 -1
- package/dist/core/schema/pod-table.js +67 -0
- package/dist/core/schema/pod-table.js.map +1 -1
- package/dist/core/select-plan.d.ts +6 -3
- package/dist/core/select-plan.d.ts.map +1 -1
- package/dist/core/sparql/builder/expression-builder.d.ts +10 -0
- package/dist/core/sparql/builder/expression-builder.d.ts.map +1 -1
- package/dist/core/sparql/builder/expression-builder.js +27 -4
- package/dist/core/sparql/builder/expression-builder.js.map +1 -1
- package/dist/core/sparql/builder/select-builder.d.ts +9 -0
- package/dist/core/sparql/builder/select-builder.d.ts.map +1 -1
- package/dist/core/sparql/builder/select-builder.js +147 -2
- package/dist/core/sparql/builder/select-builder.js.map +1 -1
- package/dist/core/utils/debug-logger.d.ts +19 -0
- package/dist/core/utils/debug-logger.d.ts.map +1 -0
- package/dist/core/utils/debug-logger.js +59 -0
- package/dist/core/utils/debug-logger.js.map +1 -0
- package/dist/driver.d.ts +4 -0
- package/dist/driver.d.ts.map +1 -1
- package/dist/driver.js +1 -0
- package/dist/driver.js.map +1 -1
- package/dist/esm/core/expressions.d.ts +4 -0
- package/dist/esm/core/expressions.d.ts.map +1 -1
- package/dist/esm/core/expressions.js +6 -0
- package/dist/esm/core/expressions.js.map +1 -1
- package/dist/esm/core/order-by.d.ts +9 -0
- package/dist/esm/core/order-by.d.ts.map +1 -0
- package/dist/esm/core/order-by.js +15 -0
- package/dist/esm/core/order-by.js.map +1 -0
- package/dist/esm/core/pod-database.d.ts +6 -0
- package/dist/esm/core/pod-database.d.ts.map +1 -1
- package/dist/esm/core/pod-database.js +122 -32
- package/dist/esm/core/pod-database.js.map +1 -1
- package/dist/esm/core/pod-dialect.d.ts +10 -1
- package/dist/esm/core/pod-dialect.d.ts.map +1 -1
- package/dist/esm/core/pod-dialect.js +81 -2
- package/dist/esm/core/pod-dialect.js.map +1 -1
- package/dist/esm/core/query-builders/delete-query-builder.d.ts +7 -12
- package/dist/esm/core/query-builders/delete-query-builder.d.ts.map +1 -1
- package/dist/esm/core/query-builders/delete-query-builder.js +48 -21
- package/dist/esm/core/query-builders/delete-query-builder.js.map +1 -1
- package/dist/esm/core/query-builders/helpers.d.ts +7 -0
- package/dist/esm/core/query-builders/helpers.d.ts.map +1 -1
- package/dist/esm/core/query-builders/helpers.js +164 -0
- package/dist/esm/core/query-builders/helpers.js.map +1 -1
- package/dist/esm/core/query-builders/insert-query-builder.d.ts +10 -3
- package/dist/esm/core/query-builders/insert-query-builder.d.ts.map +1 -1
- package/dist/esm/core/query-builders/insert-query-builder.js +50 -6
- package/dist/esm/core/query-builders/insert-query-builder.js.map +1 -1
- package/dist/esm/core/query-builders/select-query-builder.d.ts +29 -1
- package/dist/esm/core/query-builders/select-query-builder.d.ts.map +1 -1
- package/dist/esm/core/query-builders/select-query-builder.js +407 -87
- package/dist/esm/core/query-builders/select-query-builder.js.map +1 -1
- package/dist/esm/core/query-builders/types.d.ts +5 -3
- package/dist/esm/core/query-builders/types.d.ts.map +1 -1
- package/dist/esm/core/query-builders/update-query-builder.d.ts +8 -12
- package/dist/esm/core/query-builders/update-query-builder.d.ts.map +1 -1
- package/dist/esm/core/query-builders/update-query-builder.js +64 -22
- package/dist/esm/core/query-builders/update-query-builder.js.map +1 -1
- package/dist/esm/core/query-conditions.d.ts +17 -16
- package/dist/esm/core/query-conditions.d.ts.map +1 -1
- package/dist/esm/core/query-conditions.js.map +1 -1
- package/dist/esm/core/resource-resolver/base-resolver.d.ts +8 -4
- package/dist/esm/core/resource-resolver/base-resolver.d.ts.map +1 -1
- package/dist/esm/core/resource-resolver/base-resolver.js +39 -36
- package/dist/esm/core/resource-resolver/base-resolver.js.map +1 -1
- package/dist/esm/core/resource-resolver/document-resolver.d.ts.map +1 -1
- package/dist/esm/core/resource-resolver/document-resolver.js +75 -78
- package/dist/esm/core/resource-resolver/document-resolver.js.map +1 -1
- package/dist/esm/core/schema/pod-table.d.ts +1 -0
- package/dist/esm/core/schema/pod-table.d.ts.map +1 -1
- package/dist/esm/core/schema/pod-table.js +66 -0
- package/dist/esm/core/schema/pod-table.js.map +1 -1
- package/dist/esm/core/select-plan.d.ts +6 -3
- package/dist/esm/core/select-plan.d.ts.map +1 -1
- package/dist/esm/core/sparql/builder/expression-builder.d.ts +10 -0
- package/dist/esm/core/sparql/builder/expression-builder.d.ts.map +1 -1
- package/dist/esm/core/sparql/builder/expression-builder.js +27 -4
- package/dist/esm/core/sparql/builder/expression-builder.js.map +1 -1
- package/dist/esm/core/sparql/builder/select-builder.d.ts +9 -0
- package/dist/esm/core/sparql/builder/select-builder.d.ts.map +1 -1
- package/dist/esm/core/sparql/builder/select-builder.js +148 -3
- package/dist/esm/core/sparql/builder/select-builder.js.map +1 -1
- package/dist/esm/core/utils/debug-logger.d.ts +19 -0
- package/dist/esm/core/utils/debug-logger.d.ts.map +1 -0
- package/dist/esm/core/utils/debug-logger.js +53 -0
- package/dist/esm/core/utils/debug-logger.js.map +1 -0
- package/dist/esm/driver.d.ts +4 -0
- package/dist/esm/driver.d.ts.map +1 -1
- package/dist/esm/driver.js +1 -0
- package/dist/esm/driver.js.map +1 -1
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +3 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/package.json +17 -6
|
@@ -8,6 +8,8 @@ const query_conditions_1 = require("../query-conditions");
|
|
|
8
8
|
const aggregates_1 = require("../aggregates");
|
|
9
9
|
const helpers_1 = require("./helpers");
|
|
10
10
|
const uri_1 = require("../uri");
|
|
11
|
+
const order_by_1 = require("../order-by");
|
|
12
|
+
const expressions_1 = require("../expressions");
|
|
11
13
|
class SelectQueryBuilder {
|
|
12
14
|
constructor(session, fields) {
|
|
13
15
|
this.session = session;
|
|
@@ -132,17 +134,35 @@ class SelectQueryBuilder {
|
|
|
132
134
|
fullJoin(table, condition) {
|
|
133
135
|
return this.addJoin('fullJoin', table, condition);
|
|
134
136
|
}
|
|
137
|
+
crossJoin(table) {
|
|
138
|
+
return this.addJoin('crossJoin', table);
|
|
139
|
+
}
|
|
135
140
|
groupBy(...fields) {
|
|
136
141
|
const refs = fields.map((field) => this.resolveColumnReference(field));
|
|
137
142
|
this.groupByColumns.push(...refs);
|
|
138
143
|
return this;
|
|
139
144
|
}
|
|
145
|
+
having(condition) {
|
|
146
|
+
this.havingCondition = typeof condition === 'function'
|
|
147
|
+
? condition(this.createSelectedFieldAliases())
|
|
148
|
+
: condition;
|
|
149
|
+
return this;
|
|
150
|
+
}
|
|
151
|
+
createSelectedFieldAliases() {
|
|
152
|
+
const aliases = {};
|
|
153
|
+
for (const alias of Object.keys(this.selectedFields ?? {})) {
|
|
154
|
+
aliases[alias] = new expressions_1.SelectionAliasExpression(alias);
|
|
155
|
+
}
|
|
156
|
+
return aliases;
|
|
157
|
+
}
|
|
140
158
|
addJoin(type, table, condition) {
|
|
141
159
|
if (type === 'rightJoin' || type === 'fullJoin') {
|
|
142
160
|
throw new Error(`${type} is not yet supported in Solid dialect`);
|
|
143
161
|
}
|
|
144
162
|
const alias = this.ensureAliasForTable(table);
|
|
145
|
-
const resolvedConditions =
|
|
163
|
+
const resolvedConditions = type === 'crossJoin'
|
|
164
|
+
? undefined
|
|
165
|
+
: this.resolveJoinConditions(condition, alias);
|
|
146
166
|
this.joins.push({
|
|
147
167
|
type,
|
|
148
168
|
table,
|
|
@@ -167,8 +187,11 @@ class SelectQueryBuilder {
|
|
|
167
187
|
return alias;
|
|
168
188
|
}
|
|
169
189
|
resolveJoinConditions(condition, joinAlias) {
|
|
190
|
+
if (this.isQueryCondition(condition)) {
|
|
191
|
+
return this.resolveJoinConditionExpression(condition, joinAlias);
|
|
192
|
+
}
|
|
170
193
|
if (!condition || typeof condition !== 'object') {
|
|
171
|
-
throw new Error('JOIN condition must be an
|
|
194
|
+
throw new Error('JOIN condition must be an equality expression or column mapping');
|
|
172
195
|
}
|
|
173
196
|
const entries = Object.entries(condition);
|
|
174
197
|
if (entries.length === 0) {
|
|
@@ -183,6 +206,44 @@ class SelectQueryBuilder {
|
|
|
183
206
|
return { left: leftRef, right: rightRef };
|
|
184
207
|
});
|
|
185
208
|
}
|
|
209
|
+
resolveJoinConditionExpression(condition, joinAlias) {
|
|
210
|
+
if (condition.type === 'logical_expr') {
|
|
211
|
+
const operator = (condition.operator ?? '').toUpperCase();
|
|
212
|
+
const expressions = (condition.expressions ?? []);
|
|
213
|
+
if (operator !== 'AND' || expressions.length === 0) {
|
|
214
|
+
throw new Error('JOIN condition only supports equality expressions combined with AND');
|
|
215
|
+
}
|
|
216
|
+
return expressions.flatMap((expression) => this.resolveJoinConditionExpression(expression, joinAlias));
|
|
217
|
+
}
|
|
218
|
+
if (condition.type !== 'binary_expr' || condition.operator !== '=') {
|
|
219
|
+
throw new Error('JOIN condition only supports equality expressions');
|
|
220
|
+
}
|
|
221
|
+
const leftRef = this.getConditionColumnReference(condition.left);
|
|
222
|
+
const rightRef = this.getConditionColumnReference(condition.right);
|
|
223
|
+
if (!leftRef || !rightRef) {
|
|
224
|
+
throw new Error('JOIN equality must compare two table columns');
|
|
225
|
+
}
|
|
226
|
+
if (leftRef.alias !== joinAlias && rightRef.alias !== joinAlias) {
|
|
227
|
+
throw new Error('JOIN condition must reference the joined table in at least one side');
|
|
228
|
+
}
|
|
229
|
+
return [{ left: leftRef, right: rightRef }];
|
|
230
|
+
}
|
|
231
|
+
getConditionColumnReference(field, fallbackAlias) {
|
|
232
|
+
if (field instanceof schema_1.PodColumnBase) {
|
|
233
|
+
return this.resolveColumnReference(field, fallbackAlias);
|
|
234
|
+
}
|
|
235
|
+
if (typeof field === 'string') {
|
|
236
|
+
if (field.includes('.')) {
|
|
237
|
+
return this.resolveColumnReference(field, fallbackAlias);
|
|
238
|
+
}
|
|
239
|
+
const alias = fallbackAlias ?? this.primaryAlias;
|
|
240
|
+
const table = alias ? this.aliasToTable.get(alias) : undefined;
|
|
241
|
+
if (table && field in (table.columns ?? {})) {
|
|
242
|
+
return this.resolveColumnReference(field, fallbackAlias);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return undefined;
|
|
246
|
+
}
|
|
186
247
|
resolveColumnReference(field, fallbackAlias) {
|
|
187
248
|
if (field instanceof schema_1.PodColumnBase) {
|
|
188
249
|
const table = field.table;
|
|
@@ -277,6 +338,7 @@ class SelectQueryBuilder {
|
|
|
277
338
|
joins: planJoins.length > 0 ? planJoins : undefined,
|
|
278
339
|
joinFilters: this.joinFilters.length > 0 ? [...this.joinFilters] : undefined,
|
|
279
340
|
groupBy: this.groupByColumns.length > 0 ? [...this.groupByColumns] : undefined,
|
|
341
|
+
having: this.havingCondition,
|
|
280
342
|
orderBy: this.orderByClauses.length > 0
|
|
281
343
|
? this.orderByClauses.map((clause) => ({
|
|
282
344
|
rawColumn: clause.column,
|
|
@@ -304,49 +366,115 @@ class SelectQueryBuilder {
|
|
|
304
366
|
this.offsetCount = count;
|
|
305
367
|
return this;
|
|
306
368
|
}
|
|
307
|
-
|
|
369
|
+
addOrderByClause(column, direction = 'asc') {
|
|
308
370
|
const columnName = typeof column === 'string' ? column : column.name;
|
|
309
371
|
if (!columnName) {
|
|
310
372
|
throw new Error('ORDER BY requires a valid column name');
|
|
311
373
|
}
|
|
312
374
|
this.orderByClauses.push({ column: columnName, direction });
|
|
375
|
+
}
|
|
376
|
+
orderBy(...args) {
|
|
377
|
+
if (args.length === 0) {
|
|
378
|
+
throw new Error('ORDER BY requires at least one column or expression');
|
|
379
|
+
}
|
|
380
|
+
if (args.length === 2
|
|
381
|
+
&& (args[0] instanceof schema_1.PodColumnBase || typeof args[0] === 'string')
|
|
382
|
+
&& (args[1] === 'asc' || args[1] === 'desc')) {
|
|
383
|
+
this.addOrderByClause(args[0], args[1]);
|
|
384
|
+
return this;
|
|
385
|
+
}
|
|
386
|
+
for (const arg of args) {
|
|
387
|
+
if ((0, order_by_1.isOrderByExpression)(arg)) {
|
|
388
|
+
this.addOrderByClause(arg.column, arg.direction);
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
if (arg instanceof schema_1.PodColumnBase || typeof arg === 'string') {
|
|
392
|
+
this.addOrderByClause(arg, 'asc');
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
throw new Error('ORDER BY received an unsupported argument');
|
|
396
|
+
}
|
|
313
397
|
return this;
|
|
314
398
|
}
|
|
315
399
|
distinct(enable = true) {
|
|
316
400
|
this.isDistinct = enable;
|
|
317
401
|
return this;
|
|
318
402
|
}
|
|
403
|
+
buildSPARQLQuery(methodName = 'toSPARQL()') {
|
|
404
|
+
if (this.sql) {
|
|
405
|
+
const query = this.sql.queryChunks.join('');
|
|
406
|
+
const type = (0, helpers_1.inferSPARQLQueryType)(query);
|
|
407
|
+
if (!type) {
|
|
408
|
+
throw new Error(`${methodName} could not infer SPARQL query type from raw AST input`);
|
|
409
|
+
}
|
|
410
|
+
return { type, query, prefixes: {} };
|
|
411
|
+
}
|
|
412
|
+
if (!this.selectedTable) {
|
|
413
|
+
throw new Error('No table specified for SELECT query');
|
|
414
|
+
}
|
|
415
|
+
if (this.joins.length > 0) {
|
|
416
|
+
throw new Error(`${methodName} is not yet supported for JOIN queries in Solid dialect`);
|
|
417
|
+
}
|
|
418
|
+
if (this.shouldUseProjectionFallback()) {
|
|
419
|
+
throw new Error(`${methodName} does not support structured selections in Solid dialect`);
|
|
420
|
+
}
|
|
421
|
+
const converter = this.session.getDialect().getSPARQLConverter?.();
|
|
422
|
+
if (!converter) {
|
|
423
|
+
throw new Error(`${methodName} requires dialect SPARQL converter support`);
|
|
424
|
+
}
|
|
425
|
+
return converter.convertSelectPlan(this.toIR());
|
|
426
|
+
}
|
|
427
|
+
toSPARQL() {
|
|
428
|
+
return this.buildSPARQLQuery('toSPARQL()');
|
|
429
|
+
}
|
|
430
|
+
toSparql() {
|
|
431
|
+
return this.toSPARQL();
|
|
432
|
+
}
|
|
319
433
|
async execute() {
|
|
320
434
|
if (!this.selectedTable) {
|
|
321
435
|
throw new Error('No table specified for SELECT query');
|
|
322
436
|
}
|
|
437
|
+
if (this.limitCount === 0) {
|
|
438
|
+
return [];
|
|
439
|
+
}
|
|
323
440
|
if (this.sql) {
|
|
324
441
|
return await this.session.executeSql(this.sql, this.selectedTable);
|
|
325
442
|
}
|
|
326
443
|
else {
|
|
327
444
|
const plan = this.toIR();
|
|
328
445
|
const wherePayload = plan.conditionTree;
|
|
446
|
+
const hasJoins = this.joins.length > 0;
|
|
447
|
+
const useAggregateFallback = this.shouldUseAggregateFallback();
|
|
448
|
+
const useProjectionFallback = this.shouldUseProjectionFallback();
|
|
449
|
+
const shouldDeferQueryModifiers = hasJoins || useAggregateFallback;
|
|
450
|
+
if (hasJoins || useAggregateFallback || useProjectionFallback) {
|
|
451
|
+
plan.select = undefined;
|
|
452
|
+
plan.selectAll = true;
|
|
453
|
+
}
|
|
454
|
+
const executionPlan = shouldDeferQueryModifiers
|
|
455
|
+
? {
|
|
456
|
+
...plan,
|
|
457
|
+
limit: undefined,
|
|
458
|
+
offset: undefined,
|
|
459
|
+
orderBy: undefined,
|
|
460
|
+
...(useAggregateFallback ? { groupBy: undefined, having: undefined } : {}),
|
|
461
|
+
}
|
|
462
|
+
: plan;
|
|
329
463
|
const operation = {
|
|
330
464
|
type: 'select',
|
|
331
465
|
table: this.selectedTable,
|
|
332
466
|
where: wherePayload,
|
|
333
|
-
limit: this.limitCount,
|
|
334
|
-
offset: this.offsetCount,
|
|
335
|
-
orderBy: this.orderByClauses.length
|
|
467
|
+
limit: shouldDeferQueryModifiers ? undefined : this.limitCount,
|
|
468
|
+
offset: shouldDeferQueryModifiers ? undefined : this.offsetCount,
|
|
469
|
+
orderBy: shouldDeferQueryModifiers || this.orderByClauses.length === 0 ? undefined : this.orderByClauses,
|
|
336
470
|
distinct: this.isDistinct || undefined
|
|
337
471
|
};
|
|
338
|
-
|
|
339
|
-
const useAggregateFallback = this.shouldUseAggregateFallback();
|
|
340
|
-
if (hasJoins || useAggregateFallback) {
|
|
341
|
-
plan.select = undefined;
|
|
342
|
-
plan.selectAll = true;
|
|
343
|
-
}
|
|
344
|
-
operation.plan = plan;
|
|
472
|
+
operation.plan = executionPlan;
|
|
345
473
|
if (this.groupByColumns.length === 0 && this.hasMixedAggregateSelection()) {
|
|
346
474
|
throw new Error('Mixed aggregate and non-aggregate selections require groupBy columns');
|
|
347
475
|
}
|
|
348
476
|
let intermediateRows;
|
|
349
|
-
if (!hasJoins && !useAggregateFallback) {
|
|
477
|
+
if (!hasJoins && !useAggregateFallback && !useProjectionFallback) {
|
|
350
478
|
if (this.selectedFields) {
|
|
351
479
|
operation.select = this.selectedFields;
|
|
352
480
|
}
|
|
@@ -357,7 +485,7 @@ class SelectQueryBuilder {
|
|
|
357
485
|
if (hasJoins) {
|
|
358
486
|
operation.select = undefined;
|
|
359
487
|
}
|
|
360
|
-
else if (!useAggregateFallback) {
|
|
488
|
+
else if (!useAggregateFallback && !useProjectionFallback) {
|
|
361
489
|
operation.select = this.selectedFields;
|
|
362
490
|
}
|
|
363
491
|
else {
|
|
@@ -374,51 +502,141 @@ class SelectQueryBuilder {
|
|
|
374
502
|
}
|
|
375
503
|
}
|
|
376
504
|
if (useAggregateFallback) {
|
|
377
|
-
|
|
505
|
+
let aggregateRows = this.handleAggregateFallback(intermediateRows);
|
|
506
|
+
aggregateRows = this.applyHavingFilter(aggregateRows);
|
|
507
|
+
if (shouldDeferQueryModifiers) {
|
|
508
|
+
aggregateRows = this.applyDeferredOrderBy(aggregateRows);
|
|
509
|
+
aggregateRows = this.applyDeferredOffsetAndLimit(aggregateRows);
|
|
510
|
+
}
|
|
511
|
+
return aggregateRows;
|
|
378
512
|
}
|
|
379
513
|
let finalRows = intermediateRows;
|
|
380
514
|
if (!hasJoins) {
|
|
381
515
|
finalRows = this.mergeRowsBySubject(finalRows);
|
|
382
516
|
}
|
|
383
517
|
if (this.selectedTable) {
|
|
384
|
-
finalRows = await this.hydrateInlineColumns(finalRows, this.selectedTable);
|
|
518
|
+
finalRows = await this.hydrateInlineColumns(finalRows, this.selectedTable, !hasJoins);
|
|
385
519
|
// 处理引用字段:将 URI 转换回 ID
|
|
386
520
|
finalRows = this.resolveReferenceIds(finalRows, this.selectedTable);
|
|
387
521
|
}
|
|
522
|
+
if (hasJoins) {
|
|
523
|
+
finalRows = this.applyDeferredOrderBy(finalRows);
|
|
524
|
+
}
|
|
388
525
|
if (this.selectedFields) {
|
|
389
526
|
finalRows = finalRows.map((row) => this.projectSelectedRow(row));
|
|
390
527
|
}
|
|
391
|
-
finalRows = this.
|
|
528
|
+
finalRows = this.applyDistinctRows(finalRows);
|
|
529
|
+
if (!hasJoins) {
|
|
530
|
+
finalRows = this.mergeRowsBySubject(finalRows);
|
|
531
|
+
}
|
|
532
|
+
if (hasJoins) {
|
|
533
|
+
finalRows = this.applyDeferredOffsetAndLimit(finalRows);
|
|
534
|
+
}
|
|
392
535
|
return finalRows;
|
|
393
536
|
}
|
|
394
537
|
}
|
|
395
538
|
projectSelectedRow(row) {
|
|
396
|
-
const projected = {};
|
|
397
539
|
if (!this.selectedFields) {
|
|
398
540
|
return row;
|
|
399
541
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
542
|
+
return this.projectFieldMap(row, this.selectedFields);
|
|
543
|
+
}
|
|
544
|
+
projectFieldMap(row, fields, allowAliasFallback = true) {
|
|
545
|
+
const projected = {};
|
|
546
|
+
for (const [key, field] of Object.entries(fields)) {
|
|
547
|
+
projected[key] = this.projectFieldValue(row, key, field, allowAliasFallback);
|
|
548
|
+
}
|
|
549
|
+
return projected;
|
|
550
|
+
}
|
|
551
|
+
projectFieldValue(row, alias, field, allowAliasFallback = true) {
|
|
552
|
+
if ((0, aggregates_1.isAggregateExpression)(field)) {
|
|
553
|
+
return allowAliasFallback ? row[alias] : undefined;
|
|
554
|
+
}
|
|
555
|
+
if (field instanceof schema_1.PodTable) {
|
|
556
|
+
return this.projectTableValue(row, field);
|
|
557
|
+
}
|
|
558
|
+
if (this.isSelectFieldMap(field)) {
|
|
559
|
+
const aliases = this.collectSelectionAliases(field);
|
|
560
|
+
const isJoinedOnlySelection = aliases.size === 1 && !aliases.has(this.primaryAlias ?? '');
|
|
561
|
+
const projected = this.projectFieldMap(row, field, !isJoinedOnlySelection);
|
|
562
|
+
if (aliases.size === 1) {
|
|
563
|
+
const [targetAlias] = Array.from(aliases);
|
|
564
|
+
if (targetAlias && targetAlias !== this.primaryAlias && this.isProjectedValueEmpty(projected)) {
|
|
565
|
+
return null;
|
|
412
566
|
}
|
|
413
567
|
}
|
|
414
|
-
|
|
415
|
-
|
|
568
|
+
return projected;
|
|
569
|
+
}
|
|
570
|
+
for (const candidate of this.resolveFieldBindingCandidates(alias, field)) {
|
|
571
|
+
if (row[candidate] !== undefined) {
|
|
572
|
+
return row[candidate];
|
|
416
573
|
}
|
|
417
574
|
}
|
|
575
|
+
return allowAliasFallback ? row[alias] : undefined;
|
|
576
|
+
}
|
|
577
|
+
projectTableValue(row, table) {
|
|
578
|
+
const alias = this.tableAliases.get(table) ?? table.config.name;
|
|
579
|
+
const projected = {};
|
|
580
|
+
let hasValue = false;
|
|
581
|
+
for (const columnName of Object.keys(table.columns)) {
|
|
582
|
+
const candidates = alias === this.primaryAlias
|
|
583
|
+
? [columnName, `${alias}.${columnName}`]
|
|
584
|
+
: [`${alias}.${columnName}`];
|
|
585
|
+
const match = candidates.find((candidate) => row[candidate] !== undefined);
|
|
586
|
+
projected[columnName] = match ? row[match] : undefined;
|
|
587
|
+
if (projected[columnName] !== undefined) {
|
|
588
|
+
hasValue = true;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
if (alias !== this.primaryAlias && !hasValue) {
|
|
592
|
+
return null;
|
|
593
|
+
}
|
|
418
594
|
return projected;
|
|
419
595
|
}
|
|
596
|
+
isSelectFieldMap(field) {
|
|
597
|
+
return !!field
|
|
598
|
+
&& typeof field === 'object'
|
|
599
|
+
&& !(field instanceof schema_1.PodColumnBase)
|
|
600
|
+
&& !(field instanceof schema_1.PodTable)
|
|
601
|
+
&& !(0, aggregates_1.isAggregateExpression)(field);
|
|
602
|
+
}
|
|
603
|
+
collectSelectionAliases(field) {
|
|
604
|
+
if (typeof field === 'string') {
|
|
605
|
+
const { alias } = this.parseColumnReferenceString(field);
|
|
606
|
+
return new Set(alias ? [alias] : this.primaryAlias ? [this.primaryAlias] : []);
|
|
607
|
+
}
|
|
608
|
+
if (field instanceof schema_1.PodColumnBase) {
|
|
609
|
+
return new Set([this.resolveColumnReference(field).alias]);
|
|
610
|
+
}
|
|
611
|
+
if (field instanceof schema_1.PodTable) {
|
|
612
|
+
return new Set([this.tableAliases.get(field) ?? field.config.name]);
|
|
613
|
+
}
|
|
614
|
+
if (!this.isSelectFieldMap(field)) {
|
|
615
|
+
return new Set();
|
|
616
|
+
}
|
|
617
|
+
const aliases = new Set();
|
|
618
|
+
for (const child of Object.values(field)) {
|
|
619
|
+
for (const alias of this.collectSelectionAliases(child)) {
|
|
620
|
+
aliases.add(alias);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
return aliases;
|
|
624
|
+
}
|
|
625
|
+
isProjectedValueEmpty(value) {
|
|
626
|
+
if (value === undefined || value === null) {
|
|
627
|
+
return true;
|
|
628
|
+
}
|
|
629
|
+
if (Array.isArray(value)) {
|
|
630
|
+
return value.length === 0;
|
|
631
|
+
}
|
|
632
|
+
if (typeof value === 'object') {
|
|
633
|
+
const entries = Object.values(value);
|
|
634
|
+
return entries.length > 0 && entries.every((entry) => this.isProjectedValueEmpty(entry));
|
|
635
|
+
}
|
|
636
|
+
return false;
|
|
637
|
+
}
|
|
420
638
|
resolveFieldBindingCandidates(alias, field) {
|
|
421
|
-
const candidates = new Set(
|
|
639
|
+
const candidates = new Set();
|
|
422
640
|
if (typeof field === 'string') {
|
|
423
641
|
const { alias: refAlias, column } = this.parseColumnReferenceString(field);
|
|
424
642
|
candidates.add(field);
|
|
@@ -429,8 +647,10 @@ class SelectQueryBuilder {
|
|
|
429
647
|
}
|
|
430
648
|
else if (field instanceof schema_1.PodColumnBase) {
|
|
431
649
|
const columnRef = this.resolveColumnReference(field);
|
|
432
|
-
candidates.add(field.name);
|
|
433
650
|
candidates.add(`${columnRef.alias}.${columnRef.column}`);
|
|
651
|
+
if (!columnRef.alias || columnRef.alias === this.primaryAlias) {
|
|
652
|
+
candidates.add(field.name);
|
|
653
|
+
}
|
|
434
654
|
}
|
|
435
655
|
else if (field && typeof field === 'object') {
|
|
436
656
|
const candidateName = field.name;
|
|
@@ -440,13 +660,31 @@ class SelectQueryBuilder {
|
|
|
440
660
|
}
|
|
441
661
|
return Array.from(candidates);
|
|
442
662
|
}
|
|
663
|
+
shouldUseProjectionFallback() {
|
|
664
|
+
if (!this.selectedFields) {
|
|
665
|
+
return false;
|
|
666
|
+
}
|
|
667
|
+
const containsStructuredField = (field) => {
|
|
668
|
+
if (field instanceof schema_1.PodTable) {
|
|
669
|
+
return true;
|
|
670
|
+
}
|
|
671
|
+
if (this.isSelectFieldMap(field)) {
|
|
672
|
+
return true;
|
|
673
|
+
}
|
|
674
|
+
return false;
|
|
675
|
+
};
|
|
676
|
+
return Object.values(this.selectedFields).some((field) => containsStructuredField(field));
|
|
677
|
+
}
|
|
443
678
|
shouldUseAggregateFallback() {
|
|
444
|
-
|
|
679
|
+
if (this.havingCondition) {
|
|
680
|
+
return true;
|
|
681
|
+
}
|
|
682
|
+
if (this.joins.length > 0) {
|
|
683
|
+
return this.groupByColumns.length > 0 || this.hasAggregateSelection();
|
|
684
|
+
}
|
|
445
685
|
if (this.groupByColumns.length > 0) {
|
|
446
686
|
return false;
|
|
447
687
|
}
|
|
448
|
-
// For pure aggregate queries (no GROUP BY), Comunica seems to have issues with multiple aggregates
|
|
449
|
-
// So we use JS fallback for these cases
|
|
450
688
|
if (!this.selectedFields) {
|
|
451
689
|
return false;
|
|
452
690
|
}
|
|
@@ -657,6 +895,12 @@ class SelectQueryBuilder {
|
|
|
657
895
|
}
|
|
658
896
|
return undefined;
|
|
659
897
|
}
|
|
898
|
+
hasAggregateSelection() {
|
|
899
|
+
if (!this.selectedFields) {
|
|
900
|
+
return false;
|
|
901
|
+
}
|
|
902
|
+
return Object.values(this.selectedFields).some((field) => (0, aggregates_1.isAggregateExpression)(field));
|
|
903
|
+
}
|
|
660
904
|
hasMixedAggregateSelection() {
|
|
661
905
|
if (!this.selectedFields) {
|
|
662
906
|
return false;
|
|
@@ -721,15 +965,17 @@ class SelectQueryBuilder {
|
|
|
721
965
|
return result;
|
|
722
966
|
});
|
|
723
967
|
}
|
|
724
|
-
async hydrateInlineColumns(rows, table) {
|
|
968
|
+
async hydrateInlineColumns(rows, table, mergeRows = true) {
|
|
725
969
|
if (!rows.length) {
|
|
726
970
|
return rows;
|
|
727
971
|
}
|
|
728
|
-
rows = this.mergeRowsBySubject(rows);
|
|
729
972
|
const inlineColumns = Object.values(table.columns ?? {}).filter((col) => this.isInlineObjectColumn(col));
|
|
730
973
|
if (inlineColumns.length === 0) {
|
|
731
974
|
return rows;
|
|
732
975
|
}
|
|
976
|
+
if (mergeRows) {
|
|
977
|
+
rows = this.mergeRowsBySubject(rows);
|
|
978
|
+
}
|
|
733
979
|
const predicateToColumn = new Map();
|
|
734
980
|
inlineColumns.forEach((col) => {
|
|
735
981
|
const predicate = col.getPredicate(table.config.namespace);
|
|
@@ -782,7 +1028,7 @@ class SelectQueryBuilder {
|
|
|
782
1028
|
if (!childIri || !pred)
|
|
783
1029
|
return;
|
|
784
1030
|
const child = childMap.get(childIri) ?? { '@id': childIri, id: this.extractIdFromSubject(childIri, table) };
|
|
785
|
-
const key =
|
|
1031
|
+
const key = this.normalizeInlinePredicateKey(pred, inlineNamespace);
|
|
786
1032
|
if (obj === undefined) {
|
|
787
1033
|
childMap.set(childIri, child);
|
|
788
1034
|
return;
|
|
@@ -868,6 +1114,20 @@ class SelectQueryBuilder {
|
|
|
868
1114
|
return result;
|
|
869
1115
|
});
|
|
870
1116
|
}
|
|
1117
|
+
normalizeInlinePredicateKey(predicate, inlineNamespace) {
|
|
1118
|
+
if (inlineNamespace && predicate.startsWith(inlineNamespace)) {
|
|
1119
|
+
return predicate.slice(inlineNamespace.length);
|
|
1120
|
+
}
|
|
1121
|
+
const hashIndex = predicate.lastIndexOf('#');
|
|
1122
|
+
if (hashIndex !== -1 && hashIndex < predicate.length - 1) {
|
|
1123
|
+
return predicate.slice(hashIndex + 1);
|
|
1124
|
+
}
|
|
1125
|
+
const slashIndex = predicate.lastIndexOf('/');
|
|
1126
|
+
if (slashIndex !== -1 && slashIndex < predicate.length - 1) {
|
|
1127
|
+
return predicate.slice(slashIndex + 1);
|
|
1128
|
+
}
|
|
1129
|
+
return predicate;
|
|
1130
|
+
}
|
|
871
1131
|
normalizeInlineObjectValue(value) {
|
|
872
1132
|
if (value === null || value === undefined)
|
|
873
1133
|
return undefined;
|
|
@@ -890,6 +1150,73 @@ class SelectQueryBuilder {
|
|
|
890
1150
|
return value.value;
|
|
891
1151
|
return undefined;
|
|
892
1152
|
}
|
|
1153
|
+
applyDeferredOrderBy(rows) {
|
|
1154
|
+
if (this.orderByClauses.length === 0 || rows.length < 2) {
|
|
1155
|
+
return rows;
|
|
1156
|
+
}
|
|
1157
|
+
const sorted = [...rows];
|
|
1158
|
+
sorted.sort((leftRow, rightRow) => {
|
|
1159
|
+
for (const clause of this.orderByClauses) {
|
|
1160
|
+
const leftValue = this.getOrderByValue(leftRow, clause.column);
|
|
1161
|
+
const rightValue = this.getOrderByValue(rightRow, clause.column);
|
|
1162
|
+
const comparison = this.compareOrderByValues(leftValue, rightValue);
|
|
1163
|
+
if (comparison !== 0) {
|
|
1164
|
+
return clause.direction === 'desc' ? -comparison : comparison;
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
return 0;
|
|
1168
|
+
});
|
|
1169
|
+
return sorted;
|
|
1170
|
+
}
|
|
1171
|
+
applyDistinctRows(rows) {
|
|
1172
|
+
if (!this.isDistinct || rows.length < 2) {
|
|
1173
|
+
return rows;
|
|
1174
|
+
}
|
|
1175
|
+
const seen = new Set();
|
|
1176
|
+
const deduped = [];
|
|
1177
|
+
for (const row of rows) {
|
|
1178
|
+
const key = this.serializeValueForKey(row);
|
|
1179
|
+
if (seen.has(key)) {
|
|
1180
|
+
continue;
|
|
1181
|
+
}
|
|
1182
|
+
seen.add(key);
|
|
1183
|
+
deduped.push(row);
|
|
1184
|
+
}
|
|
1185
|
+
return deduped;
|
|
1186
|
+
}
|
|
1187
|
+
applyDeferredOffsetAndLimit(rows) {
|
|
1188
|
+
const offset = this.offsetCount ?? 0;
|
|
1189
|
+
const offsetRows = offset > 0 ? rows.slice(offset) : rows;
|
|
1190
|
+
if (this.limitCount === undefined) {
|
|
1191
|
+
return offsetRows;
|
|
1192
|
+
}
|
|
1193
|
+
return offsetRows.slice(0, this.limitCount);
|
|
1194
|
+
}
|
|
1195
|
+
getOrderByValue(row, columnName) {
|
|
1196
|
+
if (columnName in row) {
|
|
1197
|
+
return row[columnName];
|
|
1198
|
+
}
|
|
1199
|
+
const aliasKey = Object.keys(row).find((key) => key.endsWith(`.${columnName}`));
|
|
1200
|
+
if (aliasKey) {
|
|
1201
|
+
return row[aliasKey];
|
|
1202
|
+
}
|
|
1203
|
+
return undefined;
|
|
1204
|
+
}
|
|
1205
|
+
compareOrderByValues(left, right) {
|
|
1206
|
+
if (left === right) {
|
|
1207
|
+
return 0;
|
|
1208
|
+
}
|
|
1209
|
+
if (left === undefined || left === null) {
|
|
1210
|
+
return 1;
|
|
1211
|
+
}
|
|
1212
|
+
if (right === undefined || right === null) {
|
|
1213
|
+
return -1;
|
|
1214
|
+
}
|
|
1215
|
+
if (typeof left === 'number' && typeof right === 'number') {
|
|
1216
|
+
return left - right;
|
|
1217
|
+
}
|
|
1218
|
+
return String(left).localeCompare(String(right));
|
|
1219
|
+
}
|
|
893
1220
|
mergeRowsBySubject(rows) {
|
|
894
1221
|
const merged = new Map();
|
|
895
1222
|
const order = [];
|
|
@@ -987,11 +1314,11 @@ class SelectQueryBuilder {
|
|
|
987
1314
|
isInlineObjectColumn(column) {
|
|
988
1315
|
if (!column)
|
|
989
1316
|
return false;
|
|
990
|
-
if (column.dataType === 'object')
|
|
1317
|
+
if (column.dataType === 'object' || column.dataType === 'json')
|
|
991
1318
|
return true;
|
|
992
1319
|
if (column.dataType === 'array') {
|
|
993
1320
|
const elementType = column.elementType ?? column.options?.baseType;
|
|
994
|
-
return elementType === 'object';
|
|
1321
|
+
return elementType === 'object' || elementType === 'json';
|
|
995
1322
|
}
|
|
996
1323
|
return false;
|
|
997
1324
|
}
|
|
@@ -1004,6 +1331,10 @@ class SelectQueryBuilder {
|
|
|
1004
1331
|
return combinedRows;
|
|
1005
1332
|
}
|
|
1006
1333
|
async fetchJoinRows(join, baseRows) {
|
|
1334
|
+
if (join.type === 'crossJoin') {
|
|
1335
|
+
const joinRows = await this.session.select().from(join.table);
|
|
1336
|
+
return this.normalizeJoinRows(join, joinRows);
|
|
1337
|
+
}
|
|
1007
1338
|
const conditions = join.resolvedConditions ?? [];
|
|
1008
1339
|
if (conditions.length === 0) {
|
|
1009
1340
|
return [];
|
|
@@ -1057,6 +1388,18 @@ class SelectQueryBuilder {
|
|
|
1057
1388
|
});
|
|
1058
1389
|
}
|
|
1059
1390
|
mergeRowsWithJoin(baseRows, join, joinRows) {
|
|
1391
|
+
if (join.type === 'crossJoin') {
|
|
1392
|
+
if (baseRows.length === 0 || joinRows.length === 0) {
|
|
1393
|
+
return [];
|
|
1394
|
+
}
|
|
1395
|
+
const merged = [];
|
|
1396
|
+
for (const baseRow of baseRows) {
|
|
1397
|
+
for (const joinRow of joinRows) {
|
|
1398
|
+
merged.push({ ...baseRow, ...joinRow });
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
return merged;
|
|
1402
|
+
}
|
|
1060
1403
|
const conditions = join.resolvedConditions ?? [];
|
|
1061
1404
|
if (conditions.length === 0) {
|
|
1062
1405
|
return baseRows;
|
|
@@ -1109,6 +1452,12 @@ class SelectQueryBuilder {
|
|
|
1109
1452
|
}
|
|
1110
1453
|
return rows.filter((row) => this.joinFilters.every((condition) => this.evaluateCondition(row, condition)));
|
|
1111
1454
|
}
|
|
1455
|
+
applyHavingFilter(rows) {
|
|
1456
|
+
if (!this.havingCondition) {
|
|
1457
|
+
return rows;
|
|
1458
|
+
}
|
|
1459
|
+
return rows.filter((row) => this.evaluateCondition(row, this.havingCondition));
|
|
1460
|
+
}
|
|
1112
1461
|
evaluateCondition(row, condition) {
|
|
1113
1462
|
switch (condition.type) {
|
|
1114
1463
|
case 'binary_expr':
|
|
@@ -1128,27 +1477,8 @@ class SelectQueryBuilder {
|
|
|
1128
1477
|
if (!left) {
|
|
1129
1478
|
return true;
|
|
1130
1479
|
}
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
let tableAlias;
|
|
1134
|
-
if (typeof left === 'string') {
|
|
1135
|
-
if (left.includes('.')) {
|
|
1136
|
-
[tableAlias, colName] = left.split('.');
|
|
1137
|
-
}
|
|
1138
|
-
else {
|
|
1139
|
-
colName = left;
|
|
1140
|
-
}
|
|
1141
|
-
}
|
|
1142
|
-
else if (left && typeof left === 'object') {
|
|
1143
|
-
colName = left.name;
|
|
1144
|
-
tableAlias = left.table;
|
|
1145
|
-
}
|
|
1146
|
-
else {
|
|
1147
|
-
return true;
|
|
1148
|
-
}
|
|
1149
|
-
const columnRef = this.resolveColumnReference(`${tableAlias ?? this.primaryAlias}.${colName}`);
|
|
1150
|
-
const value = this.getRowValueForColumn(row, columnRef);
|
|
1151
|
-
const target = right;
|
|
1480
|
+
const value = this.resolveConditionOperandValue(row, left, this.primaryAlias);
|
|
1481
|
+
const target = this.resolveConditionOperandValue(row, right);
|
|
1152
1482
|
switch (op.toUpperCase()) {
|
|
1153
1483
|
case '=':
|
|
1154
1484
|
return value === target;
|
|
@@ -1176,33 +1506,13 @@ class SelectQueryBuilder {
|
|
|
1176
1506
|
evaluateUnaryCondition(row, condition) {
|
|
1177
1507
|
const op = condition.operator;
|
|
1178
1508
|
const val = condition.value;
|
|
1179
|
-
// For NOT operator, value is another condition
|
|
1180
1509
|
if (op.toUpperCase() === 'NOT') {
|
|
1181
1510
|
return !this.evaluateCondition(row, val);
|
|
1182
1511
|
}
|
|
1183
|
-
// For IS NULL / IS NOT NULL, value is the column reference
|
|
1184
1512
|
if (!val) {
|
|
1185
1513
|
return true;
|
|
1186
1514
|
}
|
|
1187
|
-
|
|
1188
|
-
let tableAlias;
|
|
1189
|
-
if (typeof val === 'string') {
|
|
1190
|
-
if (val.includes('.')) {
|
|
1191
|
-
[tableAlias, colName] = val.split('.');
|
|
1192
|
-
}
|
|
1193
|
-
else {
|
|
1194
|
-
colName = val;
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
else if (val && typeof val === 'object' && 'name' in val) {
|
|
1198
|
-
colName = val.name;
|
|
1199
|
-
tableAlias = val.table;
|
|
1200
|
-
}
|
|
1201
|
-
else {
|
|
1202
|
-
return true;
|
|
1203
|
-
}
|
|
1204
|
-
const columnRef = this.resolveColumnReference(`${tableAlias ?? this.primaryAlias}.${colName}`);
|
|
1205
|
-
const rowValue = this.getRowValueForColumn(row, columnRef);
|
|
1515
|
+
const rowValue = this.resolveConditionOperandValue(row, val, this.primaryAlias);
|
|
1206
1516
|
switch (op.toUpperCase()) {
|
|
1207
1517
|
case 'IS NULL':
|
|
1208
1518
|
return rowValue === null || rowValue === undefined;
|
|
@@ -1223,6 +1533,16 @@ class SelectQueryBuilder {
|
|
|
1223
1533
|
}
|
|
1224
1534
|
return true;
|
|
1225
1535
|
}
|
|
1536
|
+
resolveConditionOperandValue(row, operand, fallbackAlias) {
|
|
1537
|
+
if (operand instanceof expressions_1.SelectionAliasExpression) {
|
|
1538
|
+
return row[operand.alias];
|
|
1539
|
+
}
|
|
1540
|
+
const columnRef = this.getConditionColumnReference(operand, fallbackAlias);
|
|
1541
|
+
if (columnRef) {
|
|
1542
|
+
return this.getRowValueForColumn(row, columnRef);
|
|
1543
|
+
}
|
|
1544
|
+
return operand;
|
|
1545
|
+
}
|
|
1226
1546
|
getColumnKeyCandidates(column) {
|
|
1227
1547
|
const candidates = [];
|
|
1228
1548
|
const baseAlias = this.primaryAlias;
|