validate a shortest-path expression
| 864 | |
| 865 | // validate a shortest-path expression |
| 866 | static VISITOR_STRATEGY _Validate_shortest_path |
| 867 | ( |
| 868 | const cypher_astnode_t *n, // ast-node |
| 869 | bool start, // first traversal |
| 870 | ast_visitor *visitor // visitor |
| 871 | ) { |
| 872 | validations_ctx *vctx = AST_Visitor_GetContext(visitor); |
| 873 | if(!start) { |
| 874 | return VISITOR_CONTINUE; |
| 875 | } |
| 876 | |
| 877 | if(cypher_ast_shortest_path_is_single(n)) { |
| 878 | const cypher_astnode_t *path = cypher_ast_shortest_path_get_path(n); |
| 879 | int elements = cypher_ast_pattern_path_nelements(path); |
| 880 | const cypher_astnode_t *start = cypher_ast_node_pattern_get_identifier(cypher_ast_pattern_path_get_element(path, 0)); |
| 881 | const cypher_astnode_t *end = cypher_ast_node_pattern_get_identifier(cypher_ast_pattern_path_get_element(path, elements - 1)); |
| 882 | if(start == NULL || end == NULL) { |
| 883 | ErrorCtx_SetError("A shortestPath requires bound nodes"); |
| 884 | return VISITOR_BREAK; |
| 885 | } |
| 886 | const char *start_id = cypher_ast_identifier_get_name(start); |
| 887 | const char *end_id = cypher_ast_identifier_get_name(end); |
| 888 | if(raxFind(vctx->defined_identifiers, (unsigned char *)start_id, strlen(start_id)) == raxNotFound || |
| 889 | raxFind(vctx->defined_identifiers, (unsigned char *)end_id, strlen(end_id)) == raxNotFound) { |
| 890 | ErrorCtx_SetError("A shortestPath requires bound nodes"); |
| 891 | return VISITOR_BREAK; |
| 892 | } |
| 893 | return VISITOR_RECURSE; |
| 894 | } else { |
| 895 | // MATCH (a), (b), p = allShortestPaths((a)-[*2..]->(b)) RETURN p |
| 896 | // validate rel pattern range doesn't contains a minimum > 1 |
| 897 | const cypher_astnode_t **ranges = AST_GetTypedNodes(n, CYPHER_AST_RANGE); |
| 898 | int range_count = array_len(ranges); |
| 899 | for(int i = 0; i < range_count; i++) { |
| 900 | long min_hops = 1; |
| 901 | const cypher_astnode_t *r = ranges[i]; |
| 902 | const cypher_astnode_t *start = cypher_ast_range_get_start(r); |
| 903 | if(start) min_hops = AST_ParseIntegerNode(start); |
| 904 | if(min_hops != 1) { |
| 905 | ErrorCtx_SetError("allShortestPaths(...) does not support a minimal length different from 1"); |
| 906 | break; |
| 907 | } |
| 908 | } |
| 909 | array_free(ranges); |
| 910 | } |
| 911 | |
| 912 | if(ErrorCtx_EncounteredError()) { |
| 913 | return VISITOR_BREAK; |
| 914 | } |
| 915 | |
| 916 | return VISITOR_RECURSE; |
| 917 | } |
| 918 | |
| 919 | // validate a pattern-path expression |
| 920 | static VISITOR_STRATEGY _Validate_pattern_path |
nothing calls this directly
no test coverage detected