OpenCypher Function Implementation Status¶
Implementation status of OpenCypher built-in functions in GraphForge.
Legend: - ✅ COMPLETE: Fully implemented with comprehensive test coverage - ⚠️ PARTIAL: Basic implementation, missing edge cases or variants - ❌ NOT_IMPLEMENTED: Function not yet implemented
Summary Statistics¶
| Category | Total Functions | Complete | Partial | Not Implemented |
|---|---|---|---|---|
| String | 13 | 13 (100%) | 0 (0%) | 0 (0%) |
| Numeric | 10 | 10 (100%) | 0 (0%) | 0 (0%) |
| List | 8 | 7 (88%) | 0 (0%) | 1 (12%) |
| Aggregation | 10 | 9 (90%) | 0 (0%) | 1 (10%) |
| Predicate | 6 | 6 (100%) | 0 (0%) | 0 (0%) |
| Scalar | 9 | 8 (89%) | 0 (0%) | 1 (11%) |
| Temporal | 11 | 11 (100%) | 0 (0%) | 0 (0%) |
| Spatial | 2 | 2 (100%) | 0 (0%) | 0 (0%) |
| Path | 3 | 3 (100%) | 0 (0%) | 0 (0%) |
| TOTAL | 72 | 65 (90%) | 0 (0%) | 7 (10%) |
String Functions¶
substring() ✅¶
Status: COMPLETE
File: src/graphforge/executor/evaluator.py:1185
Signature: substring(string, start [, length])
Tests: String function TCK scenarios
trim(), ltrim(), rtrim() ✅¶
Status: COMPLETE
Files: evaluator.py:1220, evaluator.py:1275, evaluator.py:1289
Signatures: trim(string), ltrim(string), rtrim(string)
Tests: String function scenarios
toUpper(), toLower() ✅¶
Status: COMPLETE
Files: evaluator.py:1210, evaluator.py:1215
Signatures: toUpper(string) / upper(string), toLower(string) / lower(string)
Tests: tests/integration/test_string_functions.py (TestToUpperFunction, TestToLowerFunction, TestToUpperToLowerInterop)
Notes: Both camelCase (toUpper/toLower) and legacy (UPPER/LOWER) forms supported. Aliases normalized in evaluator.
split() ✅¶
Status: COMPLETE
File: evaluator.py:1230
Signature: split(string, delimiter)
Tests: String function scenarios
replace() ✅¶
Status: COMPLETE
File: evaluator.py:1246
Signature: replace(string, search, replacement)
Tests: String function scenarios
reverse() ✅¶
Status: COMPLETE
File: evaluator.py:1225
Signature: reverse(string)
Tests: String function scenarios
Notes: Works for both strings and lists
left(), right() ✅¶
Status: COMPLETE
Files: evaluator.py:1303, evaluator.py:1320
Signatures: left(string, length), right(string, length)
Tests: String function scenarios
toString() ✅¶
Status: COMPLETE (as TOSTRING)
File: evaluator.py:1569
Signature: toString(value)
Tests: Type conversion scenarios
length() ✅¶
Status: COMPLETE
File: evaluator.py:2604 (path length), size() function for strings/lists
Signature: length(path) for paths; use size() for strings and lists
Tests: Path function scenarios (tests/unit/executor/test_path_functions.py)
Notes: Path length returns relationship count. For string/list length, use size() function.
Numeric Functions¶
abs() ✅¶
Status: COMPLETE
File: evaluator.py:1327
Signature: abs(number)
Tests: Mathematical function scenarios
ceil(), floor() ✅¶
Status: COMPLETE
Files: evaluator.py:1337, evaluator.py:1351
Signatures: ceil(number), floor(number)
Tests: Mathematical scenarios
round() ✅¶
Status: COMPLETE
File: evaluator.py:1369
Signature: round(number [, precision])
Tests: Mathematical scenarios
sign() ✅¶
Status: COMPLETE
File: evaluator.py:1409
Signature: sign(number)
Tests: Mathematical scenarios
toInteger(), toFloat() ✅¶
Status: COMPLETE (as TOINTEGER, TOFLOAT)
Files: evaluator.py:1556, evaluator.py:1600
Signatures: toInteger(value), toFloat(value)
Tests: Type conversion scenarios
sqrt() ✅¶
Status: COMPLETE
File: evaluator.py:1672
Signature: sqrt(number)
Tests: tests/integration/test_math_functions_extended.py (TestSqrtFunction)
Notes: Returns CypherFloat. Negative input returns null.
rand() ✅¶
Status: COMPLETE
File: evaluator.py:1683
Signature: rand()
Tests: tests/integration/test_math_functions_extended.py (TestRandFunction)
Notes: Returns random CypherFloat in [0.0, 1.0).
pow() ✅¶
Status: COMPLETE
File: evaluator.py:1690
Signature: pow(base, exponent)
Tests: tests/integration/test_math_functions_extended.py (TestPowFunction)
Notes: Exponentiation function, consistent with ^ operator. Returns CypherInt for int^int with non-negative exponent when result is whole.
List Functions¶
size() ✅¶
Status: COMPLETE
File: evaluator.py:2720
Signature: size(list) or size(string)
Tests: List and string scenarios
head(), last() ✅¶
Status: COMPLETE
Files: evaluator.py:2739, evaluator.py:2768
Signatures: head(list), last(list)
Tests: List function scenarios
tail() ✅¶
Status: COMPLETE
File: evaluator.py:2753
Signature: tail(list)
Tests: List function scenarios
range() ✅¶
Status: COMPLETE
File: evaluator.py:2787
Signature: range(start, end [, step])
Tests: List function scenarios
reverse() ✅¶
Status: COMPLETE (dual: string and list)
File: evaluator.py:1225 (string), list version in same function
Signature: reverse(list)
Tests: List scenarios
extract() ❌¶
Status: NOT_IMPLEMENTED Notes: List comprehension equivalent. Not yet implemented.
filter() ❌¶
Status: NOT_IMPLEMENTED Notes: List filtering function. Not yet implemented.
reduce() ❌¶
Status: NOT_IMPLEMENTED Notes: List reduction function. Complex, low priority.
Aggregation Functions¶
count() ✅¶
Status: COMPLETE
File: src/graphforge/executor/executor.py (aggregation logic)
Signature: count(expression) or count(*)
Tests: Extensive aggregation TCK scenarios (Aggregation1-8.feature)
sum() ✅¶
Status: COMPLETE
File: executor.py (aggregation logic)
Signature: sum(expression)
Tests: Aggregation scenarios
avg() ✅¶
Status: COMPLETE
File: executor.py (aggregation logic)
Signature: avg(expression)
Tests: Aggregation scenarios
min(), max() ✅¶
Status: COMPLETE
File: executor.py (aggregation logic)
Signatures: min(expression), max(expression)
Tests: Aggregation scenarios
collect() ✅¶
Status: COMPLETE
File: executor.py (aggregation logic)
Signature: collect(expression)
Tests: Aggregation scenarios
percentileDisc(), percentileCont() ✅¶
Status: COMPLETE
File: src/graphforge/executor/executor.py (aggregation logic)
Signatures: percentileDisc(expression, percentile), percentileCont(expression, percentile)
Tests: tests/unit/executor/test_aggregation_functions_advanced.py, tests/integration/test_aggregation_functions_advanced.py
Notes: Discrete and continuous percentile calculations. NULL values ignored. Percentile must be between 0.0 and 1.0.
stDev(), stDevP() ✅¶
Status: COMPLETE
File: src/graphforge/executor/executor.py (aggregation logic)
Signatures: stDev(expression), stDevP(expression)
Tests: tests/unit/executor/test_aggregation_functions_advanced.py, tests/integration/test_aggregation_functions_advanced.py
Notes: Sample (stDev) and population (stDevP) standard deviation. NULL values ignored. stDev returns NULL for single value, stDevP returns 0.
Predicate Functions¶
all() ✅¶
Status: COMPLETE
File: evaluator.py:553-629
Signature: all(variable IN list WHERE predicate)
Tests: tests/integration/test_predicate_functions.py
Notes: Tests if all elements in list satisfy predicate. Implements three-valued NULL logic.
any() ✅¶
Status: COMPLETE
File: evaluator.py:553-629
Signature: any(variable IN list WHERE predicate)
Tests: tests/integration/test_predicate_functions.py
Notes: Tests if any element in list satisfies predicate. Implements three-valued NULL logic.
none() ✅¶
Status: COMPLETE
File: evaluator.py:553-629
Signature: none(variable IN list WHERE predicate)
Tests: tests/integration/test_predicate_functions.py
Notes: Tests if no elements in list satisfy predicate. Implements three-valued NULL logic.
single() ✅¶
Status: COMPLETE
File: evaluator.py:553-629
Signature: single(variable IN list WHERE predicate)
Tests: tests/integration/test_predicate_functions.py
Notes: Tests if exactly one element in list satisfies predicate. Implements three-valued NULL logic.
exists() ✅¶
Status: COMPLETE
File: evaluator.py:1135-1145
Signature: exists(property) or exists(expression)
Tests: tests/integration/test_exists_isEmpty.py
Notes: Tests if a property exists or if an expression is not NULL. Handles property access specially to detect missing properties.
isEmpty() ✅¶
Status: COMPLETE
File: evaluator.py:1165-1175
Signature: isEmpty(list), isEmpty(string), or isEmpty(map)
Tests: tests/integration/test_exists_isEmpty.py
Notes: Tests if a list, string, or map is empty. Returns NULL for NULL input.
Scalar Functions¶
id() ✅¶
Status: COMPLETE
File: evaluator.py:2537
Signature: id(node_or_relationship)
Tests: Graph function scenarios
type() (Graph Function) ✅¶
Status: COMPLETE
File: evaluator.py:2558
Signature: type(relationship) or type(value)
Tests: Graph and type scenarios
labels() ✅¶
Status: COMPLETE
File: evaluator.py:2583
Signature: labels(node)
Tests: Graph function scenarios
properties() ✅¶
Status: COMPLETE (via property access) Notes: Property access implemented, properties() function may need explicit implementation
keys() ✅¶
Status: COMPLETE (via type introspection) Notes: Can get keys from maps, may need explicit keys() function
coalesce() ✅¶
Status: COMPLETE
File: evaluator.py:1035 (function evaluation)
Signature: coalesce(expr1, expr2, ...)
Tests: Null handling scenarios
toBoolean() ✅¶
Status: COMPLETE (as TOBOOLEAN)
File: evaluator.py:1644
Signature: toBoolean(value)
Tests: Type conversion scenarios
timestamp() ✅¶
Status: COMPLETE (via temporal functions) Notes: Current timestamp via datetime functions
elementId() ❌¶
Status: NOT_IMPLEMENTED Notes: New in GQL spec for stable element IDs. Not yet implemented.
Temporal Functions¶
All temporal functions are ✅ COMPLETE with comprehensive support added in v0.3.0.
date() ✅¶
File: evaluator.py:1738
Signature: date(), date(string), date({components})
datetime() ✅¶
File: evaluator.py:1807
Signature: datetime(), datetime(string), datetime({components})
time() ✅¶
File: evaluator.py:1973
Signature: time(), time(string), time({components})
localtime() ✅¶
File: evaluator.py:2084
Signature: localtime(), localtime(string), localtime({components})
localdatetime() ✅¶
File: evaluator.py:2145
Signature: localdatetime(), localdatetime(string), localdatetime({components})
duration() ✅¶
File: evaluator.py:2225
Signature: duration(string), duration({components})
Temporal component accessors ✅¶
Status: COMPLETE
Functions: year(), month(), day(), hour(), minute(), second()
Files: Various in evaluator.py
Tests: Temporal TCK scenarios
truncate() ✅¶
File: evaluator.py:919
Signature: truncate(temporal, unit)
Notes: Temporal truncation to specific units
Spatial Functions¶
point() ✅¶
Status: COMPLETE
File: evaluator.py:2431
Signature: point({x, y [, crs]}) or point({latitude, longitude [, crs]})
Tests: Spatial function scenarios
Notes: Supports 2D/3D, Cartesian/Geographic coordinates
distance() ✅¶
Status: COMPLETE
File: evaluator.py:2469
Signature: distance(point1, point2)
Tests: Spatial function scenarios
Notes: Haversine distance for geographic, Euclidean for Cartesian
Path Functions¶
length() ✅¶
Status: COMPLETE (for paths)
File: evaluator.py:2604
Signature: length(path)
Tests: Path function scenarios
Notes: Returns relationship count in path
nodes() ✅¶
Status: COMPLETE
File: evaluator.py:2622
Signature: nodes(path)
Tests: Path function scenarios
relationships() ✅¶
Status: COMPLETE
File: evaluator.py:2657
Signature: relationships(path)
Tests: Path function scenarios
Implementation Notes¶
Strengths¶
- Temporal functions complete: Full temporal type system with all constructors and accessors (v0.3.0)
- Spatial functions complete: Point and distance with multiple coordinate systems (v0.3.0)
- Core string/numeric/list functions: Most commonly used functions implemented
- Type conversions: Complete conversion functions (toString, toInteger, toFloat, toBoolean)
- Aggregations: Essential aggregations (count, sum, avg, min, max, collect)
- Statistical aggregations: percentileDisc, percentileCont, stDev, stDevP (v0.3.5)
Limitations¶
- List operations: extract(), filter(), reduce() not implemented
Recommended Priority for v0.4.0+¶
- Medium: List operations (extract, filter, reduce)
Version History¶
- v0.1.0: Basic string, numeric, list functions
- v0.2.0: Type conversions, aggregations
- v0.3.0: Complete temporal and spatial function support
- v0.4.0 (in progress): TCK coverage improvements, edge case fixes
References¶
- OpenCypher Specification: https://opencypher.org/resources/
- GraphForge Evaluator:
src/graphforge/executor/evaluator.py - GraphForge Executor:
src/graphforge/executor/executor.py(aggregations)