leangraph 1.1.2 → 1.1.3
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/db.d.ts.map +1 -1
- package/dist/db.js +42 -3
- package/dist/db.js.map +1 -1
- package/dist/engine/hybrid-executor.d.ts +118 -0
- package/dist/engine/hybrid-executor.d.ts.map +1 -0
- package/dist/engine/hybrid-executor.js +205 -0
- package/dist/engine/hybrid-executor.js.map +1 -0
- package/dist/engine/index.d.ts +36 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +34 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/memory-graph.d.ts +68 -0
- package/dist/engine/memory-graph.d.ts.map +1 -0
- package/dist/engine/memory-graph.js +176 -0
- package/dist/engine/memory-graph.js.map +1 -0
- package/dist/engine/query-planner.d.ts +62 -0
- package/dist/engine/query-planner.d.ts.map +1 -0
- package/dist/engine/query-planner.js +481 -0
- package/dist/engine/query-planner.js.map +1 -0
- package/dist/engine/subgraph-loader.d.ts +41 -0
- package/dist/engine/subgraph-loader.d.ts.map +1 -0
- package/dist/engine/subgraph-loader.js +172 -0
- package/dist/engine/subgraph-loader.js.map +1 -0
- package/dist/executor.d.ts +17 -0
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +286 -100
- package/dist/executor.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/parser.d.ts +47 -3
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +228 -41
- package/dist/parser.js.map +1 -1
- package/dist/translator.d.ts +53 -0
- package/dist/translator.d.ts.map +1 -1
- package/dist/translator.js +1545 -186
- package/dist/translator.js.map +1 -1
- package/package.json +9 -3
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Planner - Analyzes Cypher AST to determine if a query
|
|
3
|
+
* can use the hybrid execution engine.
|
|
4
|
+
*
|
|
5
|
+
* Supports generalized pattern chains with:
|
|
6
|
+
* - N nodes (arbitrary chain length)
|
|
7
|
+
* - Multiple variable-length edges
|
|
8
|
+
* - Var-length edges at any position
|
|
9
|
+
*/
|
|
10
|
+
/** Default max depth for unbounded variable-length paths */
|
|
11
|
+
const DEFAULT_MAX_DEPTH = 50;
|
|
12
|
+
/**
|
|
13
|
+
* Analyze a parsed query to determine if it can use the hybrid executor.
|
|
14
|
+
* Returns extracted parameters if suitable, or a reason if not.
|
|
15
|
+
*
|
|
16
|
+
* Supports generalized pattern chains:
|
|
17
|
+
* (a)-[*]->(b)-[:R1]->(c)-[:R2]->(d) -- N nodes
|
|
18
|
+
* (a)-[*]->(b)-[*]->(c) -- multiple var-length
|
|
19
|
+
*/
|
|
20
|
+
export function analyzeForHybrid(query, params) {
|
|
21
|
+
if (!isHybridCompatiblePattern(query)) {
|
|
22
|
+
return { suitable: false, reason: "Query pattern not compatible with hybrid execution" };
|
|
23
|
+
}
|
|
24
|
+
// Extract the MATCH clause
|
|
25
|
+
const matchClause = query.clauses.find((c) => c.type === "MATCH");
|
|
26
|
+
if (!matchClause) {
|
|
27
|
+
return { suitable: false, reason: "No MATCH clause found" };
|
|
28
|
+
}
|
|
29
|
+
// Get the relationship patterns
|
|
30
|
+
const relPatterns = matchClause.patterns.filter((p) => "edge" in p);
|
|
31
|
+
if (relPatterns.length < 1) {
|
|
32
|
+
return { suitable: false, reason: "Need at least 1 relationship pattern" };
|
|
33
|
+
}
|
|
34
|
+
// Extract anchor node info (first node in the pattern)
|
|
35
|
+
const anchorInfo = extractNodeInfo(relPatterns[0].source, params);
|
|
36
|
+
if (!anchorInfo) {
|
|
37
|
+
return { suitable: false, reason: "Anchor node must have a label" };
|
|
38
|
+
}
|
|
39
|
+
const anchorVar = relPatterns[0].source.variable || "node0";
|
|
40
|
+
// Build the chain from relationship patterns
|
|
41
|
+
const chain = [];
|
|
42
|
+
// Track which variable the WHERE clause applies to (for now: single node)
|
|
43
|
+
let filterTargetVar = null;
|
|
44
|
+
let filterTargetIndex = -1;
|
|
45
|
+
// Find which node the WHERE clause references (if any)
|
|
46
|
+
if (matchClause.where) {
|
|
47
|
+
filterTargetVar = findWhereTargetVar(matchClause.where, relPatterns);
|
|
48
|
+
}
|
|
49
|
+
for (let i = 0; i < relPatterns.length; i++) {
|
|
50
|
+
const rel = relPatterns[i];
|
|
51
|
+
// Extract edge info
|
|
52
|
+
const edge = rel.edge;
|
|
53
|
+
const isVarLength = edge.minHops !== undefined || edge.maxHops !== undefined;
|
|
54
|
+
const hop = {
|
|
55
|
+
edgeType: edge.type || null,
|
|
56
|
+
direction: edgeDirectionToDirection(edge.direction),
|
|
57
|
+
minHops: isVarLength ? (edge.minHops ?? 1) : 1,
|
|
58
|
+
maxHops: isVarLength ? (edge.maxHops ?? DEFAULT_MAX_DEPTH) : 1,
|
|
59
|
+
};
|
|
60
|
+
// Extract target node info
|
|
61
|
+
const targetInfo = extractNodeInfo(rel.target, params);
|
|
62
|
+
if (!targetInfo) {
|
|
63
|
+
return { suitable: false, reason: `Node at position ${i + 1} must have a label` };
|
|
64
|
+
}
|
|
65
|
+
const targetVar = rel.target.variable || `node${i + 1}`;
|
|
66
|
+
// Check if this is the node WHERE applies to
|
|
67
|
+
const whereFilter = (filterTargetVar === targetVar)
|
|
68
|
+
? convertWhereToFilter(matchClause.where, targetVar, params)
|
|
69
|
+
: undefined;
|
|
70
|
+
// If WHERE references this node but couldn't be converted, fail
|
|
71
|
+
if (filterTargetVar === targetVar && whereFilter === null) {
|
|
72
|
+
return { suitable: false, reason: "WHERE clause uses unsupported expressions" };
|
|
73
|
+
}
|
|
74
|
+
if (filterTargetVar === targetVar) {
|
|
75
|
+
filterTargetIndex = i;
|
|
76
|
+
}
|
|
77
|
+
// Build filter from inline properties and/or WHERE clause
|
|
78
|
+
const inlineProps = targetInfo.properties;
|
|
79
|
+
const hasInlineProps = Object.keys(inlineProps).length > 0;
|
|
80
|
+
let nodeFilter;
|
|
81
|
+
if (hasInlineProps && whereFilter) {
|
|
82
|
+
// Combine inline property filter with WHERE filter
|
|
83
|
+
nodeFilter = (node) => {
|
|
84
|
+
for (const [key, value] of Object.entries(inlineProps)) {
|
|
85
|
+
if (node.properties[key] !== value)
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return whereFilter(node);
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
else if (hasInlineProps) {
|
|
92
|
+
// Only inline property filter
|
|
93
|
+
nodeFilter = (node) => {
|
|
94
|
+
for (const [key, value] of Object.entries(inlineProps)) {
|
|
95
|
+
if (node.properties[key] !== value)
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
return true;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
else if (whereFilter) {
|
|
102
|
+
nodeFilter = whereFilter;
|
|
103
|
+
}
|
|
104
|
+
const node = {
|
|
105
|
+
variable: targetVar,
|
|
106
|
+
label: targetInfo.label,
|
|
107
|
+
filter: nodeFilter,
|
|
108
|
+
};
|
|
109
|
+
chain.push({ hop, node });
|
|
110
|
+
}
|
|
111
|
+
// If WHERE references a node that's not in the chain (e.g., anchor), fail for now
|
|
112
|
+
if (matchClause.where && filterTargetVar && filterTargetIndex === -1 && filterTargetVar !== anchorVar) {
|
|
113
|
+
return { suitable: false, reason: "WHERE clause references node not in chain or unsupported" };
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
suitable: true,
|
|
117
|
+
params: {
|
|
118
|
+
anchor: {
|
|
119
|
+
variable: anchorVar,
|
|
120
|
+
label: anchorInfo.label,
|
|
121
|
+
},
|
|
122
|
+
anchorProps: anchorInfo.properties,
|
|
123
|
+
chain,
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Find which variable the WHERE clause references.
|
|
129
|
+
* Returns null if WHERE references multiple nodes or an unknown variable.
|
|
130
|
+
*/
|
|
131
|
+
function findWhereTargetVar(where, relPatterns) {
|
|
132
|
+
// Collect all variables from the pattern
|
|
133
|
+
const allVars = new Set();
|
|
134
|
+
if (relPatterns[0]?.source.variable) {
|
|
135
|
+
allVars.add(relPatterns[0].source.variable);
|
|
136
|
+
}
|
|
137
|
+
for (const rel of relPatterns) {
|
|
138
|
+
if (rel.target.variable) {
|
|
139
|
+
allVars.add(rel.target.variable);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Find which variable is referenced in WHERE
|
|
143
|
+
const referencedVars = new Set();
|
|
144
|
+
collectReferencedVars(where, referencedVars);
|
|
145
|
+
// Filter to only include known pattern variables
|
|
146
|
+
const patternVars = [...referencedVars].filter(v => allVars.has(v));
|
|
147
|
+
// We only support single-node WHERE for now
|
|
148
|
+
if (patternVars.length === 1) {
|
|
149
|
+
return patternVars[0];
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Collect all variable names referenced in a WHERE condition.
|
|
155
|
+
*/
|
|
156
|
+
function collectReferencedVars(condition, vars) {
|
|
157
|
+
if (condition.left?.type === "property" && condition.left.variable) {
|
|
158
|
+
vars.add(condition.left.variable);
|
|
159
|
+
}
|
|
160
|
+
if (condition.right?.type === "property" && condition.right.variable) {
|
|
161
|
+
vars.add(condition.right.variable);
|
|
162
|
+
}
|
|
163
|
+
if (condition.conditions) {
|
|
164
|
+
for (const c of condition.conditions) {
|
|
165
|
+
collectReferencedVars(c, vars);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Check if WHERE contains an equality filter on the anchor variable.
|
|
171
|
+
* This indicates the anchor set will be small (good for hybrid).
|
|
172
|
+
*/
|
|
173
|
+
function hasAnchorEqualityFilter(where, anchorVar) {
|
|
174
|
+
// Check if this condition is an equality comparison on the anchor
|
|
175
|
+
if (where.type === "comparison" && where.operator === "=") {
|
|
176
|
+
const leftIsAnchor = where.left?.type === "property" && where.left.variable === anchorVar;
|
|
177
|
+
const rightIsAnchor = where.right?.type === "property" && where.right.variable === anchorVar;
|
|
178
|
+
// One side should be anchor property, other side should be a value/param
|
|
179
|
+
if (leftIsAnchor && where.right?.type !== "property") {
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
if (rightIsAnchor && where.left?.type !== "property") {
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Check AND conditions (any equality filter is sufficient)
|
|
187
|
+
if (where.type === "and" && where.conditions) {
|
|
188
|
+
return where.conditions.some(c => hasAnchorEqualityFilter(c, anchorVar));
|
|
189
|
+
}
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Convert edge direction from parser format to Direction type.
|
|
194
|
+
*/
|
|
195
|
+
function edgeDirectionToDirection(direction) {
|
|
196
|
+
switch (direction) {
|
|
197
|
+
case "right":
|
|
198
|
+
return "out";
|
|
199
|
+
case "left":
|
|
200
|
+
return "in";
|
|
201
|
+
case "none":
|
|
202
|
+
return "both";
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Check if an expression contains an aggregation function.
|
|
207
|
+
*/
|
|
208
|
+
function hasAggregationFunction(expr) {
|
|
209
|
+
if (!expr)
|
|
210
|
+
return false;
|
|
211
|
+
if (expr.type === "function") {
|
|
212
|
+
const aggFunctions = ["count", "sum", "avg", "min", "max", "collect", "stdev", "stdevp"];
|
|
213
|
+
// Check both name and functionName (parser uses different fields)
|
|
214
|
+
const funcName = (expr.name || expr.functionName || "").toLowerCase();
|
|
215
|
+
if (aggFunctions.includes(funcName)) {
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
// Check arguments recursively
|
|
219
|
+
if (expr.args) {
|
|
220
|
+
return expr.args.some((arg) => hasAggregationFunction(arg));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// Check for aggregation in nested expressions
|
|
224
|
+
if (expr.type === "binary") {
|
|
225
|
+
return hasAggregationFunction(expr.left) || hasAggregationFunction(expr.right);
|
|
226
|
+
}
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Check if a query's structure matches a hybrid-compatible pattern.
|
|
231
|
+
*
|
|
232
|
+
* Supported patterns:
|
|
233
|
+
* (a:Label)-[*min..max]->(b:Label)-[:TYPE]->(c:Label) -- original
|
|
234
|
+
* (a)-[*]->(b)-[:R1]->(c)-[:R2]->(d) -- longer chains
|
|
235
|
+
* (a)-[*]->(b)-[*]->(c) -- multiple var-length
|
|
236
|
+
* (a)-[:R1]->(b)-[*]->(c) -- var-length anywhere
|
|
237
|
+
*
|
|
238
|
+
* Requirements:
|
|
239
|
+
* - No mutations (CREATE, SET, DELETE, MERGE)
|
|
240
|
+
* - Has RETURN clause
|
|
241
|
+
* - Exactly one MATCH clause
|
|
242
|
+
* - At least 1 relationship pattern
|
|
243
|
+
* - At least one variable-length edge
|
|
244
|
+
* - No relationship property predicates (not supported in hybrid)
|
|
245
|
+
* - All nodes must have labels (checked in analyzeForHybrid)
|
|
246
|
+
*/
|
|
247
|
+
export function isHybridCompatiblePattern(query) {
|
|
248
|
+
// Must not have mutations
|
|
249
|
+
const hasMutations = query.clauses.some((c) => ["CREATE", "SET", "DELETE", "MERGE"].includes(c.type));
|
|
250
|
+
if (hasMutations) {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
// Must have RETURN
|
|
254
|
+
const returnClause = query.clauses.find((c) => c.type === "RETURN");
|
|
255
|
+
if (!returnClause) {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
// Must not have ORDER BY (not supported in hybrid)
|
|
259
|
+
if (returnClause.orderBy && returnClause.orderBy.length > 0) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
// Must not have aggregation functions in RETURN (not supported in hybrid)
|
|
263
|
+
const hasAggregation = returnClause.items.some((item) => hasAggregationFunction(item.expression));
|
|
264
|
+
if (hasAggregation) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
// Must have exactly one MATCH clause
|
|
268
|
+
const matchClauses = query.clauses.filter((c) => c.type === "MATCH" || c.type === "OPTIONAL_MATCH");
|
|
269
|
+
if (matchClauses.length !== 1) {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
const matchClause = matchClauses[0];
|
|
273
|
+
// Get relationship patterns
|
|
274
|
+
const relPatterns = matchClause.patterns.filter((p) => "edge" in p);
|
|
275
|
+
// Must have at least 1 relationship pattern
|
|
276
|
+
if (relPatterns.length < 1) {
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
// Suitable for hybrid if has at least one variable-length edge
|
|
280
|
+
const hasVarLength = relPatterns.some((rel) => rel.edge.minHops !== undefined || rel.edge.maxHops !== undefined);
|
|
281
|
+
// Multi-hop fixed-length patterns (2+ hops) benefit from hybrid ONLY if
|
|
282
|
+
// the anchor node is filtered (otherwise SQL join is more efficient)
|
|
283
|
+
const isMultiHop = relPatterns.length >= 2;
|
|
284
|
+
if (!hasVarLength && !isMultiHop) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
// For multi-hop without var-length, require anchor filtering
|
|
288
|
+
if (isMultiHop && !hasVarLength) {
|
|
289
|
+
const anchorNode = relPatterns[0].source;
|
|
290
|
+
const anchorVar = anchorNode.variable;
|
|
291
|
+
// Check for inline property filter on anchor
|
|
292
|
+
const hasInlineFilter = anchorNode.properties && Object.keys(anchorNode.properties).length > 0;
|
|
293
|
+
// Check for WHERE clause filtering anchor with equality
|
|
294
|
+
let hasWhereFilter = false;
|
|
295
|
+
if (matchClause.where && anchorVar) {
|
|
296
|
+
hasWhereFilter = hasAnchorEqualityFilter(matchClause.where, anchorVar);
|
|
297
|
+
}
|
|
298
|
+
if (!hasInlineFilter && !hasWhereFilter) {
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
// Must not have relationship property predicates (not supported in hybrid)
|
|
303
|
+
const hasEdgeProperties = relPatterns.some((rel) => rel.edge.properties && Object.keys(rel.edge.properties).length > 0);
|
|
304
|
+
if (hasEdgeProperties) {
|
|
305
|
+
return false;
|
|
306
|
+
}
|
|
307
|
+
return true;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Extract node information (label, properties) from a NodePattern.
|
|
311
|
+
*/
|
|
312
|
+
export function extractNodeInfo(node, params) {
|
|
313
|
+
// Must have at least one label
|
|
314
|
+
if (!node.label) {
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
// Handle label as string or string[]
|
|
318
|
+
const label = Array.isArray(node.label) ? node.label[0] : node.label;
|
|
319
|
+
if (!label) {
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
const properties = {};
|
|
323
|
+
// Extract and resolve properties
|
|
324
|
+
if (node.properties) {
|
|
325
|
+
for (const [key, value] of Object.entries(node.properties)) {
|
|
326
|
+
properties[key] = resolvePropertyValue(value, params);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return { label, properties };
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Resolve a property value, handling parameter references.
|
|
333
|
+
*/
|
|
334
|
+
function resolvePropertyValue(value, params) {
|
|
335
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
336
|
+
return value;
|
|
337
|
+
}
|
|
338
|
+
if (typeof value === "object" && value !== null) {
|
|
339
|
+
if ("type" in value && value.type === "parameter") {
|
|
340
|
+
const paramRef = value;
|
|
341
|
+
return params[paramRef.name];
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return value;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Convert a WHERE condition to a filter function for the middle node.
|
|
348
|
+
* Returns null if the condition references nodes other than the middle node,
|
|
349
|
+
* or if it contains unsupported expressions.
|
|
350
|
+
*/
|
|
351
|
+
export function convertWhereToFilter(where, middleVar, params) {
|
|
352
|
+
// No WHERE clause - return identity filter
|
|
353
|
+
if (!where) {
|
|
354
|
+
return () => true;
|
|
355
|
+
}
|
|
356
|
+
return convertCondition(where, middleVar, params);
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Convert a single WHERE condition to a filter function.
|
|
360
|
+
*/
|
|
361
|
+
function convertCondition(condition, middleVar, params) {
|
|
362
|
+
switch (condition.type) {
|
|
363
|
+
case "comparison":
|
|
364
|
+
return convertComparison(condition, middleVar, params);
|
|
365
|
+
case "and": {
|
|
366
|
+
if (!condition.conditions)
|
|
367
|
+
return null;
|
|
368
|
+
const filters = condition.conditions.map((c) => convertCondition(c, middleVar, params));
|
|
369
|
+
if (filters.some((f) => f === null))
|
|
370
|
+
return null;
|
|
371
|
+
return (node) => filters.every((f) => f(node));
|
|
372
|
+
}
|
|
373
|
+
case "or": {
|
|
374
|
+
if (!condition.conditions)
|
|
375
|
+
return null;
|
|
376
|
+
const filters = condition.conditions.map((c) => convertCondition(c, middleVar, params));
|
|
377
|
+
if (filters.some((f) => f === null))
|
|
378
|
+
return null;
|
|
379
|
+
return (node) => filters.some((f) => f(node));
|
|
380
|
+
}
|
|
381
|
+
case "isNotNull": {
|
|
382
|
+
const propInfo = extractPropertyAccess(condition.left, middleVar);
|
|
383
|
+
if (!propInfo)
|
|
384
|
+
return null;
|
|
385
|
+
return (node) => {
|
|
386
|
+
const value = node.properties[propInfo.property];
|
|
387
|
+
return value !== null && value !== undefined;
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
case "isNull": {
|
|
391
|
+
const propInfo = extractPropertyAccess(condition.left, middleVar);
|
|
392
|
+
if (!propInfo)
|
|
393
|
+
return null;
|
|
394
|
+
return (node) => {
|
|
395
|
+
const value = node.properties[propInfo.property];
|
|
396
|
+
return value === null || value === undefined;
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
default:
|
|
400
|
+
// Unsupported condition type
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Convert a comparison condition to a filter function.
|
|
406
|
+
*/
|
|
407
|
+
function convertComparison(condition, middleVar, params) {
|
|
408
|
+
if (!condition.left || !condition.right || !condition.operator) {
|
|
409
|
+
return null;
|
|
410
|
+
}
|
|
411
|
+
// Check if left side is a property access on the middle node
|
|
412
|
+
const propInfo = extractPropertyAccess(condition.left, middleVar);
|
|
413
|
+
if (!propInfo) {
|
|
414
|
+
return null;
|
|
415
|
+
}
|
|
416
|
+
// Extract the comparison value from the right side
|
|
417
|
+
const rightValue = extractLiteralValue(condition.right, params);
|
|
418
|
+
if (rightValue === undefined) {
|
|
419
|
+
// Right side might reference another node - not supported
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
const { property } = propInfo;
|
|
423
|
+
const op = condition.operator;
|
|
424
|
+
return (node) => {
|
|
425
|
+
const leftValue = node.properties[property];
|
|
426
|
+
return compareValues(leftValue, op, rightValue);
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Extract property access info from an expression.
|
|
431
|
+
* Returns null if the expression is not a property access on the target variable.
|
|
432
|
+
*/
|
|
433
|
+
function extractPropertyAccess(expr, targetVar) {
|
|
434
|
+
if (!expr)
|
|
435
|
+
return null;
|
|
436
|
+
if (expr.type === "property" && expr.variable === targetVar && expr.property) {
|
|
437
|
+
return { variable: expr.variable, property: expr.property };
|
|
438
|
+
}
|
|
439
|
+
return null;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Extract a literal value from an expression.
|
|
443
|
+
* Returns undefined if the expression is not a literal or parameter.
|
|
444
|
+
*/
|
|
445
|
+
function extractLiteralValue(expr, params) {
|
|
446
|
+
if (!expr)
|
|
447
|
+
return undefined;
|
|
448
|
+
if (expr.type === "literal") {
|
|
449
|
+
return expr.value;
|
|
450
|
+
}
|
|
451
|
+
if (expr.type === "parameter" && expr.name) {
|
|
452
|
+
return params[expr.name];
|
|
453
|
+
}
|
|
454
|
+
// Check for property access on a different node (not supported)
|
|
455
|
+
if (expr.type === "property") {
|
|
456
|
+
return undefined;
|
|
457
|
+
}
|
|
458
|
+
return undefined;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Compare two values with the given operator.
|
|
462
|
+
*/
|
|
463
|
+
function compareValues(left, operator, right) {
|
|
464
|
+
switch (operator) {
|
|
465
|
+
case "=":
|
|
466
|
+
return left === right;
|
|
467
|
+
case "<>":
|
|
468
|
+
return left !== right;
|
|
469
|
+
case "<":
|
|
470
|
+
return left < right;
|
|
471
|
+
case ">":
|
|
472
|
+
return left > right;
|
|
473
|
+
case "<=":
|
|
474
|
+
return left <= right;
|
|
475
|
+
case ">=":
|
|
476
|
+
return left >= right;
|
|
477
|
+
default:
|
|
478
|
+
return false;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
//# sourceMappingURL=query-planner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-planner.js","sourceRoot":"","sources":["../../src/engine/query-planner.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAeH,4DAA4D;AAC5D,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAW7B;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAY,EACZ,MAA+B;IAE/B,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,oDAAoD,EAAE,CAAC;IAC3F,CAAC;IAED,2BAA2B;IAC3B,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAgB,CAAC;IACjF,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAC9D,CAAC;IAED,gCAAgC;IAChC,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAC7C,CAAC,CAAC,EAA4B,EAAE,CAAC,MAAM,IAAI,CAAC,CAC7C,CAAC;IAEF,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,sCAAsC,EAAE,CAAC;IAC7E,CAAC;IAED,uDAAuD;IACvD,MAAM,UAAU,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClE,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC;IACtE,CAAC;IAED,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,IAAI,OAAO,CAAC;IAE5D,6CAA6C;IAC7C,MAAM,KAAK,GAA8C,EAAE,CAAC;IAE5D,0EAA0E;IAC1E,IAAI,eAAe,GAAkB,IAAI,CAAC;IAC1C,IAAI,iBAAiB,GAAW,CAAC,CAAC,CAAC;IAEnC,uDAAuD;IACvD,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;QACtB,eAAe,GAAG,kBAAkB,CAAC,WAAW,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QAE3B,oBAAoB;QACpB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC;QAE7E,MAAM,GAAG,GAAa;YACpB,QAAQ,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;YAC3B,SAAS,EAAE,wBAAwB,CAAC,IAAI,CAAC,SAAS,CAAC;YACnD,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9C,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;SAC/D,CAAC;QAEF,2BAA2B;QAC3B,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC;QACpF,CAAC;QAED,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAExD,6CAA6C;QAC7C,MAAM,WAAW,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC;YACjD,CAAC,CAAC,oBAAoB,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC;YAC5D,CAAC,CAAC,SAAS,CAAC;QAEd,gEAAgE;QAChE,IAAI,eAAe,KAAK,SAAS,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YAC1D,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,2CAA2C,EAAE,CAAC;QAClF,CAAC;QAED,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;YAClC,iBAAiB,GAAG,CAAC,CAAC;QACxB,CAAC;QAED,0DAA0D;QAC1D,MAAM,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC;QAC1C,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QAE3D,IAAI,UAAuD,CAAC;QAC5D,IAAI,cAAc,IAAI,WAAW,EAAE,CAAC;YAClC,mDAAmD;YACnD,UAAU,GAAG,CAAC,IAAgB,EAAE,EAAE;gBAChC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;oBACvD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,KAAK;wBAAE,OAAO,KAAK,CAAC;gBACnD,CAAC;gBACD,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;YAC3B,CAAC,CAAC;QACJ,CAAC;aAAM,IAAI,cAAc,EAAE,CAAC;YAC1B,8BAA8B;YAC9B,UAAU,GAAG,CAAC,IAAgB,EAAE,EAAE;gBAChC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;oBACvD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,KAAK;wBAAE,OAAO,KAAK,CAAC;gBACnD,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC,CAAC;QACJ,CAAC;aAAM,IAAI,WAAW,EAAE,CAAC;YACvB,UAAU,GAAG,WAAW,CAAC;QAC3B,CAAC;QAED,MAAM,IAAI,GAAc;YACtB,QAAQ,EAAE,SAAS;YACnB,KAAK,EAAE,UAAU,CAAC,KAAK;YACvB,MAAM,EAAE,UAAU;SACnB,CAAC;QAEF,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED,kFAAkF;IAClF,IAAI,WAAW,CAAC,KAAK,IAAI,eAAe,IAAI,iBAAiB,KAAK,CAAC,CAAC,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QACtG,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,0DAA0D,EAAE,CAAC;IACjG,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE;YACN,MAAM,EAAE;gBACN,QAAQ,EAAE,SAAS;gBACnB,KAAK,EAAE,UAAU,CAAC,KAAK;aACxB;YACD,WAAW,EAAE,UAAU,CAAC,UAAU;YAClC,KAAK;SACN;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CACzB,KAAqB,EACrB,WAAkC;IAElC,yCAAyC;IACzC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,6CAA6C;IAC7C,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;IACzC,qBAAqB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IAE7C,iDAAiD;IACjD,MAAM,WAAW,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAEpE,4CAA4C;IAC5C,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,SAAyB,EAAE,IAAiB;IACzE,IAAI,SAAS,CAAC,IAAI,EAAE,IAAI,KAAK,UAAU,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnE,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,SAAS,CAAC,KAAK,EAAE,IAAI,KAAK,UAAU,IAAI,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACrE,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;QACzB,KAAK,MAAM,CAAC,IAAI,SAAS,CAAC,UAAU,EAAE,CAAC;YACrC,qBAAqB,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,uBAAuB,CAAC,KAAqB,EAAE,SAAiB;IACvE,kEAAkE;IAClE,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,QAAQ,KAAK,GAAG,EAAE,CAAC;QAC1D,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC;QAC1F,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,EAAE,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC;QAE7F,yEAAyE;QACzE,IAAI,YAAY,IAAI,KAAK,CAAC,KAAK,EAAE,IAAI,KAAK,UAAU,EAAE,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,aAAa,IAAI,KAAK,CAAC,IAAI,EAAE,IAAI,KAAK,UAAU,EAAE,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,2DAA2D;IAC3D,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QAC7C,OAAO,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,wBAAwB,CAAC,SAAoC;IACpE,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,OAAO;YACV,OAAO,KAAK,CAAC;QACf,KAAK,MAAM;YACT,OAAO,IAAI,CAAC;QACd,KAAK,MAAM;YACT,OAAO,MAAM,CAAC;IAClB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAAC,IAA4B;IAC1D,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IAExB,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC7B,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QACzF,kEAAkE;QAClE,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACtE,IAAI,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,8BAA8B;QAC9B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAe,EAAE,EAAE,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,OAAO,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjF,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAAY;IACpD,0BAA0B;IAC1B,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAC5C,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CACtD,CAAC;IACF,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,mBAAmB;IACnB,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAA6B,CAAC;IAChG,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,mDAAmD;IACnD,IAAI,YAAY,CAAC,OAAO,IAAI,YAAY,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,0EAA0E;IAC1E,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACtD,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC,CACxC,CAAC;IACF,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,qCAAqC;IACrC,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAAC;IACpG,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAgB,CAAC;IAEnD,4BAA4B;IAC5B,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAC7C,CAAC,CAAC,EAA4B,EAAE,CAAC,MAAM,IAAI,CAAC,CAC7C,CAAC;IAEF,4CAA4C;IAC5C,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,+DAA+D;IAC/D,MAAM,YAAY,GAAG,WAAW,CAAC,IAAI,CACnC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAC1E,CAAC;IAEF,wEAAwE;IACxE,qEAAqE;IACrE,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,IAAI,CAAC,CAAC;IAE3C,IAAI,CAAC,YAAY,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,6DAA6D;IAC7D,IAAI,UAAU,IAAI,CAAC,YAAY,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC;QAEtC,6CAA6C;QAC7C,MAAM,eAAe,GAAG,UAAU,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QAE/F,wDAAwD;QACxD,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,IAAI,WAAW,CAAC,KAAK,IAAI,SAAS,EAAE,CAAC;YACnC,cAAc,GAAG,uBAAuB,CAAC,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACzE,CAAC;QAED,IAAI,CAAC,eAAe,IAAI,CAAC,cAAc,EAAE,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,MAAM,iBAAiB,GAAG,WAAW,CAAC,IAAI,CACxC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAC5E,CAAC;IACF,IAAI,iBAAiB,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAiB,EACjB,MAA+B;IAE/B,+BAA+B;IAC/B,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,qCAAqC;IACrC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;IACrE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAA4B,EAAE,CAAC;IAE/C,iCAAiC;IACjC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3D,UAAU,CAAC,GAAG,CAAC,GAAG,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAC3B,KAAoB,EACpB,MAA+B;IAE/B,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QAC3G,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAClD,MAAM,QAAQ,GAAG,KAA4C,CAAC;YAC9D,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAiC,EACjC,SAAiB,EACjB,MAA+B;IAE/B,2CAA2C;IAC3C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC;IACpB,CAAC;IAED,OAAO,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CACvB,SAAyB,EACzB,SAAiB,EACjB,MAA+B;IAE/B,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;QACvB,KAAK,YAAY;YACf,OAAO,iBAAiB,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QAEzD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,IAAI,CAAC,SAAS,CAAC,UAAU;gBAAE,OAAO,IAAI,CAAC;YACvC,MAAM,OAAO,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;YACxF,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;YACjD,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAClD,CAAC;QAED,KAAK,IAAI,CAAC,CAAC,CAAC;YACV,IAAI,CAAC,SAAS,CAAC,UAAU;gBAAE,OAAO,IAAI,CAAC;YACvC,MAAM,OAAO,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;YACxF,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;YACjD,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QACjD,CAAC;QAED,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,MAAM,QAAQ,GAAG,qBAAqB,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAClE,IAAI,CAAC,QAAQ;gBAAE,OAAO,IAAI,CAAC;YAC3B,OAAO,CAAC,IAAI,EAAE,EAAE;gBACd,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACjD,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC;YAC/C,CAAC,CAAC;QACJ,CAAC;QAED,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,QAAQ,GAAG,qBAAqB,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YAClE,IAAI,CAAC,QAAQ;gBAAE,OAAO,IAAI,CAAC;YAC3B,OAAO,CAAC,IAAI,EAAE,EAAE;gBACd,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACjD,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC;YAC/C,CAAC,CAAC;QACJ,CAAC;QAED;YACE,6BAA6B;YAC7B,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CACxB,SAAyB,EACzB,SAAiB,EACjB,MAA+B;IAE/B,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6DAA6D;IAC7D,MAAM,QAAQ,GAAG,qBAAqB,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAClE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mDAAmD;IACnD,MAAM,UAAU,GAAG,mBAAmB,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAChE,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,0DAA0D;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC;IAC9B,MAAM,EAAE,GAAG,SAAS,CAAC,QAAQ,CAAC;IAE9B,OAAO,CAAC,IAAI,EAAE,EAAE;QACd,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC5C,OAAO,aAAa,CAAC,SAAS,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;IAClD,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,qBAAqB,CAC5B,IAA4B,EAC5B,SAAiB;IAEjB,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7E,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC9D,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAC1B,IAA4B,EAC5B,MAA+B;IAE/B,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAE5B,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QAC3C,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IAED,gEAAgE;IAChE,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC7B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CACpB,IAAa,EACb,QAA8C,EAC9C,KAAc;IAEd,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,GAAG;YACN,OAAO,IAAI,KAAK,KAAK,CAAC;QACxB,KAAK,IAAI;YACP,OAAO,IAAI,KAAK,KAAK,CAAC;QACxB,KAAK,GAAG;YACN,OAAQ,IAAe,GAAI,KAAgB,CAAC;QAC9C,KAAK,GAAG;YACN,OAAQ,IAAe,GAAI,KAAgB,CAAC;QAC9C,KAAK,IAAI;YACP,OAAQ,IAAe,IAAK,KAAgB,CAAC;QAC/C,KAAK,IAAI;YACP,OAAQ,IAAe,IAAK,KAAgB,CAAC;QAC/C;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subgraph Loader - loads bounded subgraphs from SQLite into memory.
|
|
3
|
+
* Uses indexed SQL queries for anchor node discovery and bounded
|
|
4
|
+
* recursive CTEs for subgraph extraction.
|
|
5
|
+
*/
|
|
6
|
+
import { GraphDatabase } from "../db.js";
|
|
7
|
+
import { MemoryGraph, Direction } from "./memory-graph.js";
|
|
8
|
+
export interface SubgraphBounds {
|
|
9
|
+
/** Starting node IDs for subgraph expansion */
|
|
10
|
+
anchorNodeIds: string[];
|
|
11
|
+
/** Maximum depth to expand from anchors */
|
|
12
|
+
maxDepth: number;
|
|
13
|
+
/** Edge types to traverse (null = all types) */
|
|
14
|
+
edgeTypes: string[] | null;
|
|
15
|
+
/** Direction of traversal */
|
|
16
|
+
direction: Direction;
|
|
17
|
+
}
|
|
18
|
+
export interface PropertyFilter {
|
|
19
|
+
[key: string]: unknown;
|
|
20
|
+
}
|
|
21
|
+
export declare class SubgraphLoader {
|
|
22
|
+
private db;
|
|
23
|
+
constructor(db: GraphDatabase);
|
|
24
|
+
/**
|
|
25
|
+
* Find anchor nodes by label and optional property filters.
|
|
26
|
+
* Uses indexed queries for efficient lookup.
|
|
27
|
+
*/
|
|
28
|
+
findAnchors(label: string, propertyFilters?: PropertyFilter): string[];
|
|
29
|
+
/**
|
|
30
|
+
* Load a bounded subgraph into memory.
|
|
31
|
+
* Uses a recursive CTE to collect reachable node IDs within bounds,
|
|
32
|
+
* then bulk fetches nodes and edges.
|
|
33
|
+
*/
|
|
34
|
+
loadSubgraph(bounds: SubgraphBounds): MemoryGraph;
|
|
35
|
+
/**
|
|
36
|
+
* Collect all node IDs reachable from anchors within the given bounds.
|
|
37
|
+
* Uses BFS with depth tracking.
|
|
38
|
+
*/
|
|
39
|
+
private collectReachableNodes;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=subgraph-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subgraph-loader.d.ts","sourceRoot":"","sources":["../../src/engine/subgraph-loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,aAAa,EAAoB,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,SAAS,EAAgD,MAAM,mBAAmB,CAAC;AAEzG,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC3B,6BAA6B;IAC7B,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAMD,qBAAa,cAAc;IACb,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,aAAa;IAErC;;;OAGG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,cAAc,GAAG,MAAM,EAAE;IAmBtE;;;;OAIG;IACH,YAAY,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW;IAkGjD;;;OAGG;IACH,OAAO,CAAC,qBAAqB;CA0E9B"}
|