apache / apache/age

Cache ResultRelInfo per label in apply_update_list to avoid per-row generated-expr rebuild on SET

Open
#2,459 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
4.8k
Forks
523
Avg merge
1d 2h
Merged PRs (30d)
9

Description

### Summary

The Cypher `SET` executor (`apply_update_list` in `src/backend/executor/cypher_set.c`) creates a fresh `ResultRelInfo` per updated entity via `create_entity_result_rel_info()` inside the per-row loop.

Now that `SET` computes stored generated columns (#2458, for #2450), `ExecComputeStoredGenerated()` lazily initializes `ri_GeneratedExprsU` on that `ResultRelInfo`. Because a new `ResultRelInfo` is built per row, a multi-row `SET` on a label with a stored generated column rebuilds the generated-column expression state on every row and retains it in the executor query context until query end.

### Impact

- Only affects `SET` on labels that actually have a `GENERATED ALWAYS ... STORED` column (the compute is guarded by `has_generated_stored`), so there is no regression for the common case.
- For that case, expression-state setup is O(rows) instead of O(labels), with corresponding memory held for the duration of the query.

### Proposed fix

Cache/reuse the `ResultRelInfo` per label (relation OID) for the lifetime of `apply_update_list`, mirroring the existing relation / index-OID / RLS caching already done there. That lets `ri_GeneratedExprsU` (and index/constraint setup) initialize once per relation instead of once per updated row.

### Notes

Split out from the #2458 review (thanks @MuhammadTahaNaveed) to keep that bugfix focused. Not a correctness issue — a performance/memory improvement for multi-row `SET` on generated-column labels.

Contributor guide

Open the contributing guide

Research direction

Start in src/backend/executor/cypher_set.c at apply_update_list and inspect the existing relation, index-OID, and RLS caches alongside create_entity_result_rel_info(). Trace how the per-row ResultRelInfo is created, then verify that a multi-row SET on a label with a stored generated column reuses one per-label entry and initializes its generated-expression state once.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, postgresql
Domain
databases, performance
Issue type
Refactor
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.