From 860e5bdd66407f98c10e774e8825235e067c1e5a Mon Sep 17 00:00:00 2001 From: nafraf Date: Tue, 27 Jun 2023 17:14:02 -0500 Subject: [PATCH 1/6] Add functions to push clause to query --- lib/src/ast_call_subquery.c | 16 ++++++++++++++ lib/src/ast_query.c | 44 +++++++++++++++++++++++++++++++++++++ lib/src/cypher-parser.h.in | 36 ++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) diff --git a/lib/src/ast_call_subquery.c b/lib/src/ast_call_subquery.c index bdf1da3..10b2b1d 100644 --- a/lib/src/ast_call_subquery.c +++ b/lib/src/ast_call_subquery.c @@ -99,6 +99,22 @@ void cypher_ast_call_subquery_replace_query node->query = query; } +void cypher_ast_call_subquery_push_clause( + cypher_astnode_t *astnode, + cypher_astnode_t *clause, + unsigned int index +) { + REQUIRE_TYPE(astnode, CYPHER_AST_CALL_SUBQUERY, NULL); + struct call_subquery *subquery_node = + container_of(astnode, struct call_subquery, _astnode); + + cypher_astnode_t *new_query = + cypher_ast_query_push_clause(subquery_node->query, clause, index); + free(subquery_node->query); + astnode->children[0] = new_query; + subquery_node->query = new_query; +} + cypher_astnode_t *clone(const cypher_astnode_t *self, cypher_astnode_t **children) { diff --git a/lib/src/ast_query.c b/lib/src/ast_query.c index da15d3f..0d0147a 100644 --- a/lib/src/ast_query.c +++ b/lib/src/ast_query.c @@ -205,6 +205,50 @@ void cypher_ast_query_replace_clauses( astnode->nchildren -= end_index - start_index; } +cypher_astnode_t *cypher_ast_query_push_clause( + cypher_astnode_t *astnode, + cypher_astnode_t *clause, + unsigned int index +) +{ + REQUIRE_TYPE(astnode, CYPHER_AST_QUERY, NULL); + REQUIRE_TYPE(clause, CYPHER_AST_QUERY_CLAUSE, NULL); + struct query *query = container_of(astnode, struct query, _astnode); + + unsigned int nchildren = astnode->nchildren + 1; + unsigned int nclauses = query->nclauses + 1; + + cypher_astnode_t **clauses = calloc(nclauses, sizeof(cypher_astnode_t *)); + if (clauses == NULL) { + return NULL; + } + + cypher_astnode_t **children = calloc(nchildren, sizeof(cypher_astnode_t *)); + if (children == NULL) { + return NULL; + } + + //insert new clause + for(uint i = nclauses - 1; i > index; i--) { + clauses[i] = query->clauses[i - 1]; + children[i] = query->clauses[i - 1]; + } + + clauses[index] = clause; + children[index] = clause; + + for(int i = index - 1; i >= 0; i--) { + clauses[i] = query->clauses[i]; + children[i] = clauses[i]; + } + + cypher_astnode_t *new_query = cypher_ast_query(NULL, 0, clauses, nclauses, + children, nchildren, astnode->range); + free(clauses); + free(children); + + return new_query; +} ssize_t detailstr(const cypher_astnode_t *self, char *str, size_t size) { diff --git a/lib/src/cypher-parser.h.in b/lib/src/cypher-parser.h.in index e529b80..c6e1388 100644 --- a/lib/src/cypher-parser.h.in +++ b/lib/src/cypher-parser.h.in @@ -1328,6 +1328,26 @@ void cypher_ast_query_set_clause( void cypher_ast_query_replace_clauses( cypher_astnode_t *astnode, cypher_astnode_t *clause, unsigned int start_index, unsigned int end_index); +/** + * Insert clause at position `index` of a `CYPHER_AST_QUERY` node. + * + * If the node is not an instance of `CYPHER_AST_QUERY` then the result will + * be undefined. + * + * If the clause is not an instance of `CYPHER_AST_QUERY_CLAUSE` then the result + * will be undefined. + * + * @param [node] The AST node. + * @param [clause] The AST clause node. + * @param [index] The index of the new clause. + * @return The query, or NULL if an error occurs. + */ +cypher_astnode_t *cypher_ast_query_push_clause( + cypher_astnode_t *astnode, + cypher_astnode_t *clause, + unsigned int index +); + /** * Replace the clauses of a `CYPHER_AST_FOREACH` node. * @@ -3130,6 +3150,22 @@ void cypher_ast_call_subquery_replace_query cypher_astnode_t *query ); +/** + * Insert a new clause at position `index` of a `CYPHER_AST_CALL_SUBQUERY` node. + * + * If the node is not an instance of `CYPHER_AST_CALL_SUBQUERY` then the + * result will be undefined. + * + * @param [astnode] The AST node. + * @param [query] The query to replace the existing query with. + * @param [index] Position of the new clause + */ +void cypher_ast_call_subquery_push_clause( + cypher_astnode_t *astnode, + cypher_astnode_t *clause, + unsigned int index +); + /** * Get the proc name of a `CYPHER_AST_CALL` node. * From fa1cbcba7a12291dcb3377bf9e6fbfb8f06dce36 Mon Sep 17 00:00:00 2001 From: nafraf Date: Wed, 28 Jun 2023 09:38:52 -0500 Subject: [PATCH 2/6] Add cypher_ast_statement_push_clause() --- lib/src/ast_query.c | 4 +--- lib/src/ast_statement.c | 19 +++++++++++++++++++ lib/src/cypher-parser.h.in | 20 ++++++++++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/lib/src/ast_query.c b/lib/src/ast_query.c index 0d0147a..9513e01 100644 --- a/lib/src/ast_query.c +++ b/lib/src/ast_query.c @@ -233,13 +233,11 @@ cypher_astnode_t *cypher_ast_query_push_clause( clauses[i] = query->clauses[i - 1]; children[i] = query->clauses[i - 1]; } - clauses[index] = clause; children[index] = clause; - for(int i = index - 1; i >= 0; i--) { clauses[i] = query->clauses[i]; - children[i] = clauses[i]; + children[i] = query->clauses[i]; } cypher_astnode_t *new_query = cypher_ast_query(NULL, 0, clauses, nclauses, diff --git a/lib/src/ast_statement.c b/lib/src/ast_statement.c index b65c931..9783694 100644 --- a/lib/src/ast_statement.c +++ b/lib/src/ast_statement.c @@ -92,6 +92,25 @@ void cypher_ast_statement_replace_body } +void cypher_ast_statement_push_clause +( + cypher_astnode_t *astnode, + cypher_astnode_t *clause, + unsigned int index +) +{ + REQUIRE_TYPE(astnode, CYPHER_AST_STATEMENT, NULL); + REQUIRE_TYPE(clause, CYPHER_AST_QUERY_CLAUSE, NULL); + struct statement *node = container_of(astnode, struct statement, _astnode); + + cypher_astnode_t *body = + cypher_ast_query_push_clause(node->body, clause, index); + astnode->children[child_index(astnode, node->body)] = body; + free(node->body); + node->body = body; +} + + cypher_astnode_t *clone(const cypher_astnode_t *self, cypher_astnode_t **children) { diff --git a/lib/src/cypher-parser.h.in b/lib/src/cypher-parser.h.in index c6e1388..f824a4b 100644 --- a/lib/src/cypher-parser.h.in +++ b/lib/src/cypher-parser.h.in @@ -550,6 +550,26 @@ cypher_astnode_t *cypher_ast_statement(cypher_astnode_t * const *options, void cypher_ast_statement_replace_body(cypher_astnode_t *astnode, const cypher_astnode_t *body); +/** + * Insert clause at position `index` of a `CYPHER_AST_STATEMENT` node. + * + * If the node is not an instance of `CYPHER_AST_STATEMENT` then the result will + * be undefined. + * + * If the clause is not an instance of `CYPHER_AST_QUERY_CLAUSE` then the result + * will be undefined. + * + * @param [node] The AST node. + * @param [clause] The AST clause node. + * @param [index] The index of the new clause. + */ +void cypher_ast_statement_push_clause +( + cypher_astnode_t *astnode, + cypher_astnode_t *clause, + unsigned int index +); + /** * Get the number of options in a `CYPHER_AST_STATEMENT` node. * From d5a4449c84b7cc131a604eb12918462cd6a0791f Mon Sep 17 00:00:00 2001 From: nafraf Date: Wed, 28 Jun 2023 15:31:13 -0500 Subject: [PATCH 3/6] Free annotations --- lib/src/ast_call_subquery.c | 10 +++++++++- lib/src/ast_statement.c | 9 ++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/src/ast_call_subquery.c b/lib/src/ast_call_subquery.c index 10b2b1d..e449607 100644 --- a/lib/src/ast_call_subquery.c +++ b/lib/src/ast_call_subquery.c @@ -110,7 +110,15 @@ void cypher_ast_call_subquery_push_clause( cypher_astnode_t *new_query = cypher_ast_query_push_clause(subquery_node->query, clause, index); - free(subquery_node->query); + + if(subquery_node->query != NULL) { + free(subquery_node->query); + while (subquery_node->query->annotations != NULL) + { + cp_release_annotation(subquery_node->query->annotations); + } + } + astnode->children[0] = new_query; subquery_node->query = new_query; } diff --git a/lib/src/ast_statement.c b/lib/src/ast_statement.c index 9783694..0a96ee7 100644 --- a/lib/src/ast_statement.c +++ b/lib/src/ast_statement.c @@ -106,7 +106,14 @@ void cypher_ast_statement_push_clause cypher_astnode_t *body = cypher_ast_query_push_clause(node->body, clause, index); astnode->children[child_index(astnode, node->body)] = body; - free(node->body); + + if(node->body != NULL) { + free(node->body); + while (node->body->annotations != NULL) + { + cp_release_annotation(node->body->annotations); + } + } node->body = body; } From cd99dfdf7070902c2c0f4c8df31cff810017d61a Mon Sep 17 00:00:00 2001 From: nafraf Date: Thu, 29 Jun 2023 07:56:39 -0500 Subject: [PATCH 4/6] Free children --- lib/src/ast_call_subquery.c | 3 ++- lib/src/ast_statement.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/src/ast_call_subquery.c b/lib/src/ast_call_subquery.c index e449607..b258a0f 100644 --- a/lib/src/ast_call_subquery.c +++ b/lib/src/ast_call_subquery.c @@ -112,11 +112,12 @@ void cypher_ast_call_subquery_push_clause( cypher_ast_query_push_clause(subquery_node->query, clause, index); if(subquery_node->query != NULL) { - free(subquery_node->query); while (subquery_node->query->annotations != NULL) { cp_release_annotation(subquery_node->query->annotations); } + free(subquery_node->query->children); + free(subquery_node->query); } astnode->children[0] = new_query; diff --git a/lib/src/ast_statement.c b/lib/src/ast_statement.c index 0a96ee7..a02f4a5 100644 --- a/lib/src/ast_statement.c +++ b/lib/src/ast_statement.c @@ -108,11 +108,12 @@ void cypher_ast_statement_push_clause astnode->children[child_index(astnode, node->body)] = body; if(node->body != NULL) { - free(node->body); while (node->body->annotations != NULL) { cp_release_annotation(node->body->annotations); } + free(node->body->children); + free(node->body); } node->body = body; } From 1e947e45cf797bb51b728d40f35b61819ed9e184 Mon Sep 17 00:00:00 2001 From: nafraf Date: Thu, 29 Jun 2023 10:10:44 -0500 Subject: [PATCH 5/6] Use cypher_astnode_free() --- lib/src/ast_call_subquery.c | 10 +--------- lib/src/ast_statement.c | 11 ++--------- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/lib/src/ast_call_subquery.c b/lib/src/ast_call_subquery.c index b258a0f..edafe0b 100644 --- a/lib/src/ast_call_subquery.c +++ b/lib/src/ast_call_subquery.c @@ -111,15 +111,7 @@ void cypher_ast_call_subquery_push_clause( cypher_astnode_t *new_query = cypher_ast_query_push_clause(subquery_node->query, clause, index); - if(subquery_node->query != NULL) { - while (subquery_node->query->annotations != NULL) - { - cp_release_annotation(subquery_node->query->annotations); - } - free(subquery_node->query->children); - free(subquery_node->query); - } - + cypher_astnode_free(subquery_node->query); astnode->children[0] = new_query; subquery_node->query = new_query; } diff --git a/lib/src/ast_statement.c b/lib/src/ast_statement.c index a02f4a5..9c2af2c 100644 --- a/lib/src/ast_statement.c +++ b/lib/src/ast_statement.c @@ -105,16 +105,9 @@ void cypher_ast_statement_push_clause cypher_astnode_t *body = cypher_ast_query_push_clause(node->body, clause, index); + astnode->children[child_index(astnode, node->body)] = body; - - if(node->body != NULL) { - while (node->body->annotations != NULL) - { - cp_release_annotation(node->body->annotations); - } - free(node->body->children); - free(node->body); - } + cypher_astnode_free(node->body); node->body = body; } From 1271153d224e57f9d4ab3ab60812385ba043202c Mon Sep 17 00:00:00 2001 From: nafraf Date: Thu, 29 Jun 2023 14:06:08 -0500 Subject: [PATCH 6/6] push query clause: from 0 to nclauses --- lib/src/ast_query.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/src/ast_query.c b/lib/src/ast_query.c index 9513e01..b75779e 100644 --- a/lib/src/ast_query.c +++ b/lib/src/ast_query.c @@ -229,15 +229,15 @@ cypher_astnode_t *cypher_ast_query_push_clause( } //insert new clause - for(uint i = nclauses - 1; i > index; i--) { - clauses[i] = query->clauses[i - 1]; - children[i] = query->clauses[i - 1]; + for(uint i = 0; i < index; i++) { + clauses[i] = query->clauses[i]; + children[i] = query->clauses[i]; } clauses[index] = clause; children[index] = clause; - for(int i = index - 1; i >= 0; i--) { - clauses[i] = query->clauses[i]; - children[i] = query->clauses[i]; + for(uint i = index + 1; i < nclauses; i++) { + clauses[i] = query->clauses[i - 1]; + children[i] = query->clauses[i - 1]; } cypher_astnode_t *new_query = cypher_ast_query(NULL, 0, clauses, nclauses,