Cross-join node-only pattern into existing bindings. Returns 0 on success, * CBM_NOT_FOUND when the allocation is refused (overflow) or fails (OOM); the * caller propagates that as a query error rather than silently skipping the * MATCH, which would return a wrong (short) result. */
| 4554 | * caller propagates that as a query error rather than silently skipping the |
| 4555 | * MATCH, which would return a wrong (short) result. */ |
| 4556 | static int cross_join_nodes(binding_t **bindings, int *bind_count, cbm_node_t *extra_nodes, |
| 4557 | int extra_count, const char *nvar, bool opt) { |
| 4558 | size_t alloc_n = 0; |
| 4559 | if (cbm_cypher_cross_join_alloc(*bind_count, extra_count, opt, &alloc_n) != 0) { |
| 4560 | return CBM_NOT_FOUND; /* product overflows int/size_t: fail the query */ |
| 4561 | } |
| 4562 | binding_t *new_bindings = malloc(alloc_n * sizeof(binding_t)); |
| 4563 | if (!new_bindings) { |
| 4564 | return CBM_NOT_FOUND; /* OOM: propagate, don't silently skip the MATCH */ |
| 4565 | } |
| 4566 | size_t new_count = 0; |
| 4567 | for (int bi = 0; bi < *bind_count; bi++) { |
| 4568 | for (int ni = 0; ni < extra_count && new_count < alloc_n; ni++) { |
| 4569 | binding_t nb = {0}; |
| 4570 | binding_copy(&nb, &(*bindings)[bi]); |
| 4571 | binding_set(&nb, nvar, &extra_nodes[ni]); |
| 4572 | new_bindings[new_count++] = nb; |
| 4573 | } |
| 4574 | if (opt && extra_count == 0 && new_count < alloc_n) { |
| 4575 | binding_t nb = {0}; |
| 4576 | binding_copy(&nb, &(*bindings)[bi]); |
| 4577 | new_bindings[new_count++] = nb; |
| 4578 | } |
| 4579 | } |
| 4580 | for (int bi = 0; bi < *bind_count; bi++) { |
| 4581 | binding_free(&(*bindings)[bi]); |
| 4582 | } |
| 4583 | free(*bindings); |
| 4584 | *bindings = new_bindings; |
| 4585 | *bind_count = (int)new_count; /* new_count <= INT_MAX, guaranteed above */ |
| 4586 | return 0; |
| 4587 | } |
| 4588 | |
| 4589 | /* Cross-join pattern-with-rels into existing bindings */ |
| 4590 | static void cross_join_with_rels(cbm_store_t *store, cbm_pattern_t *patn, binding_t **bindings, |
no test coverage detected