fix(cypher): exclude schema commands from async create node batch handler#25
Merged
orneryd merged 2 commits intoorneryd:mainfrom Feb 28, 2026
Merged
Conversation
CREATE CONSTRAINT and CREATE INDEX queries were being intercepted by tryAsyncCreateNodeBatch before reaching the schema handler. The async batch handler has no async engine in unit tests (so tests pass), but in production the async engine is active, causing schema queries to be parsed as node CREATE patterns — resulting in "invalid label name: Node)" errors during Mimir schema initialization. Fix: add CONSTRAINT, INDEX, FULLTEXT, VECTOR, and RANGE to the early- return exclusion list alongside the existing DATABASE/ALIAS exclusions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reproduces the bug where CREATE CONSTRAINT / CREATE INDEX queries fail when an AsyncEngine is active (production deployments) but pass in MemoryEngine-based unit tests (masking the bug in CI). Uses the full production-equivalent stack (BadgerEngine → WALEngine → AsyncEngine) to exercise the tryAsyncCreateNodeBatch routing path. Covers all eight schema queries issued by Mimir v4.1 during GraphManager initialisation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a bug where
CREATE CONSTRAINTandCREATE INDEXqueries fail with:when NornicDB is running with an
AsyncEngineactive (i.e. all production deployments).Root Cause
tryAsyncCreateNodeBatchintercepts all queries that begin withCREATEto batch node writes through the async engine. This is correct forCREATE (n:Label)data mutations, but it also incorrectly intercepts schema DDL commands (CREATE CONSTRAINT,CREATE INDEX,CREATE FULLTEXT INDEX,CREATE VECTOR INDEX,CREATE RANGE INDEX) before the schema handler runs.The parser then attempts to extract a label from the schema syntax — e.g. from
FOR (n:Node) REQUIRE n.id IS UNIQUE— and capturesNode)(including the closing paren) as the label name, producing the invalid label error.Why tests didn't catch this: The existing test suite uses
MemoryEngine. When noAsyncEngineis present,tryAsyncCreateNodeBatchreturns early at theif engines.asyncEngine != nilguard — so the bug is completely masked in CI, but triggers on every production startup.Fix
Added
CONSTRAINT,INDEX,FULLTEXT,VECTOR, andRANGEto the early-return exclusion list insidetryAsyncCreateNodeBatch, alongside the already-excludedDATABASE,COMPOSITE DATABASE, andALIASkeywords:These keywords cause the function to return
(nil, nil, false), allowing the query to fall through toexecuteSchemaCommandwhere it is correctly parsed and executed.Regression Test
Added
pkg/cypher/bug_schema_async_routing_test.gowhich exercises the full production-equivalent storage stack (BadgerEngine → WALEngine → AsyncEngine) — the exact condition that exposes the bug and thatMemoryEngine-based tests cannot catch.The test covers all eight schema queries issued by Mimir v4.1 during
GraphManagerinitialisation:CREATE CONSTRAINT node_id_unique IF NOT EXISTS FOR (n:Node) REQUIRE n.id IS UNIQUECREATE FULLTEXT INDEX node_search IF NOT EXISTS FOR (n:Node) ON EACH [n.properties]CREATE INDEX node_type IF NOT EXISTS FOR (n:Node) ON (n.type)CREATE CONSTRAINT watch_config_id_unique IF NOT EXISTS FOR (w:WatchConfig) REQUIRE w.id IS UNIQUECREATE INDEX watch_config_path IF NOT EXISTS FOR (w:WatchConfig) ON (w.path)CREATE INDEX file_path IF NOT EXISTS FOR (f:File) ON (f.path)CREATE FULLTEXT INDEX file_metadata_search IF NOT EXISTS FOR (f:File) ON EACH [f.path, f.name, f.language]CREATE VECTOR INDEX node_embedding_index IF NOT EXISTS FOR (n:Node) ON (n.embedding) OPTIONS {indexConfig: {vector.dimensions: 1024}}All 8 pass after the fix; all 8 fail (with "invalid label name") on the unfixed code.
Reproduction Context
Discovered while integrating NornicDB as the backing store for Mimir (https://github.com/orneryd/Mimir), which is maintained by the same org. On every Mimir startup,
GraphManagersends these schema commands and every one fails — making the database unusable in production.Environment:
arm64-metal-bge-heimdallimage, Docker with Colima (aarch64, VZ)Checklist
TestBug_SchemaCommandsWithAsyncEngine)go fmtapplied to all changed files