| 9 | #include "../util/rmalloc.h" |
| 10 | |
| 11 | AST *AST_MockMatchClause(AST *master_ast, cypher_astnode_t *node, bool node_is_path) { |
| 12 | /* The AST node and its children must be reused directly, |
| 13 | * as cloning causes annotations (entity names) to be lost. |
| 14 | * TODO consider updating parser to improve this. */ |
| 15 | AST *ast = rm_malloc(sizeof(AST)); |
| 16 | ast->referenced_entities = master_ast->referenced_entities; |
| 17 | ast->anot_ctx_collection = master_ast->anot_ctx_collection; |
| 18 | ast->free_root = true; |
| 19 | cypher_astnode_t *pattern; |
| 20 | struct cypher_input_range range = {0}; |
| 21 | const cypher_astnode_t *predicate = NULL; |
| 22 | uint child_count = (node_is_path) ? 1 : cypher_astnode_nchildren(node); |
| 23 | cypher_astnode_t *children[child_count]; |
| 24 | |
| 25 | if(node_is_path) { |
| 26 | /* MERGE clauses and path filters are comprised of a single path. |
| 27 | * Construct a pattern node containing just this path. */ |
| 28 | pattern = cypher_ast_pattern(&node, 1, &node, 1, range); |
| 29 | children[0] = pattern; |
| 30 | } else { |
| 31 | /* OPTIONAL MATCH clauses contain a pattern node |
| 32 | * and possibly a predicate node (containing WHERE conditions). */ |
| 33 | ASSERT(cypher_astnode_type(node) == CYPHER_AST_MATCH); |
| 34 | pattern = (cypher_astnode_t *)cypher_ast_match_get_pattern(node); |
| 35 | predicate = cypher_ast_match_get_predicate(node); |
| 36 | |
| 37 | // Explicitly collect all child nodes from the clause. |
| 38 | for(uint i = 0; i < child_count; i ++) { |
| 39 | children[i] = (cypher_astnode_t *)cypher_astnode_get_child(node, i); |
| 40 | } |
| 41 | } |
| 42 | |
| 43 | // Build a new match clause that holds this pattern. |
| 44 | cypher_astnode_t *match_clause = cypher_ast_match(false, pattern, NULL, 0, predicate, |
| 45 | children, child_count, range); |
| 46 | |
| 47 | // Build a query node holding this clause. |
| 48 | ast->root = cypher_ast_query(NULL, 0, &match_clause, 1, &match_clause, 1, range); |
| 49 | |
| 50 | QueryCtx_SetAST(ast); // Update the TLS. |
| 51 | |
| 52 | return ast; |
| 53 | } |
| 54 | |
| 55 | void AST_MockFree(AST *ast, bool free_pattern) { |
| 56 | /* When freeing the mock AST, we have to be careful to not free any shared node |
no test coverage detected