validate a list comprehension
| 338 | |
| 339 | // validate a list comprehension |
| 340 | static VISITOR_STRATEGY _Validate_list_comprehension |
| 341 | ( |
| 342 | const cypher_astnode_t *n, // ast-node |
| 343 | bool start, // first traversal |
| 344 | ast_visitor *visitor // visitor |
| 345 | ) { |
| 346 | validations_ctx *vctx = AST_Visitor_GetContext(visitor); |
| 347 | |
| 348 | // we enter ONLY when start=true, so no check is needed |
| 349 | |
| 350 | const cypher_astnode_t *id = cypher_ast_list_comprehension_get_identifier(n); |
| 351 | const char *identifier = cypher_ast_identifier_get_name(id); |
| 352 | bool is_new = (raxFind(vctx->defined_identifiers, (unsigned char *)identifier, strlen(identifier)) == raxNotFound); |
| 353 | |
| 354 | // Introduce local identifier if it is not yet introduced |
| 355 | if(is_new) { |
| 356 | raxInsert(vctx->defined_identifiers, (unsigned char *)identifier, strlen(identifier), NULL, NULL); |
| 357 | } |
| 358 | |
| 359 | // Visit expression-children |
| 360 | // Visit expression |
| 361 | const cypher_astnode_t *exp = cypher_ast_list_comprehension_get_expression(n); |
| 362 | if(exp) { |
| 363 | AST_Visitor_visit(exp, visitor); |
| 364 | if(ErrorCtx_EncounteredError()) { |
| 365 | return VISITOR_BREAK; |
| 366 | } |
| 367 | } |
| 368 | |
| 369 | // Visit predicate |
| 370 | const cypher_astnode_t *pred = cypher_ast_list_comprehension_get_predicate(n); |
| 371 | if(pred) { |
| 372 | AST_Visitor_visit(pred, visitor); |
| 373 | if(ErrorCtx_EncounteredError()) { |
| 374 | return VISITOR_BREAK; |
| 375 | } |
| 376 | } |
| 377 | |
| 378 | // Visit eval |
| 379 | const cypher_astnode_t *eval = cypher_ast_list_comprehension_get_eval(n); |
| 380 | if(eval) { |
| 381 | AST_Visitor_visit(eval, visitor); |
| 382 | if(ErrorCtx_EncounteredError()) { |
| 383 | return VISITOR_BREAK; |
| 384 | } |
| 385 | } |
| 386 | |
| 387 | // list comprehension identifier is no longer bound, remove it from bound vars |
| 388 | // if it was introduced |
| 389 | if(is_new) { |
| 390 | raxRemove(vctx->defined_identifiers, (unsigned char *)identifier, strlen(identifier), NULL); |
| 391 | } |
| 392 | |
| 393 | // do not traverse children |
| 394 | return VISITOR_CONTINUE; |
| 395 | } |
| 396 | |
| 397 | // validate a pattern comprehension |
nothing calls this directly
no test coverage detected