validate a pattern comprehension
| 396 | |
| 397 | // validate a pattern comprehension |
| 398 | static VISITOR_STRATEGY _Validate_pattern_comprehension |
| 399 | ( |
| 400 | const cypher_astnode_t *n, // ast-node |
| 401 | bool start, // first traversal |
| 402 | ast_visitor *visitor // visitor |
| 403 | ) { |
| 404 | validations_ctx *vctx = AST_Visitor_GetContext(visitor); |
| 405 | |
| 406 | // we enter ONLY when start=true, so no check is needed |
| 407 | |
| 408 | const cypher_astnode_t *id = cypher_ast_pattern_comprehension_get_identifier(n); |
| 409 | bool is_new; |
| 410 | const char *identifier; |
| 411 | if(id) { |
| 412 | identifier = cypher_ast_identifier_get_name(id); |
| 413 | is_new = (raxFind(vctx->defined_identifiers, (unsigned char *)identifier, strlen(identifier)) == raxNotFound); |
| 414 | } |
| 415 | else { |
| 416 | is_new = false; |
| 417 | } |
| 418 | |
| 419 | // Introduce local identifier if it is not yet introduced |
| 420 | if(is_new) { |
| 421 | raxInsert(vctx->defined_identifiers, (unsigned char *)identifier, strlen(identifier), NULL, NULL); |
| 422 | } |
| 423 | |
| 424 | // Visit expression-children |
| 425 | // Visit pattern |
| 426 | const cypher_astnode_t *pattern = cypher_ast_pattern_comprehension_get_pattern(n); |
| 427 | if(pattern) { |
| 428 | AST_Visitor_visit(pattern, visitor); |
| 429 | if(ErrorCtx_EncounteredError()) { |
| 430 | return VISITOR_BREAK; |
| 431 | } |
| 432 | } |
| 433 | |
| 434 | // Visit predicate |
| 435 | const cypher_astnode_t *pred = cypher_ast_pattern_comprehension_get_predicate(n); |
| 436 | if(pred) { |
| 437 | AST_Visitor_visit(pred, visitor); |
| 438 | if(ErrorCtx_EncounteredError()) { |
| 439 | return VISITOR_BREAK; |
| 440 | } |
| 441 | } |
| 442 | |
| 443 | // Visit eval |
| 444 | const cypher_astnode_t *eval = cypher_ast_pattern_comprehension_get_eval(n); |
| 445 | if(eval) { |
| 446 | AST_Visitor_visit(eval, visitor); |
| 447 | if(ErrorCtx_EncounteredError()) { |
| 448 | return VISITOR_BREAK; |
| 449 | } |
| 450 | } |
| 451 | |
| 452 | // pattern comprehension identifier is no longer bound, remove it from bound vars |
| 453 | // if it was introduced |
| 454 | if(is_new) { |
| 455 | raxRemove(vctx->defined_identifiers, (unsigned char *)identifier, strlen(identifier), NULL); |
nothing calls this directly
no test coverage detected