@_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.
- package/CHANGELOG.md +12 -0
- package/lib/cjs/queries/FieldSet.js +4 -0
- package/lib/cjs/queries/FieldSet.js.map +1 -1
- package/lib/cjs/queries/QueryBuilder.d.ts +17 -5
- package/lib/cjs/queries/QueryBuilder.js +123 -66
- package/lib/cjs/queries/QueryBuilder.js.map +1 -1
- package/lib/cjs/queries/QueryBuilderSerialization.d.ts +95 -0
- package/lib/cjs/queries/QueryBuilderSerialization.js +332 -0
- package/lib/cjs/queries/QueryBuilderSerialization.js.map +1 -0
- package/lib/cjs/sparql/irToAlgebra.js +89 -16
- package/lib/cjs/sparql/irToAlgebra.js.map +1 -1
- package/lib/cjs/test-helpers/query-fixtures.d.ts +7 -0
- package/lib/cjs/test-helpers/query-fixtures.js +2 -0
- package/lib/cjs/test-helpers/query-fixtures.js.map +1 -1
- package/lib/esm/queries/FieldSet.js +4 -0
- package/lib/esm/queries/FieldSet.js.map +1 -1
- package/lib/esm/queries/QueryBuilder.d.ts +17 -5
- package/lib/esm/queries/QueryBuilder.js +123 -66
- package/lib/esm/queries/QueryBuilder.js.map +1 -1
- package/lib/esm/queries/QueryBuilderSerialization.d.ts +95 -0
- package/lib/esm/queries/QueryBuilderSerialization.js +289 -0
- package/lib/esm/queries/QueryBuilderSerialization.js.map +1 -0
- package/lib/esm/sparql/irToAlgebra.js +89 -16
- package/lib/esm/sparql/irToAlgebra.js.map +1 -1
- package/lib/esm/test-helpers/query-fixtures.d.ts +7 -0
- package/lib/esm/test-helpers/query-fixtures.js +2 -0
- package/lib/esm/test-helpers/query-fixtures.js.map +1 -1
- package/package.json +1 -1
|
@@ -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
|
|
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
|
-
|
|
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 =
|
|
570
|
+
const ctxKey = contextAliasKey(expr.contextIri);
|
|
533
571
|
if (!registry.has(ctxKey, expr.property)) {
|
|
534
572
|
const varName = registry.getOrCreate(ctxKey, expr.property);
|
|
535
|
-
|
|
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
|
// ---------------------------------------------------------------------------
|