Skip to content

Feature: support single-argument properties() function for Node, Rel, and Struct #831

Description

@Mrhs121

API

C++

Description

Summary

Add support for the openCypher / ISO GQL standard single-argument properties() function on NODE, REL, and STRUCT expressions (e.g., PROPERTIES(n) and PROPERTIES(r)).


Background & Motivation

Currently, Ladybug only supports the two-argument form of the PROPERTIES() function:

PROPERTIES(nodes(p), 'propName')

While this is useful for variable-length path property extraction, openCypher and other Cypher implementations (such as Neo4j and so on) standardly support a single-argument properties(entity):

MATCH (n:Person {name: 'Alice'})
RETURN properties(n);

Previously in Ladybug, calling properties(n) resulted in a binder error:

Binder exception: Function PROPERTIES did not receive correct arguments:
Actual:   (NODE)
Expected: (LIST,STRING) -> ANY

Key Use Cases

  1. Clean Payloads for APIs / JSON Serialization: RETURN n returns graph entities containing internal system metadata (_ID, _LABEL). properties(n) extracts only clean user-defined business properties as a STRUCT.
  2. First-class Expression Composition: Unlike n.* (which is a statement-level wildcard expansion and cannot be nested), properties(n) is a first-class expression that can be passed to aggregation functions like collect(properties(n)).
  3. GraphRAG & LLM Prompt Construction: In Knowledge Graph / RAG pipelines, extracting clean entity/relationship property maps without system noise significantly reduces prompt token usage.

Proposed Behavior

  • PROPERTIES(node: NODE) -> STRUCT: Returns a struct containing all user-defined properties of the node (excluding internal columns _ID, _LABEL).
  • PROPERTIES(rel: REL) -> STRUCT: Returns a struct containing all user-defined properties of the relationship (excluding internal columns _ID, _LABEL, _SRC, _DST).
  • PROPERTIES(struct: STRUCT) -> STRUCT: Returns the struct with user fields.
  • PROPERTIES(list: LIST, prop: STRING) -> LIST: Existing two-argument form remains fully backwards compatible.

Example

CREATE NODE TABLE Person (name STRING, age INT64, city STRING, PRIMARY KEY (name));
CREATE (:Person {name: 'Alice', age: 25, city: 'Hangzhou'});

MATCH (n:Person {name: 'Alice'})
RETURN properties(n);
-- Output: {name: Alice, age: 25, city: Hangzhou}

MATCH (n:Person)
RETURN collect(properties(n)) AS all_users;
-- Output: [{name: Alice, age: 25, city: Hangzhou}]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions