feat(rel): unlabelled MATCH (n) RETURN n returns a whole node value (#889 slice 1)#893
Merged
Merged
Conversation
…889) Slice 1 of #889. #785 materialized a whole node value only when the label was written in the pattern; an unlabelled `MATCH (n) RETURN n` fell back to a uuid-only struct (no label, no props). This resolves both at read time. Label name: - RuntimeCatalog gains `entity_type_name` / `entity_type_names_with_ids` (mirror of the relation-type reverse lookups), surfaced through GraphCatalog::label_names. - The lowerer keeps `type_id_to_entity_name` ontology-only (it drives property-table routing, which in exploratory mode must read `_untyped`) and builds a SEPARATE label-name map (ontology + runtime catalog) for node-value rendering only. node_value_struct emits a runtime `CASE type_id WHEN k THEN 'Label' … ELSE NULL` (ascending key order, deterministic) for the `labels` field when the pattern had no label. Properties: - `prop_table_stem` centralizes property-file selection: an unlabelled node in exploratory mode now resolves to `_untyped` (where all exploratory properties are written), so the node value carries its props; an unlabelled node in an ontology mode stays a no-op (props are spread across per-entity tables — a multi-table union, out of scope). One label per node (multi-label is #799). TCK node-value rendering + scenario un-skipping is slice 2. Validated: new e2e `unlabelled_match_returns_node_with_resolved_label_and_props` (76 pass); gf-rel goldens (incl. the exploratory property-join golden) and gf-ir/gf-storage suites green; clippy --workspace -D warnings clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (5)
WalkthroughAdds runtime resolution of node labels for unlabelled ChangesUnlabelled Node Label Resolution
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #889 (slice 1 of 3 — the engine; does not close the issue).
Summary
#785 materialized a whole node value only when the label was written in the pattern (
MATCH (n:Person) RETURN n); an unlabelledMATCH (n) RETURN nfell back to a uuid-only struct (no label, no properties). This slice resolves both at read time, so an unlabelled match returns the node with its real label name and properties.How
Label name (recovered from the node's stored
type_id):RuntimeCataloggainsentity_type_name/entity_type_names_with_ids— the entity-type (label) mirror of the existingrelation_type_name*reverse lookups — surfaced throughGraphCatalog::label_names.type_id_to_entity_nameontology-only (it drives property-table routing, which in exploratory mode must read_untyped) and builds a separate label-name map (ontology + runtime catalog) used only for node-value rendering.node_value_structemits a runtimeCASE type_id WHEN k THEN 'Label' … ELSE NULL END(ascending key order → deterministic plan) for thelabelsfield when the pattern had no label.Properties:
prop_table_stemcentralizes property-file selection: an unlabelled node in exploratory mode now resolves to_untyped(where all exploratory properties are written), so the node value carries its props; an unlabelled node in an ontology mode stays a no-op (properties are spread across per-entity tables — a multi-table union, out of scope).Scope / deferrals
WITH/rust: register custom LogicalPlan node stubs for graph-native operators #577,range/coalescebuiltins, error-assertion steps — so no corpus feature is fully un-skippable at feature granularity yet; the render layer lands with its first real consumer.)RETURN r/RETURN p(relationship/path values) + the rust: startNode(r) / endNode(r) — return the node, not the UUID #753 optional/undirected null-gate are slice 3.Validation
unlabelled_match_returns_node_with_resolved_label_and_props—MATCH (n) WHERE n.name='Alice' RETURN nreturnsStruct{labels: ['Person'], name: 'Alice', …}(76 pass).cargo clippy --workspace -- -D warningsclean; fmt clean.🤖 Generated with Claude Code
Note
Return real label and properties for unlabelled
MATCH (n) RETURN nqueriestype_idvalues sourced fromRuntimeCatalog, replacing the previous NULL placeholder._untypedproperty table via a LEFT join, makingvar_N.<prop>columns available downstream.GraphCatalognow carries aTypeId→label-namereverse map (built fromRuntimeCatalog::entity_type_names_with_ids) and exposes it vialabel_names()for use during expression lowering.ExprLowereraccepts the label-name map through the updatedwith_prop_names_and_nodesconstructor and passes it intonode_value_structto populate thelabelsfield.MATCH (n) WHERE n.name = 'Alice' RETURN nnow return a structured node value with a resolved label and properties instead of a node with null labels.Macroscope summarized d3345fb.
Summary by CodeRabbit