Documentation
¶
Overview ¶
Package expr defines the runtime value model for the Cypher executor.
Value model ¶
A Value is a typed, immutable datum produced or consumed by an executor operator. Every value carries a Kind tag used by the planner and executor to dispatch without interface boxing in hot paths.
Three-valued logic (3VL) ¶
NULL is a first-class singleton (Null). Comparisons involving NULL return NULL, not false, in accordance with openCypher 9 §4.1.3. Callers that need boolean truth must use IsTruthy.
Ordering ¶
Compare implements the openCypher 9 total ordering for use in ORDER BY: NULLs sort last. Within a type the ordering matches Go's natural ordering. Across different non-null types the canonical sequence is:
Path < Node < Relationship < Map < List < String < Boolean < Float < Integer
Concurrency ¶
All Value implementations are immutable after construction. Concurrent reads are safe without external locking.
Index ¶
- func Compare(a, b Value) int
- func HashRow(row []Value) uint64
- func IsNull(v Value) bool
- func IsTruthy(v Value) bool
- type BoolValue
- type BuiltinFn
- type DateTimeValue
- type DateValue
- type DurationValue
- func AddDurations(a, b DurationValue) DurationValue
- func DivDurationFloat(d DurationValue, k float64) DurationValue
- func MulDuration(d DurationValue, k int64) DurationValue
- func MulDurationFloat(d DurationValue, k float64) DurationValue
- func NegateDuration(d DurationValue) DurationValue
- func NewDuration(months, days, seconds int64, nanos int32) DurationValue
- func ParseDuration(s string) (DurationValue, error)
- func SubDateTimes(a, b DateTimeValue) DurationValue
- func SubDates(a, b DateValue) DurationValue
- func SubDurations(a, b DurationValue) DurationValue
- func SubLocalDateTimes(a, b LocalDateTimeValue) DurationValue
- func SubLocalTimes(a, b LocalTimeValue) DurationValue
- func SubTimes(a, b TimeValue) DurationValue
- type EvalError
- type FloatValue
- type FunctionRegistry
- type IntegerValue
- type Kind
- type ListValue
- type LocalDateTimeValue
- func AddDurationToLocalDateTime(v LocalDateTimeValue, d DurationValue) LocalDateTimeValue
- func NewLocalDateTime(y, mo, d, h, mi, s, ns int) LocalDateTimeValue
- func ParseLocalDateTime(s string) (LocalDateTimeValue, error)
- func SubDurationFromLocalDateTime(v LocalDateTimeValue, d DurationValue) LocalDateTimeValue
- type LocalTimeValue
- type MapValue
- type NodeValue
- type PathValue
- type PatternEvaluator
- type RelationshipValue
- type RowContext
- type StringValue
- type SubqueryEvaluator
- type TimeValue
- type Value
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Compare ¶
Compare returns -1, 0, or +1 following openCypher 9 ORDER BY semantics. NULLs sort after all non-null values. Values of different non-null types are ordered by kindOrder. Values of the same type use natural ordering.
Note: this is a total order for sorting purposes only; it does not replace [Value.Equal] for predicate evaluation.
func HashRow ¶
HashRow returns a uint64 hash that represents the ordered sequence of values in row. Two rows whose elements are pairwise equal (per openCypher equality semantics) will have the same hash. The inverse is not guaranteed — callers must verify equality after a hash match.
NULL values contribute their own hash (0) to the mix; they participate in grouping but never compare equal to any value including another NULL.
Types ¶
type BoolValue ¶
type BoolValue bool
BoolValue is a Cypher boolean value (true or false). Note that Cypher's three-valued logic introduces a third truth state, NULL, which is not representable as BoolValue; use Null for that.
type DateTimeValue ¶
DateTimeValue is a date + time + zone.
func AddDurationToDateTime ¶
func AddDurationToDateTime(v DateTimeValue, d DurationValue) DateTimeValue
AddDurationToDateTime adds d to v, preserving v's zone.
func NewDateTime ¶
func NewDateTime(y, mo, d, h, mi, s, ns int, loc *time.Location) DateTimeValue
NewDateTime constructs a DateTimeValue from components and a time.Location.
func ParseDateTime ¶
func ParseDateTime(s string) (DateTimeValue, error)
ParseDateTime parses ISO-8601 zoned date-time: YYYY-MM-DDTHH:MM:SS[.frac][±HH:MM|Z]. A zone suffix is required. An optional trailing bracketed IANA zone name (e.g. "Europe/Stockholm") is honoured when time.LoadLocation resolves it; otherwise the numeric offset is used to build a fixed-zone location.
func SubDurationFromDateTime ¶
func SubDurationFromDateTime(v DateTimeValue, d DurationValue) DateTimeValue
SubDurationFromDateTime is the inverse of AddDurationToDateTime.
func (DateTimeValue) Equal ¶
func (v DateTimeValue) Equal(other Value) Value
Equal implements Value with 3VL semantics. Two DateTimeValues are equal iff they refer to the same instant; the textual zone is not considered.
func (DateTimeValue) String ¶
func (v DateTimeValue) String() string
String renders ISO-8601 yyyy-mm-ddThh:mm:ss[.frac] followed by the zone offset (Z for UTC, +HH:MM otherwise).
type DateValue ¶
type DateValue struct {
// Year is the Gregorian year.
Year int
// Month is 1–12.
Month int
// Day is 1–31, bounded by the days in Month.
Day int
}
DateValue is a calendar date (year/month/day) with no time-of-day and no time zone. The zero value (0001-01-01) is the proleptic Gregorian epoch matching Go's time.Time zero.
func AddDurationToDate ¶
func AddDurationToDate(dv DateValue, d DurationValue) DateValue
AddDurationToDate adds d to dv with calendar-aware rules: months are applied first (clamping to month-end), then days, then sub-day components are dropped (Date has no sub-day component).
func DateFromTime ¶
DateFromTime builds a DateValue from the calendar date of t (in t's own location).
func NewDate ¶
NewDate constructs a DateValue from y/m/d, normalising overflow via time.Date semantics (e.g. month 13 wraps to next year).
func ParseDate ¶
ParseDate parses an ISO-8601 date string. Accepted forms (calendar, week, ordinal):
YYYY-MM-DD, YYYYMMDD, YYYY-MM, YYYYMM, YYYY, YYYY-Www-D, YYYYWwwD, YYYY-Www, YYYYWww, YYYY-DDD, YYYYDDD.
Returns NULL-able semantics: callers receiving an error should treat the value as openCypher TYPE_ERROR (today: surfaced as expr.Null by the caller).
func SubDurationFromDate ¶
func SubDurationFromDate(dv DateValue, d DurationValue) DateValue
SubDurationFromDate is the inverse of AddDurationToDate.
type DurationValue ¶
type DurationValue struct {
// Months is the number of whole months (may be negative).
Months int64
// Days is the number of whole days (may be negative).
Days int64
// Seconds is the number of whole seconds (may be negative).
Seconds int64
// Nanos is the sub-second component in [0, 999_999_999]; the sign is
// carried entirely by Seconds for canonical form.
Nanos int32
}
DurationValue is an ISO-8601 duration with four independent components. Months and days do not reduce to seconds; the executor applies them calendar-aware when added to a temporal value.
func AddDurations ¶
func AddDurations(a, b DurationValue) DurationValue
AddDurations returns a new Duration that is the sum of a and b.
func DivDurationFloat ¶
func DivDurationFloat(d DurationValue, k float64) DurationValue
DivDurationFloat divides d by k. Returns the zero duration when k is zero.
func MulDuration ¶
func MulDuration(d DurationValue, k int64) DurationValue
MulDuration scales d by an integer factor.
func MulDurationFloat ¶
func MulDurationFloat(d DurationValue, k float64) DurationValue
MulDurationFloat scales d by a floating-point factor. The result rounds fractional months/days into the seconds component using the same 30.4368750-day Gregorian-month approximation as ParseDuration.
Fractional nanoseconds (the smallest representable unit) are truncated toward zero — Java's `(long)` cast behaviour, matching the openCypher TCK convention for `duration * scalar` and `duration / scalar`. A half-nano result therefore disappears rather than rounding up: e.g. `duration({nanoseconds: 1}) / 2` yields zero nanoseconds, not 1.
func NewDuration ¶
func NewDuration(months, days, seconds int64, nanos int32) DurationValue
NewDuration normalises the components to canonical form (Nanos in [0, 999_999_999], sign carried by Seconds).
func ParseDuration ¶
func ParseDuration(s string) (DurationValue, error)
ParseDuration parses an ISO-8601 duration in either form:
Designator form P[nY][nMo][nW][nD][T[nH][nMi][nS]] Date-and-time form PYYYY-MM-DDTHH:MM:SS[.fraction]
Fractional components are supported for the final emitted unit (per openCypher); internally the parser absorbs fractional months/days as fractional seconds added to the appropriate component.
func SubDateTimes ¶
func SubDateTimes(a, b DateTimeValue) DurationValue
SubDateTimes returns a-b as a duration with the same calendar-based decomposition as SubLocalDateTimes, but anchored on the absolute instant (both sides shifted to UTC before the calendar walk). Per openCypher, the duration between two DateTime values is independent of their local zones — what matters is the elapsed time on the global timeline. Without the UTC shift, the wall-clock-anchored diff drifts by the zone offset (e.g. 2014-07-21T21:40+0200 to 2015-07-21T21:40+0100 would report P11M instead of P1Y).
func SubDates ¶
func SubDates(a, b DateValue) DurationValue
SubDates returns the duration from b to a (a - b) using calendar-based decomposition into (months, days). Per openCypher, duration.between(date('1984-10-11'), date('2015-06-24')) yields P30Y8M13D — a calendar-anchored count of whole months between the boundaries, with the leftover days projected onto the closing month.
func SubLocalDateTimes ¶
func SubLocalDateTimes(a, b LocalDateTimeValue) DurationValue
SubLocalDateTimes returns a-b as a duration with calendar-based (months, days) plus the wall-clock (hours, minutes, seconds, nanos) remainder. Per openCypher, duration.between of two date-bearing temporals decomposes into the canonical PnYnMnDTnHnMnS form.
func SubLocalTimes ¶
func SubLocalTimes(a, b LocalTimeValue) DurationValue
SubLocalTimes returns a-b as a duration in (Seconds, Nanos).
func SubTimes ¶
func SubTimes(a, b TimeValue) DurationValue
SubTimes returns a-b as a duration in (Seconds, Nanos), normalising both sides to UTC before subtracting. Per openCypher, duration.between(time('14:30'), time('16:30+0100')) yields PT1H — the +01:00 zone shifts the second value's UTC equivalent to 15:30, so the difference is one hour, not two.
func (DurationValue) Equal ¶
func (v DurationValue) Equal(other Value) Value
Equal implements Value with 3VL semantics. Component-wise equality.
func (DurationValue) String ¶
func (v DurationValue) String() string
String renders ISO-8601 duration: P[nM][nD]T[nS]. Always emits the leading "P" and the "T" separator. Zero components are omitted; the all-zero duration renders as "PT0S".
type EvalError ¶
type EvalError struct {
Msg string
}
EvalError is returned when Eval encounters a type or semantic error that is not representable as a NULL (e.g. unknown operator, unsupported AST node).
type FloatValue ¶
type FloatValue float64
FloatValue is a 64-bit IEEE-754 floating-point Cypher value.
func (FloatValue) Equal ¶
func (v FloatValue) Equal(other Value) Value
Equal returns Null if other is Null, BoolValue per IEEE-754 equality otherwise (NaN != NaN). Cross-type Int/Float comparison treats 1.0 == 1 as true, per openCypher numeric equality.
func (FloatValue) String ¶
func (v FloatValue) String() string
String returns the decimal representation of the float.
type FunctionRegistry ¶
type FunctionRegistry interface {
// Resolve returns the BuiltinFn for name, or (nil, false) when unknown.
// name is lower-cased by the caller before lookup.
Resolve(name string) (BuiltinFn, bool)
}
FunctionRegistry resolves built-in and user-defined functions by name. Implementations must be safe for concurrent use (read-only after init).
type IntegerValue ¶
type IntegerValue int64
IntegerValue is a 64-bit signed integer Cypher value.
func (IntegerValue) Equal ¶
func (v IntegerValue) Equal(other Value) Value
Equal returns Null if other is Null, BoolValue(true) when both sides hold the same numeric value (cross-type Int/Float comparison treats 1 == 1.0 as true, per openCypher numeric equality), BoolValue(false) otherwise.
func (IntegerValue) String ¶
func (v IntegerValue) String() string
String returns the decimal representation of the integer.
type Kind ¶
type Kind uint8
Kind identifies the concrete type of a Value.
const ( // KindDate identifies a calendar date (year/month/day). KindDate Kind = iota + 16 // KindLocalDateTime identifies a naive date-time (no zone). KindLocalDateTime // KindDateTime identifies a zoned date-time. KindDateTime // KindLocalTime identifies a naive time-of-day. KindLocalTime // KindTime identifies a zoned time-of-day. KindTime // KindDuration identifies an ISO-8601 duration. KindDuration )
Temporal kind tags. These are appended to the Kind enumeration after the existing graph kinds; ordering for Compare is documented in [kindOrder].
const ( // KindNull is the NULL kind. KindNull Kind = iota // KindInteger is the 64-bit signed integer kind. KindInteger // KindFloat is the 64-bit IEEE-754 float kind. KindFloat // KindString is the UTF-8 string kind. KindString // KindBool is the boolean kind. KindBool // KindList is the ordered list kind. KindList // KindMap is the property map kind. KindMap // KindNode is the graph node kind. KindNode // KindRelationship is the graph relationship kind. KindRelationship // KindPath is the graph path kind. KindPath )
type ListValue ¶
type ListValue []Value
ListValue is an ordered list of Cypher values.
func (ListValue) Equal ¶
Equal returns Null if either operand is Null or contains Null. Returns BoolValue(false) if lengths differ. Otherwise returns Null if any element comparison yields Null, else BoolValue(all elements equal).
type LocalDateTimeValue ¶
type LocalDateTimeValue struct {
// T carries date and time components. The location is always set to UTC
// for canonical storage; callers must not interpret it as a real offset.
T time.Time
}
LocalDateTimeValue is a date + time with no zone. Internally stored as time.Time in UTC; the UTC interpretation is a sentinel, not a real zone.
func AddDurationToLocalDateTime ¶
func AddDurationToLocalDateTime(v LocalDateTimeValue, d DurationValue) LocalDateTimeValue
AddDurationToLocalDateTime adds d to v: months → days → seconds → nanos.
func NewLocalDateTime ¶
func NewLocalDateTime(y, mo, d, h, mi, s, ns int) LocalDateTimeValue
NewLocalDateTime constructs a LocalDateTimeValue from components.
func ParseLocalDateTime ¶
func ParseLocalDateTime(s string) (LocalDateTimeValue, error)
ParseLocalDateTime parses ISO-8601 local date-time: YYYY-MM-DDTHH:MM:SS[.frac] with no zone suffix. Both extended (with separators) and compact forms are accepted; the 'T' separator may be lowercase. A bare date with no time component is accepted as midnight (00:00:00.000000000).
func SubDurationFromLocalDateTime ¶
func SubDurationFromLocalDateTime(v LocalDateTimeValue, d DurationValue) LocalDateTimeValue
SubDurationFromLocalDateTime is the inverse of AddDurationToLocalDateTime.
func (LocalDateTimeValue) Equal ¶
func (v LocalDateTimeValue) Equal(other Value) Value
Equal implements Value with 3VL semantics. Two LocalDateTimeValues are equal iff their components are identical to the nanosecond.
func (LocalDateTimeValue) String ¶
func (v LocalDateTimeValue) String() string
String renders ISO-8601 yyyy-mm-ddThh:mm:ss[.frac] with no zone suffix.
type LocalTimeValue ¶
type LocalTimeValue struct {
// Nanos is the number of nanoseconds since midnight, in [0, 86_400_000_000_000).
Nanos int64
}
LocalTimeValue is a time-of-day with nanosecond precision and no zone.
func AddDurationToLocalTime ¶
func AddDurationToLocalTime(v LocalTimeValue, d DurationValue) LocalTimeValue
AddDurationToLocalTime wraps modulo 24h.
func NewLocalTime ¶
func NewLocalTime(h, m, s, ns int) LocalTimeValue
NewLocalTime constructs a LocalTimeValue from clock components.
func ParseLocalTime ¶
func ParseLocalTime(s string) (LocalTimeValue, error)
ParseLocalTime parses ISO-8601 time strings without zone: HH:MM:SS[.frac], HHMMSS[.frac], HH:MM, HHMM, HH.
func SubDurationFromLocalTime ¶
func SubDurationFromLocalTime(v LocalTimeValue, d DurationValue) LocalTimeValue
SubDurationFromLocalTime is the inverse of AddDurationToLocalTime.
func (LocalTimeValue) Equal ¶
func (v LocalTimeValue) Equal(other Value) Value
Equal implements Value with 3VL semantics.
func (LocalTimeValue) String ¶
func (v LocalTimeValue) String() string
String renders ISO-8601 hh:mm:ss[.frac].
type MapValue ¶
MapValue is a property map from string keys to Cypher values.
func (MapValue) Equal ¶
Equal returns Null if either operand is Null. Returns BoolValue(false) if key sets differ. Otherwise returns Null if any value comparison yields Null, else BoolValue(all values equal).
type NodeValue ¶
type NodeValue struct {
ID uint64
Labels []string
Properties MapValue
// Deleted reports whether the entity has been removed by an earlier
// DELETE / DETACH DELETE clause in the same statement. Property and
// label accessors raise EntityNotFound: DeletedEntityAccess when
// Deleted is true (openCypher 9 §3.5.8 Return2 [15]/[16]); identity
// accessors (id, type) and the structural fields (ID, Type) stay
// readable so `RETURN type(r)` after `DELETE r` still works.
Deleted bool
}
NodeValue represents a graph node at runtime. ID is the storage-layer node identifier. Labels and Properties are the node's metadata as returned by the persistence layer.
func (NodeValue) Equal ¶
Equal returns Null if other is Null, BoolValue(true) iff both refer to the same node (node identity per openCypher semantics). The peer may be a NodeValue (canonical projected form) or an IntegerValue carrying the raw NodeID (the in-pipeline encoding emitted by NodeScan/Expand); both forms compare on the underlying ID so `n = m` and similar equalities work when one operand has flowed through a projection and the other has not.
type PathValue ¶
type PathValue struct {
Nodes []NodeValue
Relationships []RelationshipValue
}
PathValue represents an alternating sequence of nodes and relationships. Nodes has length len(Relationships)+1. An empty path contains exactly one node and no relationships.
func (PathValue) Equal ¶
Equal returns Null if other is Null. Two paths are equal iff they have the same sequence of node and relationship identities.
func (PathValue) String ¶
String returns the openCypher diagnostic representation of the path, wrapped in `<…>` so a path is visibly distinct from a bare node or relationship value. A zero-relationship path of a single node renders as `<(node)>`, matching the TCK convention.
Each relationship is rendered direction-aware against the path's traversal order: when the relationship's storage StartID matches the preceding node, the forward form `-[rel]->` is used; otherwise the reverse form `<-[rel]-` is used. The renderer compares against the rel's StartID rather than re-querying the graph so a relationship projected with explicit direction (e.g. by the named-path fast path) renders consistently.
type PatternEvaluator ¶
type PatternEvaluator interface {
// EvalPattern evaluates pp as an existential predicate and returns a boolean
// Value indicating whether the pattern matches at least one path in the graph.
EvalPattern(ctx context.Context, pp *ast.PathPattern, row RowContext, params map[string]Value) (Value, error)
// EvalPatternComp evaluates pc as a list-producing pattern
// comprehension and returns the projected list. The runtime
// implementation iterates every match of pc.Pattern with the
// bindings in row as anchors.
EvalPatternComp(ctx context.Context, pc *ast.PatternComprehension, row RowContext, params map[string]Value, reg FunctionRegistry) (Value, error)
}
PatternEvaluator evaluates ast.PathPattern expressions used as existential predicates inside WHERE clauses (e.g. WHERE (a)-[:T]->(b)). The evaluator receives the current row context so that bound variables are visible and can be used as anchors for the graph traversal.
EvalPattern must return BoolValue(true) when at least one match for the pattern exists in the graph given the bindings in row, BoolValue(false) when no match exists, or Null when the result is undefined. It must honour the supplied context for cancellation and propagate errors unchanged.
EvalPatternComp is the list-producing variant used for ast.PatternComprehension expressions that survive IR hoisting (e.g. when nested inside a ast.ListComprehension's predicate or projection, where lifting the comprehension out of the per-iteration scope would lose the iteration variable binding). It enumerates every match of pc.Pattern given the bindings in row, evaluates the per-match projection (or returns the matched relationship for the projection-less form), and returns the collected ListValue. WHERE predicates declared inside the comprehension are honoured.
type RelationshipValue ¶
type RelationshipValue struct {
ID uint64
StartID uint64
EndID uint64
Type string
Properties MapValue
// Deleted — see [NodeValue.Deleted].
Deleted bool
}
RelationshipValue represents a graph relationship at runtime. ID is the storage-layer edge identifier. StartID and EndID are the endpoint node IDs.
func (RelationshipValue) Equal ¶
func (v RelationshipValue) Equal(other Value) Value
Equal returns Null if other is Null, BoolValue(true) iff both refer to the same relationship (relationship identity per openCypher semantics). Symmetric to NodeValue.Equal: the peer may be a RelationshipValue (canonical projected form) or an IntegerValue carrying the raw edge ID (the in-pipeline encoding emitted by Expand), so `r = s` compares on the underlying ID regardless of which side has flowed through a projection.
func (RelationshipValue) Hash ¶
func (v RelationshipValue) Hash() uint64
Hash implements Value; identity is determined by ID.
func (RelationshipValue) String ¶
func (v RelationshipValue) String() string
String returns a short diagnostic representation of the relationship.
type RowContext ¶
RowContext maps variable names to their current runtime values. It is typically derived from the current operator row plus the schema mapping maintained by the executor.
type StringValue ¶
type StringValue string
StringValue is a UTF-8 string Cypher value.
func (StringValue) Equal ¶
func (v StringValue) Equal(other Value) Value
Equal returns Null if other is Null, BoolValue per string equality otherwise.
func (StringValue) Hash ¶
func (v StringValue) Hash() uint64
Hash implements Value using FNV-1a for zero-alloc performance.
func (StringValue) String ¶
func (v StringValue) String() string
String returns the value enclosed in double quotes.
type SubqueryEvaluator ¶
type SubqueryEvaluator interface {
// EvalExists evaluates an EXISTS { … } subquery against row and returns
// BoolValue(true) iff the inner plan emits at least one row.
EvalExists(ctx context.Context, sub *ast.ExistsSubquery, row RowContext, params map[string]Value) (Value, error)
// EvalCount evaluates a COUNT { … } subquery against row and returns an
// IntegerValue equal to the number of rows the inner plan emits.
EvalCount(ctx context.Context, sub *ast.CountSubquery, row RowContext, params map[string]Value) (Value, error)
}
SubqueryEvaluator drives ast.ExistsSubquery and ast.CountSubquery expressions at evaluation time. The expression evaluator dispatches every subquery occurrence to one of these methods, passing the current outer row so that correlated bindings are visible inside the subquery.
Implementations must:
- return BoolValue(true) when the inner plan produces ≥1 row, BoolValue(false) otherwise (EvalExists);
- return IntegerValue equal to the exact row count produced by the inner plan, 0 when empty (EvalCount);
- honour the context (used for cancellation and deadlines);
- propagate any error from the inner plan unchanged.
Implementations are expected to compile the subquery's AST once per outer query and reuse the compiled operator across outer rows; per-row state is reset by re-seeding the inner [Argument] leaf via the IR's ArgTag wiring.
type TimeValue ¶
type TimeValue struct {
// Nanos is the number of nanoseconds since midnight, in [0, 86_400_000_000_000).
Nanos int64
// OffsetSec is the zone offset in seconds east of UTC. UTC is 0.
OffsetSec int32
}
TimeValue is a time-of-day with zone offset (seconds east of UTC).
func AddDurationToTime ¶
func AddDurationToTime(v TimeValue, d DurationValue) TimeValue
AddDurationToTime wraps modulo 24h, preserving zone offset.
func NewTime ¶
NewTime constructs a TimeValue from clock components and a zone offset in seconds east of UTC.
func ParseTime ¶
ParseTime parses ISO-8601 time strings WITH zone: HH:MM:SS[.frac]±HH:MM or HH:MM:SS[.frac]Z. Bare time strings (no zone) are rejected.
func SubDurationFromTime ¶
func SubDurationFromTime(v TimeValue, d DurationValue) TimeValue
SubDurationFromTime is the inverse of AddDurationToTime.
type Value ¶
type Value interface {
// Kind returns the kind tag of this value.
Kind() Kind
// Equal returns the three-valued equality result: Null if either operand is
// Null, BoolValue(true/false) otherwise. Callers must never compare Value
// using Go == ; use Equal and then [IsTruthy].
Equal(other Value) Value
// Hash returns a hash suitable for use as a map key. Two values that are
// equal (per openCypher semantics, i.e., IsTruthy(a.Equal(b))) must have
// the same hash. NULL has a defined hash (0) but must never be used as a
// map key in practice.
Hash() uint64
// String returns a human-readable representation of the value.
String() string
}
Value is a typed, immutable Cypher runtime datum. Implementations must be comparable by [Equal] and hashable by [Hash]. All implementations in this package are safe for concurrent reads without external locking.
var Null Value = nullValue{}
Null is the NULL singleton. Comparisons against NULL always return Null.
func Eval ¶
func Eval(expr ast.Expression, row RowContext, params map[string]Value, reg FunctionRegistry) (Value, error)
Eval evaluates expr in the context of row and params. It dispatches on the concrete AST node type and returns the resulting Value. An EvalError is returned for unsupported constructs; all other errors propagate from the function registry.
If reg is nil, function invocations return an EvalError.
Eval does not support subquery expressions (ast.ExistsSubquery, ast.CountSubquery); these return an EvalError. Use EvalWith with a non-nil SubqueryEvaluator to enable subquery evaluation.
Example ¶
ExampleEval evaluates the arithmetic expression `$base + n` where n comes from the row and base from the params map. The result is an IntegerValue.
package main
import (
"fmt"
"github.com/FlavioCFOliveira/GoGraph/cypher/ast"
"github.com/FlavioCFOliveira/GoGraph/cypher/expr"
)
// noRegistry is a FunctionRegistry that resolves nothing; the examples below
// evaluate operator expressions that need no function lookup.
type noRegistry struct{}
func (noRegistry) Resolve(string) (expr.BuiltinFn, bool) { return nil, false }
func main() {
// AST for: n + $base
e := &ast.BinaryOp{
Operator: "+",
Left: &ast.Variable{Name: "n"},
Right: &ast.Parameter{Name: "base"},
}
row := expr.RowContext{"n": expr.IntegerValue(40)}
params := map[string]expr.Value{"base": expr.IntegerValue(2)}
v, err := expr.Eval(e, row, params, noRegistry{})
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println("kind:", v.Kind())
fmt.Println("value:", v) // IntegerValue.String prints the decimal form.
}
Output: kind: Integer value: 42
Example (NullPropagation) ¶
ExampleEval_nullPropagation shows openCypher three-valued logic: any comparison involving NULL evaluates to NULL, not false. IsNull reports the outcome.
package main
import (
"fmt"
"github.com/FlavioCFOliveira/GoGraph/cypher/ast"
"github.com/FlavioCFOliveira/GoGraph/cypher/expr"
)
// noRegistry is a FunctionRegistry that resolves nothing; the examples below
// evaluate operator expressions that need no function lookup.
type noRegistry struct{}
func (noRegistry) Resolve(string) (expr.BuiltinFn, bool) { return nil, false }
func main() {
// AST for: n > 1, with n bound to NULL.
e := &ast.BinaryOp{
Operator: ">",
Left: &ast.Variable{Name: "n"},
Right: &ast.IntLiteral{Value: 1},
}
row := expr.RowContext{"n": expr.Null}
v, err := expr.Eval(e, row, nil, noRegistry{})
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println("is null:", expr.IsNull(v))
}
Output: is null: true
func EvalWith ¶
func EvalWith(ctx context.Context, expr ast.Expression, row RowContext, params map[string]Value, reg FunctionRegistry, subEval SubqueryEvaluator, patEval PatternEvaluator) (Value, error)
EvalWith evaluates expr just like Eval, but threads a context.Context and optional evaluators through the evaluation. The context is used for cancellation and deadlines when subquery or pattern evaluation is involved. subEval handles ast.ExistsSubquery and ast.CountSubquery occurrences; patEval handles ast.PathPattern existential predicates in WHERE clauses.
When subEval is nil, subquery expressions produce an EvalError. When patEval is nil, pattern predicate expressions produce an EvalError.
EvalWith is safe for concurrent use: each call carries its own context and evaluators on the call stack; there is no shared mutable state.