Skip to content

Catch the binding up to the engine - #27

Merged
tamnd merged 4 commits into
mainfrom
engine-green
Aug 25, 2026
Merged

tamnd merged 4 commits into
mainfrom
engine-green

Conversation

@tamnd

@tamnd tamnd commented Aug 25, 2026

Copy link
Copy Markdown
Owner

The engine job in CI is red and it dies at its first step, which is a
diff of the vendored header against the engine's own. Three separate
things are behind it and the two issues both say they want to land
together, so they are here as three commits.

The header is four accessors behind: zu_error_subject_kind,
zu_error_subject, zu_error_graph and zu_error_schema. They are the
rest of what ISO 39075 subclause 23.2 asks a diagnostic record to carry,
and Error now has the four fields to match. The subject is what the
condition is about when it is about something the statement named, kept
as a kind and a name rather than one string, so that asking whether a
failure is about a label is one comparison against one word. The graph
and the schema are where the statement was running and are empty
together when the failure predates a connection. MATCH (a:person) RETURN b.uid AS uid is the test: variable, b, graph home, schema
/. A division by zero is the other one, since it is about no name and
carries neither half rather than carrying an empty string as though it
were one.

Ten words became reserved in the engine and six of them are aliases in
the tests here. A reserved word after AS is a syntax error, so the
next lib.yml run that moves the pin would have turned all six red at
once. The renames are only in test text, since nothing in the package
itself names a column. I swept the other four clients the same way,
matching every alias against the reserved and pre-reserved lists in the
engine's generated keywords: zu-node, zu-java and zu-c are clean, and
zu-python's one hit was DuckDB SQL in a comparison test.

The third is the corpus runner's test that a case ahead of the engine
comes back unsupported rather than failed. It used SELECT 1 as a
statement no engine had reached, and the engine parses SELECT now, so
the case ran and the test was grading a real failure as a gap. CREATE NODE TABLE person(uid INT64) replaces it. The same assumption was in
the Java runner this was ported from and it was fixed there in
tamnd/zu-java#20.

Verified on a Linux host against the engine at 55382df, with the
header diff reporting a match and all three link modes built. Plain
run, everything green including corpus at 95s over the full case
directory. Race run, everything green including corpus at 104s.
Locally gofmt -l . is clean and the surface and doc gates pass under
CGO_ENABLED=0.

The vendored pin is still at f0ba1219, ninety four commits back. That
is the third piece both issues name and it moves by dispatching
lib.yml, which opens its own PR. It goes second on purpose, so the
pin bump arrives with these tests already fixed rather than red on
arrival.

Closes #25
Closes #26

tamnd and others added 4 commits August 25, 2026 07:33
The engine grew four accessors on an error handle and the vendored
header did not have them, which is what the engine job in CI notices
first: it diffs the header against the one in the engine tree and stops
there. The four are zu_error_subject_kind, zu_error_subject,
zu_error_graph and zu_error_schema.

They are the rest of what ISO 39075 subclause 23.2 asks a diagnostic
record to carry. The subject is what the condition is about when it is
about something the statement named, split into a kind and a name so
that asking whether a failure is about a label is one string compared
against one word rather than a sentence parsed for a quoted thing. The
graph and the schema are where the statement was running, which are
empty together when the failure happened before there was a connection
at all.

A program that underlines the offending name in an editor is the case
this is for. Before this it had to find the name inside English prose,
which is the whole reason these are fields.

The header is copied from the engine tree rather than edited, so the
diff step passes by construction.

Closes #25
Ten words became reserved in the engine and six of them are spelled as
aliases in these tests: nothing, sum, count and next, plus the same
sum in two of the zusql examples. A reserved word after AS is a syntax
error, so the next lib.yml run that moves the vendored pin turns all of
them red at the same moment, which is a confusing way to find out.

The renames are only in the test text. Nothing in the package names a
column, so there is nothing here for a user to notice. Where the Go
variable was named after the column it moves with it, so the two still
read as the same thing.

I swept the other four clients the same way, matching every alias
against the reserved and pre-reserved lists in the engine's generated
keywords: zu-node, zu-java and zu-c are clean, and zu-python had one
false positive that turned out to be DuckDB SQL in a comparison test.

Closes #26
The corpus runner has a test saying a case ahead of the engine comes
back unsupported rather than failed, which is what lets the corpus be
the contract and the engine catch up to it. It used SELECT 1 as the
statement no engine had reached yet. The engine parses SELECT now, so
the case ran, came back with a column named 1 where the case wanted n,
and the test was grading a real failure as though it were a gap.

CREATE NODE TABLE person(uid INT64) is the replacement. It refuses with
42001 and the message says CREATE is not implemented yet.

A test like this is a canary by construction and the comment now says
so: the day CREATE lands, this stops testing what it says it tests and
has to pick another spelling. The same assumption was in the Java
runner this was ported from and it was fixed there in tamnd/zu-java#20.
@tamnd

tamnd commented Aug 25, 2026

Copy link
Copy Markdown
Owner Author

The vendored pin had to come into this branch rather than follow it. I
had it the other way round at first, on the reasoning that the pin bump
should arrive with the tests already fixed, and CI said no in the
plainest way available: every vendored job failed to link. The archives
at f0ba1219 do not export the four accessors the refreshed header
declares, so a header refresh on its own is a build that compiles and
then has nothing to call.

nm on the old darwin-arm64 archive lists eleven zu_error_ symbols
and stops at zu_error_status. That is the whole story.

So the Libraries workflow ran on this branch instead of on main, which
puts its propose job's checkout here and its commit on top of these
three. It is folded in unchanged as ffbb4bb and #28 is closed. The
same archive now lists the four:

_zu_error_graph
_zu_error_schema
_zu_error_subject
_zu_error_subject_kind

The pin is a92d9c1 and not the 55382df I verified on the Linux host,
because the engine job checks out tamnd/zu with no ref and so always
diffs against current main. Building against anything older would have
put the header back out of date the moment it landed. The header is
byte identical between those two revisions, which is what made moving
the pin forward safe to do without redoing the header work.

Green locally against the new archives on darwin-arm64, every package
including corpus. The Linux host is rebuilding at a92d9c1 to repeat
the system and static link modes there.

@tamnd
tamnd merged commit dcf4d74 into main Aug 25, 2026
14 checks passed
@tamnd
tamnd deleted the engine-green branch August 25, 2026 00:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant