| 709 | } |
| 710 | |
| 711 | cypher_parse_result_t *parse_query |
| 712 | ( |
| 713 | const char *query // query to parse |
| 714 | ) { |
| 715 | FILE *f = fmemopen((char *)query, strlen(query), "r"); |
| 716 | cypher_parse_result_t *result = cypher_fparse(f, NULL, NULL, CYPHER_PARSE_SINGLE); |
| 717 | fclose(f); |
| 718 | |
| 719 | if(!result) { |
| 720 | return NULL; |
| 721 | } |
| 722 | |
| 723 | // check that the parser parsed the entire query |
| 724 | if(!cypher_parse_result_eof(result)) { |
| 725 | ErrorCtx_SetError("Error: query with more than one statement is not supported."); |
| 726 | parse_result_free(result); |
| 727 | return NULL; |
| 728 | } |
| 729 | |
| 730 | // in case ast contains any errors, report them and return |
| 731 | if(AST_ContainsErrors(result)) { |
| 732 | AST_ReportErrors(result); |
| 733 | parse_result_free(result); |
| 734 | return NULL; |
| 735 | } |
| 736 | |
| 737 | // get the index of a valid root (of type CYPHER_AST_STATEMENT) |
| 738 | int index; |
| 739 | if(AST_Validate_ParseResultRoot(result, &index) == AST_INVALID) { |
| 740 | parse_result_free(result); |
| 741 | return NULL; |
| 742 | } |
| 743 | |
| 744 | const cypher_astnode_t *root = cypher_parse_result_get_root(result, index); |
| 745 | |
| 746 | // validate the query |
| 747 | if(AST_Validate_Query(root) != AST_VALID) { |
| 748 | parse_result_free(result); |
| 749 | return NULL; |
| 750 | } |
| 751 | |
| 752 | // compress clauses |
| 753 | // e.g. MATCH (a:N) MATCH (b:N) RETURN a,b |
| 754 | // will be rewritten as: |
| 755 | // MATCH (a:N), (b:N) RETURN a,b |
| 756 | bool rerun_validation = AST_RewriteSameClauses(root); |
| 757 | |
| 758 | // rewrite eager & resulting Call {} clauses |
| 759 | // e.g. MATCH (m) CALL { CREATE (n:N) RETURN n } RETURN n, m |
| 760 | // will be rewritten as: |
| 761 | // MATCH (m) CALL { WITH m AS @m CREATE (n:N) RETURN n, @m AS m } RETURN n, m |
| 762 | // note: we rewrite the ast for sure here, so we need to re-validate it |
| 763 | rerun_validation |= AST_RewriteCallSubquery(root); |
| 764 | |
| 765 | // rewrite '*' projections |
| 766 | // e.g. MATCH (a), (b) RETURN * |
| 767 | // will be rewritten as: |
| 768 | // MATCH (a), (b) RETURN a, b |
no test coverage detected