MCPcopy Create free account
hub / github.com/RedisGraph/RedisGraph / _ExecutionPlan_UnionPlans

Function _ExecutionPlan_UnionPlans

src/execution_plan/execution_plan.c:48–133  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

46}
47
48static ExecutionPlan *_ExecutionPlan_UnionPlans(AST *ast) {
49 uint end_offset = 0;
50 uint start_offset = 0;
51 uint clause_count = cypher_ast_query_nclauses(ast->root);
52 uint *union_indices = AST_GetClauseIndices(ast, CYPHER_AST_UNION);
53 array_append(union_indices, clause_count);
54 int union_count = array_len(union_indices);
55 ASSERT(union_count > 1);
56
57 // Placeholder for each execution plan, these all will be joined
58 // via a single UNION operation
59 ExecutionPlan *plans[union_count];
60
61 for(int i = 0; i < union_count; i++) {
62 // Create an AST segment from which we will build an execution plan.
63 end_offset = union_indices[i];
64 AST *ast_segment = AST_NewSegment(ast, start_offset, end_offset);
65 plans[i] = ExecutionPlan_FromTLS_AST();
66 AST_Free(ast_segment); // Free the AST segment.
67
68 // Next segment starts where this one ends.
69 start_offset = union_indices[i] + 1;
70 }
71
72 QueryCtx_SetAST(ast); // AST segments have been freed, set master AST in QueryCtx.
73
74 array_free(union_indices);
75
76 /* Join streams:
77 * MATCH (a) RETURN a UNION MATCH (a) RETURN a ....
78 * left stream: [Scan]->[Project]->[Results]
79 * right stream: [Scan]->[Project]->[Results]
80 *
81 * Joined:
82 * left stream: [Scan]->[Project]
83 * right stream: [Scan]->[Project]
84 * [Union]->[Distinct]->[Result] */
85 ExecutionPlan *plan = ExecutionPlan_NewEmptyExecutionPlan();
86 plan->record_map = raxNew();
87
88 OpBase *results_op = NewResultsOp(plan);
89 OpBase *parent = results_op;
90 ExecutionPlan_UpdateRoot(plan, results_op);
91
92 // Introduce distinct only if `ALL` isn't specified.
93 const cypher_astnode_t *union_clause = AST_GetClause(ast, CYPHER_AST_UNION,
94 NULL);
95 if(!cypher_ast_union_has_all(union_clause)) {
96 uint clause_count = cypher_ast_query_nclauses(ast->root);
97 const cypher_astnode_t *last_clause = cypher_ast_query_get_clause(ast->root, clause_count - 1);
98 if(cypher_astnode_type(last_clause) == CYPHER_AST_RETURN) {
99 uint projection_count = cypher_ast_return_nprojections(last_clause);
100 // Build a stack array to hold the aliases to perform Distinct on
101 const char *projections[projection_count];
102 for(uint i = 0; i < projection_count; i++) {
103 // Retrieve aliases from the RETURN clause
104 const cypher_astnode_t *projection = cypher_ast_return_get_projection(last_clause, i);
105 const cypher_astnode_t *alias = cypher_ast_projection_get_alias(projection);

Callers 1

Calls 15

AST_GetClauseIndicesFunction · 0.85
array_lenFunction · 0.85
AST_NewSegmentFunction · 0.85
AST_FreeFunction · 0.85
QueryCtx_SetASTFunction · 0.85
array_freeFunction · 0.85
NewResultsOpFunction · 0.85
ExecutionPlan_UpdateRootFunction · 0.85
AST_GetClauseFunction · 0.85
NewDistinctOpFunction · 0.85

Tested by

no test coverage detected