@_linked/core 2.4.0 → 2.4.1-next.20260406160450

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.
@@ -0,0 +1,332 @@
1
+ "use strict";
2
+ /**
3
+ * Serialization and deserialization helpers for QueryBuilder fields that contain
4
+ * live object references (PropertyShape, ExpressionNode, etc.).
5
+ *
6
+ * These convert between runtime WherePath / SortByPath / RawMinusEntry structures
7
+ * and plain JSON-safe representations that can round-trip through JSON.stringify/parse.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.serializeQueryPropertyPath = serializeQueryPropertyPath;
44
+ exports.serializeWherePath = serializeWherePath;
45
+ exports.serializeSortByPath = serializeSortByPath;
46
+ exports.serializeRawMinusEntry = serializeRawMinusEntry;
47
+ exports.deserializeQueryPropertyPath = deserializeQueryPropertyPath;
48
+ exports.deserializeWherePath = deserializeWherePath;
49
+ exports.deserializeSortByPath = deserializeSortByPath;
50
+ exports.deserializeRawMinusEntry = deserializeRawMinusEntry;
51
+ const ShapeClass_js_1 = require("../utils/ShapeClass.js");
52
+ const PropertyPath_js_1 = require("./PropertyPath.js");
53
+ const ExpressionNode_js_1 = require("../expressions/ExpressionNode.js");
54
+ // ExistsCondition only exists after the WherePath refactor; access dynamically
55
+ // so this file compiles on branches where it doesn't exist yet.
56
+ const _exprModule = __importStar(require("../expressions/ExpressionNode.js"));
57
+ const ExistsConditionCtor = _exprModule.ExistsCondition;
58
+ // =============================================================================
59
+ // Serialization
60
+ // =============================================================================
61
+ function serializeQueryPropertyPath(path) {
62
+ return path.map(serializeQueryStep);
63
+ }
64
+ function serializeQueryStep(step) {
65
+ // PropertyQueryStep — has a .property field that is a PropertyShape
66
+ if ('property' in step && step.property) {
67
+ const pqs = step;
68
+ const json = {
69
+ kind: 'property',
70
+ label: pqs.property.label,
71
+ };
72
+ if (pqs.where) {
73
+ json.where = serializeWherePath(pqs.where);
74
+ }
75
+ return json;
76
+ }
77
+ // SizeStep — has a .count field
78
+ if ('count' in step) {
79
+ const ss = step;
80
+ const json = {
81
+ kind: 'size',
82
+ count: serializeQueryPropertyPath(ss.count),
83
+ };
84
+ if (ss.label)
85
+ json.label = ss.label;
86
+ return json;
87
+ }
88
+ // ShapeReferenceValue — has .id and .shape
89
+ const ref = step;
90
+ return { kind: 'shapeRef', id: ref.id, shapeId: ref.shape.id };
91
+ }
92
+ function serializeWherePath(where) {
93
+ var _a, _b;
94
+ if ('expressionNode' in where) {
95
+ const expr = where.expressionNode;
96
+ const json = {
97
+ kind: 'expression',
98
+ ir: expr.ir,
99
+ };
100
+ if (expr._refs.size > 0) {
101
+ const refs = {};
102
+ for (const [k, v] of expr._refs)
103
+ refs[k] = [...v];
104
+ json.refs = refs;
105
+ }
106
+ return json;
107
+ }
108
+ if ('firstPath' in where) {
109
+ const andOr = where;
110
+ return {
111
+ kind: 'andOr',
112
+ firstPath: serializeWherePath(andOr.firstPath),
113
+ andOr: andOr.andOr.map((token) => {
114
+ const t = {};
115
+ if (token.and)
116
+ t.and = serializeWherePath(token.and);
117
+ if (token.or)
118
+ t.or = serializeWherePath(token.or);
119
+ return t;
120
+ }),
121
+ };
122
+ }
123
+ if ('path' in where && 'method' in where && 'args' in where) {
124
+ const ev = where;
125
+ return {
126
+ kind: 'evaluation',
127
+ path: serializeQueryPropertyPath(ev.path),
128
+ method: ev.method,
129
+ args: ev.args.map(serializeQueryArg),
130
+ };
131
+ }
132
+ if ('existsCondition' in where) {
133
+ // WhereExistsPath — serialize the ExistsCondition structurally
134
+ const ec = where.existsCondition;
135
+ return {
136
+ kind: 'exists',
137
+ pathSegmentIds: [...ec.pathSegmentIds],
138
+ predicate: { ir: ec.predicate.ir, refs: serializePropertyRefMap(ec.predicate._refs) },
139
+ negated: (_a = ec.negated) !== null && _a !== void 0 ? _a : false,
140
+ chain: ((_b = ec.chain) !== null && _b !== void 0 ? _b : []).map((c) => {
141
+ var _a;
142
+ return ({
143
+ op: c.op,
144
+ condition: 'pathSegmentIds' in c.condition
145
+ ? { kind: 'exists', pathSegmentIds: [...c.condition.pathSegmentIds], predicate: { ir: c.condition.predicate.ir, refs: serializePropertyRefMap(c.condition.predicate._refs) }, negated: (_a = c.condition.negated) !== null && _a !== void 0 ? _a : false, chain: [] }
146
+ : { kind: 'expression', ir: c.condition.ir, refs: serializePropertyRefMap(c.condition._refs) },
147
+ });
148
+ }),
149
+ };
150
+ }
151
+ throw new Error(`Cannot serialize WherePath: ${JSON.stringify(Object.keys(where))}`);
152
+ }
153
+ function serializePropertyRefMap(refs) {
154
+ if (!refs || refs.size === 0)
155
+ return undefined;
156
+ const out = {};
157
+ for (const [k, v] of refs)
158
+ out[k] = [...v];
159
+ return out;
160
+ }
161
+ function serializeQueryArg(arg) {
162
+ if (typeof arg === 'string' || typeof arg === 'number' || typeof arg === 'boolean') {
163
+ return { kind: 'primitive', value: arg };
164
+ }
165
+ if (arg instanceof Date) {
166
+ return { kind: 'date', value: arg.toISOString() };
167
+ }
168
+ if (typeof arg === 'object' && arg !== null) {
169
+ if ('expressionNode' in arg || 'existsCondition' in arg || 'firstPath' in arg || ('path' in arg && 'method' in arg && 'args' in arg)) {
170
+ return { kind: 'where', where: serializeWherePath(arg) };
171
+ }
172
+ // ArgPath — has 'subject' and 'path'
173
+ if ('subject' in arg && 'path' in arg) {
174
+ const ap = arg;
175
+ return {
176
+ kind: 'argPath',
177
+ path: serializeQueryPropertyPath(ap.path),
178
+ subject: { id: ap.subject.id, shapeId: ap.subject.shape.id },
179
+ };
180
+ }
181
+ // NodeReferenceValue — has 'id'
182
+ if ('id' in arg) {
183
+ return { kind: 'nodeRef', id: arg.id };
184
+ }
185
+ }
186
+ throw new Error(`Cannot serialize query arg: ${JSON.stringify(arg)}`);
187
+ }
188
+ function serializeSortByPath(sort) {
189
+ return {
190
+ paths: sort.paths.map((p) => p.toString()),
191
+ direction: sort.direction,
192
+ };
193
+ }
194
+ function serializeRawMinusEntry(entry) {
195
+ const json = {};
196
+ if (entry.shapeId)
197
+ json.shapeId = entry.shapeId;
198
+ if (entry.where)
199
+ json.where = serializeWherePath(entry.where);
200
+ if (entry.propertyPaths) {
201
+ json.propertyPaths = entry.propertyPaths.map((pp) => pp.map((seg) => seg.propertyShapeId));
202
+ }
203
+ return json;
204
+ }
205
+ // =============================================================================
206
+ // Deserialization
207
+ // =============================================================================
208
+ function deserializeQueryPropertyPath(shape, steps) {
209
+ var _a;
210
+ const result = [];
211
+ let currentShape = shape;
212
+ for (const step of steps) {
213
+ if (step.kind === 'property') {
214
+ const propertyShape = currentShape.getPropertyShape(step.label);
215
+ if (!propertyShape) {
216
+ throw new Error(`Property '${step.label}' not found on shape '${currentShape.label || currentShape.id}'`);
217
+ }
218
+ const queryStep = { property: propertyShape };
219
+ if (step.where) {
220
+ const nestedShape = propertyShape.valueShape
221
+ ? (_a = (0, ShapeClass_js_1.getShapeClass)(propertyShape.valueShape)) === null || _a === void 0 ? void 0 : _a.shape
222
+ : currentShape;
223
+ queryStep.where = deserializeWherePath(nestedShape || currentShape, step.where);
224
+ }
225
+ result.push(queryStep);
226
+ // Advance shape context for subsequent traversals
227
+ if (propertyShape.valueShape) {
228
+ const cls = (0, ShapeClass_js_1.getShapeClass)(propertyShape.valueShape);
229
+ if (cls === null || cls === void 0 ? void 0 : cls.shape)
230
+ currentShape = cls.shape;
231
+ }
232
+ }
233
+ else if (step.kind === 'size') {
234
+ result.push({
235
+ count: deserializeQueryPropertyPath(currentShape, step.count),
236
+ label: step.label,
237
+ });
238
+ }
239
+ else {
240
+ // shapeRef
241
+ result.push({ id: step.id, shape: { id: step.shapeId } });
242
+ }
243
+ }
244
+ return result;
245
+ }
246
+ function deserializeWherePath(shape, json) {
247
+ if (json.kind === 'expression') {
248
+ const refs = new Map();
249
+ if (json.refs) {
250
+ for (const [k, v] of Object.entries(json.refs))
251
+ refs.set(k, v);
252
+ }
253
+ return { expressionNode: new ExpressionNode_js_1.ExpressionNode(json.ir, refs) };
254
+ }
255
+ if (json.kind === 'exists') {
256
+ if (!ExistsConditionCtor)
257
+ throw new Error('ExistsCondition is not available on this build');
258
+ const predRefs = deserializeRefMap(json.predicate.refs);
259
+ const predicate = new ExpressionNode_js_1.ExpressionNode(json.predicate.ir, predRefs);
260
+ const chain = json.chain.map((c) => {
261
+ if (c.condition.kind === 'exists') {
262
+ const innerRefs = deserializeRefMap(c.condition.predicate.refs);
263
+ return { op: c.op, condition: new ExistsConditionCtor(c.condition.pathSegmentIds, new ExpressionNode_js_1.ExpressionNode(c.condition.predicate.ir, innerRefs), c.condition.negated) };
264
+ }
265
+ const exprRefs = deserializeRefMap(c.condition.refs);
266
+ return { op: c.op, condition: new ExpressionNode_js_1.ExpressionNode(c.condition.ir, exprRefs) };
267
+ });
268
+ return { existsCondition: new ExistsConditionCtor(json.pathSegmentIds, predicate, json.negated, chain) };
269
+ }
270
+ if (json.kind === 'andOr') {
271
+ return {
272
+ firstPath: deserializeWherePath(shape, json.firstPath),
273
+ andOr: json.andOr.map((token) => {
274
+ const t = {};
275
+ if (token.and)
276
+ t.and = deserializeWherePath(shape, token.and);
277
+ if (token.or)
278
+ t.or = deserializeWherePath(shape, token.or);
279
+ return t;
280
+ }),
281
+ };
282
+ }
283
+ // evaluation (legacy)
284
+ return {
285
+ path: deserializeQueryPropertyPath(shape, json.path),
286
+ method: json.method,
287
+ args: json.args.map((a) => deserializeQueryArg(shape, a)),
288
+ };
289
+ }
290
+ function deserializeRefMap(refs) {
291
+ const m = new Map();
292
+ if (refs) {
293
+ for (const [k, v] of Object.entries(refs))
294
+ m.set(k, v);
295
+ }
296
+ return m;
297
+ }
298
+ function deserializeQueryArg(shape, json) {
299
+ switch (json.kind) {
300
+ case 'primitive':
301
+ return json.value;
302
+ case 'date':
303
+ return new Date(json.value);
304
+ case 'nodeRef':
305
+ return { id: json.id };
306
+ case 'where':
307
+ return deserializeWherePath(shape, json.where);
308
+ case 'argPath':
309
+ return {
310
+ path: deserializeQueryPropertyPath(shape, json.path),
311
+ subject: { id: json.subject.id, shape: { id: json.subject.shapeId } },
312
+ };
313
+ }
314
+ }
315
+ function deserializeSortByPath(shape, json) {
316
+ return {
317
+ paths: json.paths.map((p) => (0, PropertyPath_js_1.walkPropertyPath)(shape, p)),
318
+ direction: json.direction,
319
+ };
320
+ }
321
+ function deserializeRawMinusEntry(shape, json) {
322
+ const entry = {};
323
+ if (json.shapeId)
324
+ entry.shapeId = json.shapeId;
325
+ if (json.where)
326
+ entry.where = deserializeWherePath(shape, json.where);
327
+ if (json.propertyPaths) {
328
+ entry.propertyPaths = json.propertyPaths.map((pp) => pp.map((id) => ({ propertyShapeId: id })));
329
+ }
330
+ return entry;
331
+ }
332
+ //# sourceMappingURL=QueryBuilderSerialization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBuilderSerialization.js","sourceRoot":"","sources":["../../../src/queries/QueryBuilderSerialization.ts"],"names":[],"mappings":"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"}
@@ -102,6 +102,34 @@ function joinNodes(left, right) {
102
102
  return right;
103
103
  return { type: 'join', left, right };
104
104
  }
105
+ function bindingKey(alias, property) {
106
+ return `${alias}::${property}`;
107
+ }
108
+ function contextAliasKey(contextIri) {
109
+ return `__ctx__${contextIri}`;
110
+ }
111
+ function mergeKeySets(...sets) {
112
+ const merged = new Set();
113
+ for (const set of sets) {
114
+ for (const key of set) {
115
+ merged.add(key);
116
+ }
117
+ }
118
+ return merged;
119
+ }
120
+ function intersectKeySets(sets) {
121
+ if (sets.length === 0) {
122
+ return new Set();
123
+ }
124
+ const [first, ...rest] = sets;
125
+ const intersection = new Set(first);
126
+ for (const value of intersection) {
127
+ if (!rest.every((set) => set.has(value))) {
128
+ intersection.delete(value);
129
+ }
130
+ }
131
+ return intersection;
132
+ }
105
133
  // ---------------------------------------------------------------------------
106
134
  // Pattern helpers
107
135
  // ---------------------------------------------------------------------------
@@ -142,7 +170,7 @@ class VariableRegistry {
142
170
  this.usedVarNames = new Set();
143
171
  }
144
172
  key(alias, property) {
145
- return `${alias}::${property}`;
173
+ return bindingKey(alias, property);
146
174
  }
147
175
  has(alias, property) {
148
176
  return this.map.has(this.key(alias, property));
@@ -202,6 +230,13 @@ function containsAggregate(expr) {
202
230
  */
