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

Function _Validate_reduce

src/ast/ast_validations.c:606–711  ·  view source on GitHub ↗

validate reduce

Source from the content-addressed store, hash-verified

604
605// validate reduce
606static VISITOR_STRATEGY _Validate_reduce
607(
608 const cypher_astnode_t *n, // ast-node
609 bool start, // first traversal
610 ast_visitor *visitor // visitor
611) {
612 validations_ctx *vctx = AST_Visitor_GetContext(visitor);
613 if(!start) {
614 return VISITOR_CONTINUE;
615 }
616
617 cypher_astnode_type_t orig_clause = vctx->clause;
618 // change clause type of vctx so that function-validation will work properly
619 // (include-aggregations should be set to false)
620 vctx->clause = CYPHER_AST_REDUCE;
621
622 // A reduce call has an accumulator and a local list variable that should
623 // only be accessed within its scope;
624 // do not leave them in the identifiers map
625 // example: reduce(sum=0, n in [1,2] | sum+n)
626 // the reduce function is composed of 5 components:
627 // 1. accumulator `sum`
628 // 2. accumulator init expression `0`
629 // 3. list expression `[1,2,3]`
630 // 4. variable `n`
631 // 5. eval expression `sum + n`
632
633 // make sure that the init expression is a known var or valid exp.
634 const cypher_astnode_t *init_node = cypher_ast_reduce_get_init(n);
635 if(cypher_astnode_type(init_node) == CYPHER_AST_IDENTIFIER) {
636 // check if the variable has already been introduced
637 const char *var_str = cypher_ast_identifier_get_name(init_node);
638 if(raxFind(vctx->defined_identifiers, (unsigned char *)var_str, strlen(var_str)) == raxNotFound) {
639 ErrorCtx_SetError("%s not defined.", var_str);
640 return VISITOR_BREAK;
641 }
642 }
643 else {
644 AST_Visitor_visit(init_node, visitor);
645 if(ErrorCtx_EncounteredError()) {
646 return VISITOR_BREAK;
647 }
648 }
649
650 // make sure that the list expression is a list (or list comprehension) or an
651 // alias of an existing one.
652 const cypher_astnode_t *list_var = cypher_ast_reduce_get_expression(n);
653 if(cypher_astnode_type(list_var) == CYPHER_AST_IDENTIFIER) {
654 const char *list_var_str = cypher_ast_identifier_get_name(list_var);
655 if(raxFind(vctx->defined_identifiers, (unsigned char *) list_var_str, strlen(list_var_str)) == raxNotFound) {
656 ErrorCtx_SetError("%s not defined", list_var_str);
657 return VISITOR_BREAK;
658 }
659 }
660
661 // Visit the list expression (no need to introduce local vars)
662 AST_Visitor_visit(list_var, visitor);
663 if(ErrorCtx_EncounteredError()) {

Callers

nothing calls this directly

Calls 4

AST_Visitor_GetContextFunction · 0.85
ErrorCtx_SetErrorFunction · 0.85
AST_Visitor_visitFunction · 0.85

Tested by

no test coverage detected