Expand additional MATCH patterns (pi >= 1) */
| 4335 | |
| 4336 | /* Expand additional MATCH patterns (pi >= 1) */ |
| 4337 | static void expand_additional_patterns(cbm_store_t *store, cbm_query_t *q, const char *project, |
| 4338 | int max_rows, binding_t **bindings, int *bind_count, |
| 4339 | int *bind_cap) { |
| 4340 | for (int pi = SKIP_ONE; pi < q->pattern_count; pi++) { |
| 4341 | cbm_pattern_t *patn = &q->patterns[pi]; |
| 4342 | bool opt = q->pattern_optional[pi]; |
| 4343 | const char *nvar = patn->nodes[0].variable ? patn->nodes[0].variable : "_n_extra"; |
| 4344 | bool start_bound = *bind_count > 0 && binding_get(&(*bindings)[0], nvar) != NULL; |
| 4345 | |
| 4346 | if (start_bound && patn->rel_count > 0) { |
| 4347 | const char *tv = nvar; |
| 4348 | expand_pattern_rels(store, patn, bindings, bind_count, bind_cap, &tv, opt); |
| 4349 | continue; |
| 4350 | } |
| 4351 | |
| 4352 | /* Single-rel pattern whose START is unbound but whose TERMINAL is already |
| 4353 | * bound: drive from the bound terminal instead of scanning all nodes for |
| 4354 | * the start var (avoids the int-overflow OOB write and the c-IS-NULL |
| 4355 | * corruption of #627). */ |
| 4356 | if (!start_bound && patn->rel_count == 1 && *bind_count > 0) { |
| 4357 | const char *term_var = patn->nodes[1].variable; |
| 4358 | bool term_bound = term_var && binding_get(&(*bindings)[0], term_var) != NULL; |
| 4359 | if (term_bound) { |
| 4360 | expand_from_bound_terminal(store, patn, bindings, bind_count, nvar, opt); |
| 4361 | continue; |
| 4362 | } |
| 4363 | } |
| 4364 | |
| 4365 | cbm_node_t *extra_nodes = NULL; |
| 4366 | int extra_count = 0; |
| 4367 | scan_pattern_nodes(store, project, max_rows, &patn->nodes[0], &extra_nodes, &extra_count); |
| 4368 | if (patn->rel_count == 0) { |
| 4369 | cross_join_nodes(bindings, bind_count, extra_nodes, extra_count, nvar, opt); |
| 4370 | } else { |
| 4371 | cross_join_with_rels(store, patn, bindings, bind_count, extra_nodes, extra_count, nvar, |
| 4372 | opt); |
| 4373 | } |
| 4374 | cbm_store_free_nodes(extra_nodes, extra_count); |
| 4375 | } |
| 4376 | } |
| 4377 | |
| 4378 | /* Project RETURN clause results */ |
| 4379 | static void execute_return_clause(cbm_query_t *q, cbm_return_clause_t *ret, binding_t *bindings, |
no test coverage detected