Evaluate a WHERE condition against a binding */
| 2403 | |
| 2404 | /* Evaluate a WHERE condition against a binding */ |
| 2405 | static bool eval_condition(const cbm_condition_t *c, binding_t *b) { |
| 2406 | /* Label test: WHERE n:Label (#241) — compare the bound node's label |
| 2407 | * directly rather than a property value. */ |
| 2408 | if (strcmp(c->op, "HAS_LABEL") == 0) { |
| 2409 | cbm_node_t *n = binding_get(b, c->variable); |
| 2410 | bool result = n && n->label && c->value && strcmp(n->label, c->value) == 0; |
| 2411 | return c->negated ? !result : result; |
| 2412 | } |
| 2413 | |
| 2414 | /* EXISTS { (var)-[:TYPE]->() }: does the bound node have any edge of the |
| 2415 | * given type in the requested direction? (dir 0=out, 1=in, 2=any) */ |
| 2416 | if (strcmp(c->op, "EXISTS") == 0) { |
| 2417 | cbm_node_t *n = binding_get(b, c->variable); |
| 2418 | bool result = false; |
| 2419 | if (n && b->store) { |
| 2420 | cbm_edge_t *edges = NULL; |
| 2421 | int cnt = 0; |
| 2422 | if (c->exists_dir != 1) { /* outbound or any */ |
| 2423 | if (c->value) { |
| 2424 | cbm_store_find_edges_by_source_type(b->store, n->id, c->value, &edges, &cnt); |
| 2425 | } else { |
| 2426 | cbm_store_find_edges_by_source(b->store, n->id, &edges, &cnt); |
| 2427 | } |
| 2428 | result = cnt > 0; |
| 2429 | cbm_store_free_edges(edges, cnt); |
| 2430 | } |
| 2431 | if (!result && c->exists_dir != 0) { /* inbound or any */ |
| 2432 | edges = NULL; |
| 2433 | cnt = 0; |
| 2434 | if (c->value) { |
| 2435 | cbm_store_find_edges_by_target_type(b->store, n->id, c->value, &edges, &cnt); |
| 2436 | } else { |
| 2437 | cbm_store_find_edges_by_target(b->store, n->id, &edges, &cnt); |
| 2438 | } |
| 2439 | result = cnt > 0; |
| 2440 | cbm_store_free_edges(edges, cnt); |
| 2441 | } |
| 2442 | } |
| 2443 | return c->negated ? !result : result; |
| 2444 | } |
| 2445 | |
| 2446 | const char *actual = resolve_condition_value(c, b); |
| 2447 | if (!actual) { |
| 2448 | return true; |
| 2449 | } |
| 2450 | |
| 2451 | bool result; |
| 2452 | |
| 2453 | /* IS NULL / IS NOT NULL */ |
| 2454 | if (strcmp(c->op, "IS NULL") == 0) { |
| 2455 | result = (actual[0] == '\0'); |
| 2456 | return c->negated ? !result : result; |
| 2457 | } |
| 2458 | if (strcmp(c->op, "IS NOT NULL") == 0) { |
| 2459 | result = (actual[0] != '\0'); |
| 2460 | return c->negated ? !result : result; |
| 2461 | } |
| 2462 |
no test coverage detected