| 148 | } |
| 149 | |
| 150 | static ExecutionPlan **_process_segments(AST *ast) { |
| 151 | uint nsegments = 0; // number of segments |
| 152 | uint seg_end_idx = 0; // segment clause end index |
| 153 | uint clause_count = 0; // number of clauses |
| 154 | uint seg_start_idx = 0; // segment clause start index |
| 155 | AST *ast_segment = NULL; // segment AST |
| 156 | uint *segment_indices = NULL; // array segment bounds |
| 157 | ExecutionPlan *segment = NULL; // portion of the entire execution plan |
| 158 | ExecutionPlan **segments = NULL; // constructed segments |
| 159 | |
| 160 | clause_count = cypher_ast_query_nclauses(ast->root); |
| 161 | |
| 162 | //-------------------------------------------------------------------------- |
| 163 | // bound segments |
| 164 | //-------------------------------------------------------------------------- |
| 165 | |
| 166 | // retrieve the indices of each WITH clause to properly set |
| 167 | // the segment's bounds. |
| 168 | // Every WITH clause demarcates the beginning of a new segment |
| 169 | segment_indices = AST_GetClauseIndices(ast, CYPHER_AST_WITH); |
| 170 | |
| 171 | // last segment |
| 172 | array_append(segment_indices, clause_count); |
| 173 | nsegments = array_len(segment_indices); |
| 174 | segments = array_new(ExecutionPlan *, nsegments); |
| 175 | |
| 176 | //-------------------------------------------------------------------------- |
| 177 | // process segments |
| 178 | //-------------------------------------------------------------------------- |
| 179 | |
| 180 | seg_start_idx = 0; |
| 181 | for(uint i = 0; i < nsegments; i++) { |
| 182 | seg_end_idx = segment_indices[i]; |
| 183 | |
| 184 | if((seg_end_idx - seg_start_idx) == 0) continue; // skip empty segment |
| 185 | |
| 186 | // slice the AST to only include the clauses in the current segment |
| 187 | AST *ast_segment = AST_NewSegment(ast, seg_start_idx, seg_end_idx); |
| 188 | |
| 189 | // create ExecutionPlan segment that represents this slice of the AST |
| 190 | segment = _process_segment(ast_segment, seg_start_idx, seg_end_idx); |
| 191 | array_append(segments, segment); |
| 192 | |
| 193 | // The next segment will start where the current one ended. |
| 194 | seg_start_idx = seg_end_idx; |
| 195 | } |
| 196 | |
| 197 | // Restore the overall AST. |
| 198 | QueryCtx_SetAST(ast); |
| 199 | array_free(segment_indices); |
| 200 | |
| 201 | return segments; |
| 202 | } |
| 203 | |
| 204 | static bool _ExecutionPlan_HasLocateTaps |
| 205 | ( |
no test coverage detected