203
231
  function selectToAlgebra(query, _options) {
204
232
  const registry = new VariableRegistry();
233
+ // Promote bindings only when the top-level WHERE would reject rows without
234
+ // them. This keeps human-like SPARQL for null-rejecting filters without
235
+ // over-constraining OR cases that can still match through other branches.
236
+ const requiredPropertyKeys = query.where
237
+ ? collectRequiredBindingKeys(query.where)
238
+ : new Set();
239
+ const requiredPropertyTriples = [];
205
240
  // Track property triples that need to be added as OPTIONAL
206
241
  const optionalPropertyTriples = [];
207
242
  // Track filtered traversals (inline where) — these get their own OPTIONAL blocks
@@ -234,14 +269,14 @@ function selectToAlgebra(query, _options) {
234
269
  // to discover any additional property_expr references.
235
270
  // Properties already registered by inline filters (above) will be skipped.
236
271
  for (const item of query.projection) {
237
- processExpressionForProperties(item.expression, registry, optionalPropertyTriples);
272
+ processExpressionForProperties(item.expression, registry, optionalPropertyTriples, requiredPropertyTriples, requiredPropertyKeys);
238
273
  }
239
274
  if (query.where) {
240
- processExpressionForProperties(query.where, registry, optionalPropertyTriples);
275
+ processExpressionForProperties(query.where, registry, optionalPropertyTriples, requiredPropertyTriples, requiredPropertyKeys);
241
276
  }
242
277
  if (query.orderBy) {
243
278
  for (const orderItem of query.orderBy) {
244
- processExpressionForProperties(orderItem.expression, registry, optionalPropertyTriples);
279
+ processExpressionForProperties(orderItem.expression, registry, optionalPropertyTriples, requiredPropertyTriples, requiredPropertyKeys);
245
280
  }
246
281
  }
247
282
  // 5. Build the algebra tree
@@ -249,7 +284,7 @@ function selectToAlgebra(query, _options) {
249
284
  // - Wrap each optional property triple in a LeftJoin
250
285
  const requiredBgp = {
251
286
  type: 'bgp',
252
- triples: [...requiredTriples, ...traverseTriples],
287
+ triples: [...requiredTriples, ...traverseTriples, ...requiredPropertyTriples],
253
288
  };
254
289
  let algebra = requiredBgp;
255
290
  // 5b. Build filtered OPTIONAL blocks for inline where traversals.
@@ -485,39 +520,42 @@ function processPattern(pattern, registry, traverseTriples, optionalPropertyTrip
485
520
  // ---------------------------------------------------------------------------
486
521
  // Expression processing — discover property_expr references
487
522
  // ---------------------------------------------------------------------------
488
- function processExpressionForProperties(expr, registry, optionalPropertyTriples) {
523
+ function processExpressionForProperties(expr, registry, optionalPropertyTriples, requiredPropertyTriples = [], requiredPropertyKeys = new Set()) {
489
524
  switch (expr.kind) {
490
525
  case 'property_expr': {
491
526
  if (!registry.has(expr.sourceAlias, expr.property)) {
492
- // Create a new OPTIONAL triple for this property
493
527
  const varName = registry.getOrCreate(expr.sourceAlias, expr.property);
494
528
  const predicate = expr.pathExpr
495
529
  ? { kind: 'path', value: (0, pathExprToSparql_js_1.pathExprToSparql)(expr.pathExpr), uris: (0, pathExprToSparql_js_1.collectPathUris)(expr.pathExpr) }
496
530
  : iriTerm(expr.property);
497
- optionalPropertyTriples.push(tripleOf(varTerm(expr.sourceAlias), predicate, varTerm(varName)));
531
+ const triple = tripleOf(varTerm(expr.sourceAlias), predicate, varTerm(varName));
532
+ const triples = requiredPropertyKeys.has(bindingKey(expr.sourceAlias, expr.property))
533
+ ? requiredPropertyTriples
534
+ : optionalPropertyTriples;
535
+ triples.push(triple);
498
536
  }
499
537
  break;
500
538
  }
501
539
  case 'binary_expr':
502
- processExpressionForProperties(expr.left, registry, optionalPropertyTriples);
503
- processExpressionForProperties(expr.right, registry, optionalPropertyTriples);
540
+ processExpressionForProperties(expr.left, registry, optionalPropertyTriples, requiredPropertyTriples, requiredPropertyKeys);
541
+ processExpressionForProperties(expr.right, registry, optionalPropertyTriples, requiredPropertyTriples, requiredPropertyKeys);
504
542
  break;
505
543
  case 'logical_expr':
506
544
  for (const sub of expr.expressions) {
507
- processExpressionForProperties(sub, registry, optionalPropertyTriples);
545
+ processExpressionForProperties(sub, registry, optionalPropertyTriples, requiredPropertyTriples, requiredPropertyKeys);
508
546
  }
509
547
  break;
510
548
  case 'not_expr':
511
- processExpressionForProperties(expr.expression, registry, optionalPropertyTriples);
549
+ processExpressionForProperties(expr.expression, registry, optionalPropertyTriples, requiredPropertyTriples, requiredPropertyKeys);
512
550
  break;
513
551
  case 'function_expr':
514
552
  for (const arg of expr.args) {
515
- processExpressionForProperties(arg, registry, optionalPropertyTriples);
553
+ processExpressionForProperties(arg, registry, optionalPropertyTriples, requiredPropertyTriples, requiredPropertyKeys);
516
554
  }
517
555
  break;
518
556
  case 'aggregate_expr':
519
557
  for (const arg of expr.args) {
520
- processExpressionForProperties(arg, registry, optionalPropertyTriples);
558
+ processExpressionForProperties(arg, registry, optionalPropertyTriples, requiredPropertyTriples, requiredPropertyKeys);
521
559
  }
522
560
  break;
523
561
  case 'exists_expr':
@@ -529,10 +567,14 @@ function processExpressionForProperties(expr, registry, optionalPropertyTriples)
529
567
  // Context entity property — emit a triple with fixed IRI as subject.
530
568
  // Use raw IRI as registry key to avoid collision between IRIs that
531
569
  // sanitize to the same string (e.g. ctx-1 vs ctx_1).
532
- const ctxKey = `__ctx__${expr.contextIri}`;
570
+ const ctxKey = contextAliasKey(expr.contextIri);
533
571
  if (!registry.has(ctxKey, expr.property)) {
534
572
  const varName = registry.getOrCreate(ctxKey, expr.property);
535
- optionalPropertyTriples.push(tripleOf(iriTerm(expr.contextIri), iriTerm(expr.property), varTerm(varName)));
573
+ const triple = tripleOf(iriTerm(expr.contextIri), iriTerm(expr.property), varTerm(varName));
574
+ const triples = requiredPropertyKeys.has(bindingKey(ctxKey, expr.property))
575
+ ? requiredPropertyTriples
576
+ : optionalPropertyTriples;
577
+ triples.push(triple);
536
578
  }
537
579
  break;
538
580
  }
@@ -543,6 +585,37 @@ function processExpressionForProperties(expr, registry, optionalPropertyTriples)
543
585
  break;
544
586
  }
545
587
  }
588
+ /**
589
+ * Compute which bindings are mandatory for a top-level FILTER to keep a row.
590
+ * AND makes either side required; OR only keeps bindings required by every branch.
591
+ */
592
+ function collectRequiredBindingKeys(expr) {
593
+ switch (expr.kind) {
594
+ case 'property_expr':
595
+ return new Set([bindingKey(expr.sourceAlias, expr.property)]);
596
+ case 'context_property_expr':
597
+ return new Set([bindingKey(contextAliasKey(expr.contextIri), expr.property)]);
598
+ case 'binary_expr':
599
+ return mergeKeySets(collectRequiredBindingKeys(expr.left), collectRequiredBindingKeys(expr.right));
600
+ case 'function_expr':
601
+ return mergeKeySets(...expr.args.map((arg) => collectRequiredBindingKeys(arg)));
602
+ case 'not_expr':
603
+ return collectRequiredBindingKeys(expr.expression);
604
+ case 'logical_expr': {
605
+ const childSets = expr.expressions.map((sub) => collectRequiredBindingKeys(sub));
606
+ if (expr.operator === 'and') {
607
+ return mergeKeySets(...childSets);
608
+ }
609
+ return intersectKeySets(childSets);
610
+ }
611
+ case 'aggregate_expr':
612
+ case 'exists_expr':
613
+ case 'literal_expr':
614
+ case 'reference_expr':
615
+ case 'alias_expr':
616
+ return new Set();
617
+ }
618
+ }
546
619
  // ---------------------------------------------------------------------------
547
620
  // Expression conversion
548
621
  // ---------------------------------------------------------------------------