Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions crates/lance-csr/src/path_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ use arrow::compute::take;
use arrow_schema::{DataType, Field, Fields};
use datafusion::common::Result;

pub(crate) const PROPERTIES: &str = "__lance_graph_properties";
pub(crate) const IDENTITY: &str = "__lance_graph_identity";
pub(crate) const START: &str = "__lance_graph_start";
pub(crate) const END: &str = "__lance_graph_end";
pub(crate) const PROPERTIES: &str = "__lance_csr_properties";
pub(crate) const IDENTITY: &str = "__lance_csr_identity";
pub(crate) const START: &str = "__lance_csr_start";
pub(crate) const END: &str = "__lance_csr_end";
const ENTITY: &str = "lance_csr.entity";

pub(crate) fn entity_kind(data_type: &DataType) -> Option<&str> {
Expand Down
6 changes: 3 additions & 3 deletions docs/cypher.md
Original file line number Diff line number Diff line change
Expand Up @@ -348,9 +348,9 @@ traversed that relationship backwards. Property access, `keys()` and node `label
A zero-hop path has one node and an empty relationship list. All path functions return null for a null path.

`RETURN path` produces an Arrow struct with `length`, `nodes`, `node_records` and `relationships` fields.
Entity records store user properties in `__lance_graph_properties` and `{label, id}` identity metadata
in `__lance_graph_identity`. Relationship records also carry the node records `__lance_graph_start` and
`__lance_graph_end`. These metadata fields are distinct from user properties, even if a property has the
Entity records store user properties in `__lance_csr_properties` and `{label, id}` identity metadata
in `__lance_csr_identity`. Relationship records also carry the node records `__lance_csr_start` and
`__lance_csr_end`. These metadata fields are distinct from user properties, even if a property has the
same name. `keys(entity)` lists only non-null user properties; `keys(map)` includes null-valued keys.
Prefer the Cypher property and endpoint functions when writing queries. Relationship identities identify actual occurrences within this query's inventory, not persistent
IDs that can be compared across queries or refreshes. Rich paths support the same signed integer and
Expand Down
18 changes: 9 additions & 9 deletions python/python/tests/test_path_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def test_zero_path_records(engine, shortest):
assert rows[0]["length"] == 0
assert rows[0]["ids"] == [3]
assert rows[0]["edges"] == []
assert rows[0]["p"]["node_records"][0]["__lance_graph_properties"]["name"] == "c"
assert rows[0]["p"]["node_records"][0]["__lance_csr_properties"]["name"] == "c"


def test_named_trails_do_not_reuse_a_relationship(engine):
Expand Down Expand Up @@ -194,8 +194,8 @@ def test_identical_parallel_occurrences_are_distinct():
).to_pylist()
relationships = [r["p"]["relationships"][0] for r in rows]
assert len(relationships) == 2
assert len({r["__lance_graph_identity"]["id"] for r in relationships}) == 2
assert [r["__lance_graph_properties"]["weight"] for r in relationships] == [5, 5]
assert len({r["__lance_csr_identity"]["id"] for r in relationships}) == 2
assert [r["__lance_csr_properties"]["weight"] for r in relationships] == [5, 5]


@pytest.mark.parametrize("bad_type", [pa.string(), pa.uint64()])
Expand Down Expand Up @@ -316,18 +316,18 @@ def test_entity_metadata_does_not_shadow_properties():
"Person": pa.table(
{"id": [1, 2], "nullable": pa.array([None, None], pa.string())}
),
"R": pa.table({"src": [1], "dst": [2], "__lance_graph_identity": [42]}),
"R": pa.table({"src": [1], "dst": [2], "__lance_csr_identity": [42]}),
},
)
rows = engine.execute(
"MATCH p = (a:Person)-[:R]->(b:Person) UNWIND relationships(p) AS r "
"RETURN r.__lance_graph_identity AS user_value, keys(r) AS properties, "
"RETURN r.__lance_csr_identity AS user_value, keys(r) AS properties, "
"keys(startNode(r)) AS node_properties, keys({nullable: null}) AS map_keys"
).to_pylist()
assert rows == [
{
"user_value": 42,
"properties": ["__lance_graph_identity", "dst", "src"],
"properties": ["__lance_csr_identity", "dst", "src"],
"node_properties": ["id"],
"map_keys": ["nullable"],
}
Expand All @@ -344,8 +344,8 @@ def test_multiple_path_operators_share_occurrence_identity(engine):
ids = {}
for row in rows:
for edge in row.values():
weight = edge["__lance_graph_properties"]["weight"]
identity = edge["__lance_graph_identity"]
weight = edge["__lance_csr_properties"]["weight"]
identity = edge["__lance_csr_identity"]
assert ids.setdefault(weight, identity) == identity
assert ids[5] != ids[7]

Expand Down Expand Up @@ -460,7 +460,7 @@ def test_path_alias_retains_actual_relationship_values(engine, suffix):
rows = engine.execute(query).to_pylist()
edges = [row.get("edges", row.get("path", {}).get("relationships")) for row in rows]
assert sorted(
[r["__lance_graph_properties"]["weight"] for r in path] for path in edges
[r["__lance_csr_properties"]["weight"] for r in path] for path in edges
) == [
[5, 11],
[7, 11],
Expand Down
Loading