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

Function _ValidateUnion_Clauses

src/ast/ast_validations.c:990–1081  ·  view source on GitHub ↗

validate UNION clauses

Source from the content-addressed store, hash-verified

988
989// validate UNION clauses
990static AST_Validation _ValidateUnion_Clauses
991(
992 const AST *ast // ast-node
993) {
994 AST_Validation res = AST_VALID;
995
996 uint *union_indices = AST_GetClauseIndices(ast, CYPHER_AST_UNION);
997 uint union_clause_count = array_len(union_indices);
998 array_free(union_indices);
999
1000 if(union_clause_count != 0) {
1001 // Require all RETURN clauses to perform the exact same projection
1002 uint *return_indices = AST_GetClauseIndices(ast, CYPHER_AST_RETURN);
1003 uint return_clause_count = array_len(return_indices);
1004
1005 // We should have one more RETURN clauses than we have UNION clauses.
1006 if(return_clause_count != union_clause_count + 1) {
1007 ErrorCtx_SetError("Found %d UNION clauses but only %d RETURN clauses.", union_clause_count,
1008 return_clause_count);
1009 array_free(return_indices);
1010 return AST_INVALID;
1011 }
1012
1013 const cypher_astnode_t *return_clause = cypher_ast_query_get_clause(ast->root, return_indices[0]);
1014 uint proj_count = cypher_ast_return_nprojections(return_clause);
1015 const char *projections[proj_count];
1016
1017 for(uint j = 0; j < proj_count; j++) {
1018 const cypher_astnode_t *proj = cypher_ast_return_get_projection(return_clause, j);
1019 const cypher_astnode_t *alias_node = cypher_ast_projection_get_alias(proj);
1020 if(alias_node == NULL) {
1021 // The projection was not aliased, so the projection itself must be an identifier.
1022 alias_node = cypher_ast_projection_get_expression(proj);
1023 ASSERT(cypher_astnode_type(alias_node) == CYPHER_AST_IDENTIFIER);
1024 }
1025 const char *alias = cypher_ast_identifier_get_name(alias_node);
1026 projections[j] = alias;
1027 }
1028
1029 for(uint i = 1; i < return_clause_count; i++) {
1030 return_clause = cypher_ast_query_get_clause(ast->root, return_indices[i]);
1031 if(proj_count != cypher_ast_return_nprojections(return_clause)) {
1032 ErrorCtx_SetError("All sub queries in a UNION must have the same column names.");
1033 res = AST_INVALID;
1034 goto cleanup;
1035 }
1036
1037 for(uint j = 0; j < proj_count; j++) {
1038 const cypher_astnode_t *proj = cypher_ast_return_get_projection(return_clause, j);
1039 const cypher_astnode_t *alias_node = cypher_ast_projection_get_alias(proj);
1040 if(alias_node == NULL) {
1041 // The projection was not aliased, so the projection itself must be an identifier.
1042 alias_node = cypher_ast_projection_get_expression(proj);
1043 ASSERT(cypher_astnode_type(alias_node) == CYPHER_AST_IDENTIFIER);
1044 }
1045 const char *alias = cypher_ast_identifier_get_name(alias_node);
1046 if(strcmp(projections[j], alias) != 0) {
1047 ErrorCtx_SetError("All sub queries in a UNION must have the same column names.");

Callers 1

AST_Validate_QueryFunction · 0.85

Calls 4

AST_GetClauseIndicesFunction · 0.85
array_lenFunction · 0.85
array_freeFunction · 0.85
ErrorCtx_SetErrorFunction · 0.85

Tested by

no test coverage detected