Skip to content

GFQL accepts sum()/avg() over BOOLEAN, which Cypher rejects — extension or conformance gap? #1820

Description

@lmeyerov

Found by the aggregate x dtype differential sweep in #1819 (which pinned sum/avg to the Cypher
INTEGER | FLOAT | DURATION contract). This one is a deliberate GFQL extension that Cypher does
not allow, left in place there rather than changed silently — it needs an owner decision.

The divergence from Cypher

# Neo4j 5.26.26
UNWIND [true,false,true] AS x RETURN sum(x);
  -> Type mismatch: expected Float, Integer or Duration but was Boolean

GFQL, on every engine, answers 2:

import pandas as pd, graphistry
nodes = pd.DataFrame({"id": [0,1,2], "grp": ["x"]*3, "flag": [True, False, True]})
edges = pd.DataFrame({"src": [0], "dst": [1]})
g = graphistry.nodes(nodes, "id").edges(edges, "src", "dst")
g.gfql("MATCH (n) RETURN sum(n.flag) AS s", engine="pandas")._nodes   # -> s = 2
g.gfql("MATCH (n) RETURN avg(n.flag) AS a", engine="polars")._nodes   # -> a = 0.666...

Why it was NOT changed in #1819

  • Both engines already agree, so it is not a divergence — it is a uniform extension.
  • Summing an indicator column is idiomatic in the dataframe surface GFQL also serves, and rejecting
    it would break working user queries with no correctness argument behind the break.

It is recorded in graphistry/compute/gfql/agg_types.py as a choice with a reason rather than an
accident, so whoever revisits it finds the note. The decision to make is whether GFQL wants strict
Cypher conformance here (reject) or wants to keep the dataframe affordance (document it as an
explicit extension in the aggregates docs).

Repro harness: graphistry/tests/compute/gfql/test_aggregate_type_contract.py (the bool_col
parameters of the positive lane pin the current behaviour).

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