Skip to content

[Cypher] datetime() value not persisted when SET on a DATETIME-typed property #4125

@Inodix

Description

@Inodix

Summary

Setting a property typed DATETIME to the Cypher datetime() value reports the value in the same statement's RETURN projection, but the value is NOT persisted — a subsequent MATCH returns null for
the property. The same data round-trips correctly when (a) the property is typed STRING instead of DATETIME, or (b) the assignment goes through SQL sysdate() rather than Cypher datetime().

Environment

  • ArcadeDB 26.5.1-SNAPSHOT (build 1dc68da159f12ef9c8c436e5b5998a7ab483714b)
  • HTTP API /api/v1/command/<db> with language=cypher
  • Reproduced fresh (no MERGE, no UNIQUE index, no transaction wrapper) — pure raw HTTP

Reproduction

Schema:

CREATE VERTEX TYPE Foo;
CREATE PROPERTY Foo.id STRING;                                                                                                                                                                                 
CREATE PROPERTY Foo.t DATETIME;

Failing case A — CREATE with inline datetime()

CREATE (n:Foo {id: "a", t: datetime()}) RETURN n.t AS t   

Returns [{"t":null}] — the value is null even in the originating statement's RETURN.
Subsequent MATCH (n:Foo {id:"a"}) RETURN n.t[{"t":null}].

Failing case B — SET after CREATE

CREATE (n:Foo {id: "b"});
MATCH (n:Foo {id: "b"}) SET n.t = datetime() RETURN n.t AS t; 

Returns [{"t":"2026-05-07T12:37:33.058190574Z[GMT]"}] in the same statement.
But: MATCH (n:Foo {id:"b"}) RETURN n.t[{"t":null}]not persisted.

Failing case C — SET with explicit ISO string

MATCH (n:Foo {id: "c"}) SET n.t = datetime("2026-01-01T00:00:00") RETURN n.t AS t                                                                                                                              

Same shape: same-statement RETURN gives 2026-01-01T00:00Z, follow-up MATCH gives null.

Working case D — SQL sysdate()

UPDATE Foo SET t = sysdate() WHERE id = 'd'               

Subsequent Cypher MATCH (n:Foo {id:"d"}) RETURN n.t AS t[{"t":"2026-05-07 12:37:33"}]. Persists correctly.

Working case E — STRING property, same Cypher value

CREATE PROPERTY Foo.s STRING;                                                                                                                                                                                  
MATCH (n:Foo {id: "e"}) SET n.s = datetime() RETURN n.s AS s

Both same-statement RETURN and follow-up MATCH → [{"s":"2026-05-07T12:37:33.209202625Z[GMT]"}]. Persists correctly (because the column is STRING, not DATETIME).

Whole-record dump after all 5 cases

[                                                                                                                                                                                                              
  {"@rid":"#1:0","@type":"Foo","@cat":"v","t":null,"id":"a"},
  {"@rid":"#1:1","@type":"Foo","@cat":"v","id":"b"},         
  {"@rid":"#1:2","@type":"Foo","@cat":"v","id":"c"},                                                                                                                                                           
  {"@rid":"#1:3","@type":"Foo","@cat":"v","id":"d","t":"2026-05-07 12:37:33"},                                                                                                                                 
  {"@rid":"#1:4","@type":"Foo","@cat":"v","id":"e","s":"2026-05-07T12:37:33.209202625Z[GMT]"}                                                                                                                  
]                                                                                                                                                                                                              

Note that records #1:1 and #1:2 (cases B and C) have no t field at all in the persisted record — the SET silently dropped.

Expected behavior

SET n.t = datetime() on a DATETIME-typed property should persist the current timestamp as a DATETIME value, identical to SQL sysdate().

Impact

This is the only reason a Cypher MERGE … ON CREATE SET t = datetime() ON MATCH SET t = datetime() upsert flow can't be used today — it forces a fallback to SQL UPDATE … UPSERT WHERE via the HTTP API.
Also affects any pure-Cypher write path that tracks timestamps on typed columns.

Possibly related to #4089 (no-throw fix landed in 26.5.1, the persistence side appears separate).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions