MCPcopy Create free account
hub / github.com/codemix/graph / processLegacyQuery

Function processLegacyQuery

packages/graph/src/astToSteps.ts:326–469  ·  view source on GitHub ↗

* Process a query using the legacy flat structure (backward compatibility).

(query: Query, steps: Step<any>[])

Source from the content-addressed store, hash-verified

324 * Process a query using the legacy flat structure (backward compatibility).
325 */
326function processLegacyQuery(query: Query, steps: Step<any>[]): void {
327 // 1. Convert MATCH clauses patterns to steps
328 // Process regular MATCH clauses first, then OPTIONAL MATCH clauses
329 // If the first MATCH is OPTIONAL, we need a StartStep to provide an initial path
330 // so that OptionalMatchStep has an input to extend with null bindings
331 const firstMatchIsOptional = query.matches.length > 0 && query.matches[0]!.optional;
332 if (firstMatchIsOptional) {
333 steps.push(new StartStep({}));
334 }
335
336 let hasSeenPreviousMatch = false;
337 for (const matchClause of query.matches) {
338 // Convert the pattern to steps
339 let patternSteps: Step<any>[];
340
341 if (matchClause.pattern.type === "ShortestPathPattern") {
342 patternSteps = convertShortestPathPattern(
343 matchClause.pattern as ShortestPathPattern,
344 matchClause.where,
345 );
346 } else if (matchClause.pattern.type === "MultiPattern") {
347 // Handle comma-separated patterns like MATCH (a), (b)
348 patternSteps = convertMultiPattern(matchClause.pattern as MultiPattern, matchClause.where);
349 } else {
350 // For OPTIONAL MATCH after a previous MATCH, the first node may reference
351 // a previously bound variable. We enable anchor detection (anchoredToInput: true)
352 // when there are previous steps in the query that may have bound variables.
353 // The anchor heuristic will only trigger if the first node has no labels.
354 const isAnchoredContext = matchClause.optional && hasSeenPreviousMatch;
355 patternSteps = convertPattern(
356 matchClause.pattern as Pattern,
357 matchClause.where,
358 isAnchoredContext,
359 );
360 }
361
362 if (matchClause.optional) {
363 // Wrap in OptionalMatchStep for OPTIONAL MATCH
364 // skipAnchor: Only skip anchor if there was a previous MATCH that bound variables
365 const skipAnchor = hasSeenPreviousMatch;
366 const variables = extractPatternVariables(matchClause.pattern, skipAnchor);
367 steps.push(new OptionalMatchStep({ variables }, patternSteps as Step<any>[]));
368 } else {
369 steps.push(...patternSteps);
370 }
371 hasSeenPreviousMatch = true;
372 }
373
374 // 1b. If no MATCH clauses but there are mutations or list operations, add a StartStep
375 // to provide an initial empty path for CREATE/MERGE/UNWIND to work with
376 const hasMutations =
377 (query.merge && query.merge.length > 0) ||
378 query.create ||
379 query.set ||
380 query.remove ||
381 query.delete ||
382 (query.foreach && query.foreach.length > 0);
383

Callers 1

astToStepsFunction · 0.85

Calls 14

convertMultiPatternFunction · 0.85
convertPatternFunction · 0.85
extractPatternVariablesFunction · 0.85
convertWithClauseFunction · 0.85
convertUnwindClauseFunction · 0.85
convertCallClauseFunction · 0.85
convertForeachClauseFunction · 0.85
convertMergeClauseFunction · 0.85
convertCreateClauseFunction · 0.85
convertSetClauseFunction · 0.85
convertRemoveClauseFunction · 0.85

Tested by

no test coverage detected