MCPcopy Create free account
hub / github.com/RedisGraph/RedisGraph / _ValidateClauseOrder

Function _ValidateClauseOrder

src/ast/ast_validations.c:1930–1986  ·  view source on GitHub ↗

In any given query scope, reading clauses (MATCH, UNWIND, and InQueryCall) * cannot follow updating clauses (CREATE, MERGE, DELETE, SET, REMOVE, FOREACH). * https://s3.amazonaws.com/artifacts.opencypher.org/railroad/SinglePartQuery.html * Additionally, a MATCH clause cannot follow an OPTIONAL MATCH clause. */

Source from the content-addressed store, hash-verified

1928 * https://s3.amazonaws.com/artifacts.opencypher.org/railroad/SinglePartQuery.html
1929 * Additionally, a MATCH clause cannot follow an OPTIONAL MATCH clause. */
1930static AST_Validation _ValidateClauseOrder
1931(
1932 const AST *ast // ast
1933) {
1934 uint clause_count = cypher_ast_query_nclauses(ast->root);
1935
1936 bool encountered_optional_match = false;
1937 bool encountered_updating_clause = false;
1938 for(uint i = 0; i < clause_count; i ++) {
1939 const cypher_astnode_t *clause = cypher_ast_query_get_clause(ast->root, i);
1940 cypher_astnode_type_t type = cypher_astnode_type(clause);
1941 if(encountered_updating_clause && (type == CYPHER_AST_MATCH ||
1942 type == CYPHER_AST_UNWIND ||
1943 type == CYPHER_AST_CALL ||
1944 type == CYPHER_AST_CALL_SUBQUERY)) {
1945 ErrorCtx_SetError("A WITH clause is required to introduce %s after an updating clause.",
1946 cypher_astnode_typestr(type));
1947 return AST_INVALID;
1948 }
1949 if(type == CYPHER_AST_UNION) {
1950 encountered_optional_match = false;
1951 encountered_updating_clause = false;
1952 continue;
1953 }
1954 encountered_updating_clause = (encountered_updating_clause ||
1955 _is_updating_clause(clause));
1956
1957 if(type == CYPHER_AST_MATCH) {
1958 // Check whether this match is optional
1959 bool current_clause_is_optional = cypher_ast_match_is_optional(clause);
1960 // If the current clause is non-optional but we have already
1961 // encountered an optional match, emit an error
1962 if(!current_clause_is_optional && encountered_optional_match) {
1963 ErrorCtx_SetError("A WITH clause is required to introduce a \
1964MATCH clause after an OPTIONAL MATCH.");
1965 return AST_INVALID;
1966 }
1967 encountered_optional_match |= current_clause_is_optional;
1968 }
1969
1970 if(type == CYPHER_AST_WITH) {
1971 encountered_optional_match = false;
1972 encountered_updating_clause = false;
1973 }
1974
1975 if(type == CYPHER_AST_CALL_SUBQUERY) {
1976 AST subquery_ast = {
1977 .root = cypher_ast_call_subquery_get_query(clause)
1978 };
1979 if(_ValidateClauseOrder(&subquery_ast) != AST_VALID) {
1980 return AST_INVALID;
1981 }
1982 }
1983 }
1984
1985 return AST_VALID;
1986}
1987

Callers 1

AST_Validate_QueryFunction · 0.85

Calls 2

ErrorCtx_SetErrorFunction · 0.85
_is_updating_clauseFunction · 0.85

Tested by

no test coverage detected