gregfelice commented on PR #2347:
URL: https://github.com/apache/age/pull/2347#issuecomment-4289997250

   @MuhammadTahaNaveed — both crashes fixed in `f0ed4c95`. Also addressed the 
`-Wmaybe-uninitialized` warning on `new_property_value`.
   
   **Root cause (parser, not executor).** When MERGE has a previous clause, 
`transform_cypher_merge` takes the lateral-left-join path via 
`transform_merge_make_lateral_join`. That helper called 
`addRangeTableEntryForJoin` with `nscolumns=NULL`, leaving the join 
ParseNamespaceItem's `p_nscolumns` unset. The existing code paths never tripped 
on it because `RETURN` (and other clauses after MERGE) get processed in a fresh 
namespace built by `handle_prev_clause`. ON CREATE / ON MATCH SET, by contrast, 
is transformed in-line while the lateral-join's half-initialised nsitem is 
still the top of `pstate->p_namespace`, so `transform_cypher_set_item_list` → 
`colNameToVar` → `scanNSItemForColumn` dereferenced `p_nscolumns[attnum-1]` and 
the backend segfaulted on any ON SET whose RHS referenced a bound variable.
   
   (Parse-time crash — cassert PG shows a plain SIGSEGV, no assertion. GDB bt 
confirms: `scanNSItemForColumn` at `parse_relation.c:746`, down through 
`colNameToVar` → `transform_column_ref_for_indirection` → 
`transform_cypher_set_item_list` → `transform_cypher_merge`.)
   
   **Fix.** Populate the join's `p_nscolumns` from `res_colvars` in 
`transform_merge_make_lateral_join`. One subtlety caught during testing: the 
`Var` we end up producing for a bound entity lives inside `prop_expr`, which is 
opaque to the planner, so it is **not** rewritten to match the plan's output 
slots. At `ExecEvalScalarVar` time only `varattno` is consulted, and the 
scantuple layout mirrors the join's `eref->colnames` (via 
`make_target_list_from_join`). So the nscolumns must use the join rtindex and 
the 1-based position in `eref->colnames`, not the underlying RTE's 
varno/varattno — otherwise `Var(l_rte, 1)` and `Var(r_rte, 1)` both index 
`scantuple[0]` and `b.id` silently evaluates to `a.id`. That variant wasn't in 
your report but would have masqueraded as a correctness bug; caught it with 
`MATCH (a) MERGE (b {id: N}) ON CREATE SET b.x = b.id` once the crash was gone.
   
   **Regression coverage added to `cypher_merge`:**
   - Outer-ref RHS (`b.source_name = a.name`)
   - Self-ref RHS with a previous clause (the silent-wrong-value variant)
   - UNWIND-driven MERGE with self-ref (your second reproducer)
   - Multi-item ON CREATE SET mixing outer-ref / self-ref / literal
   - ON MATCH SET with a variable RHS on the match-branch second run
   
   Cassert installcheck green — 33/33 AGE tests pass.
   
   Both of your reproducers verbatim now return the expected values. Ready for 
another look.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to