Skip to content

Grammar contract

The website is explanatory. The versioned language contract lives in language/v1.

ArtifactAuthority
grammar.pestCanonical syntax grammar
spec/semantics.mdMeaning and validation rules
fixtures/valid/*.qqlPrograms that must parse and validate
fixtures/invalid/*.qqlAnnotated failures and stable error codes
fixtures/expected/*.jsonCanonical qql.ast/v1 output
qql-core::Parser::parse_allProduction full-script parser

The checked-in grammar modules are generated. language/v1/grammar.pest is the only handwritten core syntax grammar; the generated copy under crates/qql-core/grammar must never be edited directly. After a grammar change, regenerate it with qql-grammar-gen and review the complete diff.

script = [ statement, { ";", statement }, [ ";" ] ] ;
statement = query | scroll | count | upsert | update | delete
| clear-payload | delete-payload | delete-vector
| create | alter | drop | show | facet | batch ;

Every statement family, including the three SHOW forms:

FamilyGrammar production
QUERY ...query
SCROLL FROM ... LIMIT nscroll
COUNT FROM ...count
FACET field FROM ...facet
UPSERT INTO ... VALUES {...}upsert
UPDATE ... SET PAYLOAD / SET VECTORupdate
DELETE FROM ... WHERE ...delete
DELETE PAYLOAD field, ... FROM ... WHERE ...delete-payload
DELETE VECTOR name, ... FROM ... WHERE ...delete-vectors
CLEAR PAYLOAD FROM ... WHERE ...clear-payload
CREATE COLLECTION ...create-collection
CREATE INDEX ON COLLECTION ... FOR fieldcreate-index
ALTER COLLECTION ... WITH <block> (...)alter-collection
DROP COLLECTION ...drop-collection
DROP INDEX ON COLLECTION ... FOR fielddrop-index
CREATE SHARD KEY 'name' ON COLLECTION ...create-shard-key
DROP SHARD KEY 'name' ON COLLECTION ...drop-shard-key
SHOW COLLECTIONS; / SHOW COLLECTION name; / SHOW SHARD KEYS ON COLLECTION name;show-collections / show-collection / show-shard-keys
SHOW QUOTAS; / SET QUOTA (...);show-quotas / set-quota
BATCH { <stmt>; ... } [WAIT ...] [PARAMS ...]batch

A query tail accepts each clause at most once, in this order:

USING (a named vector with optional AS <kind>, or HYBRID) → PREFETCHWHERESHARDPARAMSSCORE THRESHOLDGROUP BY [SIZE n] [LOOKUP FROM collection [WITH PAYLOAD ...] [WITH VECTOR ...]]WITH PAYLOADWITH VECTORLIMITOFFSET.

The parser rejects a duplicate or out-of-order clause with QQL-PARSE-CLAUSE-ORDER rather than silently reordering it.

  • Keywords are ASCII case-insensitive.
  • Identifiers are case-sensitive and preserve spelling.
  • Bare digit literals above i64::MAX parse as unsigned (up to u64::MAX).
  • Formula datetimes format canonical uppercase (DATETIME, DATETIME_KEY); lowercase still parses.
  • Dotted and array payload paths are accepted.
  • Strings support single, double, raw, triple, and backtick delimiters.
  • -- starts a line comment; block comments do not exist.
  • Error spans are zero-based UTF-8 byte ranges [start, end).
Check the language fixtures
RUSTC_WRAPPER= cargo run -p qql-conformance -- check language/v1

The conformance runner parses every valid and invalid case through Parser::parse_all and compares valid programs with generated AST snapshots.

Check generated grammar freshness
cargo run -p qql-grammar-gen -- check

QQL follows MAJOR.MINOR; the current language version is 1.7 while the canonical AST schema is independently fixed as qql.ast/v1.

QQL 1.7 adds parameter placeholder productions (param = ":" identifier | "?") across query inputs, point IDs, scalars, and clauses (SHARD, LIMIT, OFFSET, SCORE THRESHOLD). Placeholders are substituted client-side by the SDK binders before planning — see Parameter binding.

QQL 1.7 also adds trailing WAIT true | false on UPSERT, DELETE, CLEAR/DELETE PAYLOAD, DELETE VECTOR, UPDATE VECTOR/PAYLOAD and CREATE INDEX (after SHARD), typed shard keys end-to-end (SHARD 101, numeric CREATE/DROP SHARD KEY), and ALTER COLLECTION per-vector diffs (WITH VECTOR [name] (...), WITH SPARSE name (...)) — see Collections & indexes.

  • Within one major version, every program valid in an earlier minor release must stay valid with the same meaning and canonical AST. A minor release may only make previously invalid source valid by adding syntax.
  • Breaking changes (removing syntax, changing clause order, precedence, or an existing fixture's normalization, renaming AST tags, or changing a stable error code) require QQL 2.
  • QQL 1.0 has no compatibility parser: pre-v1 SELECT, INSERT, and BOOST are invalid source, not deprecated aliases.
  • Deprecated v1 features may be announced but cannot be removed within v1.

See language/v1/spec/versioning.md for the full policy.