Skip to content

Qirava DMS docs

DDL: CREATE TABLE (schema/schemaless, columns, TTL)

Tables are created with QQL, like everything else: CREATE TABLE <name> [SCHEMALESS | SCHEMA <col>:<type> ...]. A schemaless table accepts any fields; a schema table declares typed columns and is validated strictly on every write. Both share one implicit, DB-generated, immutable primary key _id. Vector columns carry a fixed dimension (vector(<dim>)). Tables can also declare a TTL field for automatic expiry. Created user tables are recorded in the _sys_tables system catalog so the schema is data in the system DB. This page covers the syntax, column types, validation rules, TTL, and the catalog.

CREATE TABLE syntax#

CREATE TABLE <name> SCHEMALESS (the default — the SCHEMALESS keyword is optional) creates a free-form table. CREATE TABLE <name> SCHEMA <col>:<type> <col>:<type> ... creates a strictly-validated typed table with at least one column. Table names must be non-empty, ≤ 128 chars, and use only lowercase letters, digits, _, and ..

Request

CREATE TABLE users SCHEMALESS
CREATE TABLE items SCHEMA name:str e:vector(4)

Response

// each -> { "error": null, "data": null, "root": { "count": 0 } }

Column types#

Type keywordColumnTypeAccepts
intInti64 integer
bigintBigIntarbitrary-precision integer
decimalDecimalarbitrary-precision exact decimal
floatFloatf64
timestampTimestampnanoseconds since epoch (i64)
boolBooltrue / false
str / stringStrUTF-8 string
bytesBytesbyte blob
listListordered list
mapMapkey→value object
vector(<dim>)Vector(dim)fixed-dimension f32 embedding

Schema validation rules#

Schemaless tables always pass validation. Schema tables are strict on every INSERT and UPDATE:

  • Every declared column must be present and match its type (a non-nullable column that is missing or null is a missing-field error).
  • A vector column's value must have EXACTLY the declared dimension, else a vector-dim error.
  • Unknown fields (not a declared column) are rejected.
  • Columns can be declared nullable to allow absence/null.

Request

-- users SCHEMA name:str age:int
INSERT INTO users { name: "x", age: "oops" }

Response

{ "error": { "code": "bad_request", "message": "field 'age' expected Int" }, "data": null, "root": { "count": 0 } }

The implicit primary key#

Every table has an implicit _id primary key: a DB-generated, monotonically increasing integer assigned on INSERT and immutable thereafter. You never declare it and cannot set or change it — supplying _id in an INSERT or UPDATE is ignored. _id powers the O(1) point-read path (WHERE _id = n) and the per-record write serialization key.

TTL (time-to-live) expiry#

A table can declare a TTL field holding a unix-seconds expiry; the scheduled sweeper deletes rows whose expiry <= now. Declare a Filter index on the TTL field so the sweep is index-served (a range scan, no full scan). TTL is set on the table definition (via with_ttl(field) in code); see the TTL Sweep page for the maintenance flow.

The _sys_tables catalog#

Creating a non-system table records a row in _sys_tables with its name, mode (schemaless/schema), and columns (a comma-separated col:type string). This makes the schema queryable like any other data and lets a durable engine restore the full catalog on restart. (Tables whose name starts with _sys_ are not self-recorded.)

Request

SELECT name FROM _sys_tables

Response

// after creating `users` and `items`:
{ "error": null, "data": [ { "name": "users" }, { "name": "items" } ], "root": { "count": 2 } }