SMQL language reference
Applies to: development tools; not published APT 0.1.0-2. For examples and pagination instructions, start with Query with SMQL.
Statement structure
SELECT (* | column [, column ...])
FROM [database.]table
[WHERE predicate [AND predicate ...]]
[LIMIT integer]
[;]
predicate := column (= | < | <= | > | >=) literal
| column IS NOT NULL
Only one statement is accepted. There are no SQL comments, aliases, arithmetic
expressions, parentheses, parameter placeholders, or functions. Joins, OR, IN,
LIKE, BETWEEN, NOT, !=, <>, ORDER BY, GROUP BY, DISTINCT, COUNT, OFFSET, subqueries,
and write/DDL statements are unsupported. NOT is accepted only in IS NOT NULL.
An unsupported clause fails the entire query; no prefix is executed.
Identifiers and database selection
Bare identifiers start with an ASCII letter or underscore, followed by ASCII
letters, digits, or underscores. Use double quotes for other names, for example
"display-name" or "用户"; a doubled double quote represents a literal quote.
Table and column names contain 1–64 UTF-8 bytes. Names are case-sensitive;
keywords are case-insensitive. Duplicate projection columns are rejected.
Database names contain 1–64 ASCII letters, digits, underscores, or hyphens.
Quote names containing hyphens. A qualified database.table overrides the
selected database; an unqualified table uses --database in the CLI or the web
Database field. The CLI defaults to default.
Values and comparisons
| Type | Literal example | Behavior |
|---|---|---|
| String | 'O''Brien' |
Single quotes are doubled; backslash is literal. UTF-8 supported. |
| Integer | -9223372036854775808 |
Signed int64, through 9223372036854775807. |
| Float | 1.5, -1.25e2 |
Finite floating-point value; include a decimal point or exponent. |
| Boolean | true, FALSE |
Case-insensitive literal. |
| Bytes | X'00ff' |
Hexadecimal pairs; hex letter case does not matter. |
Equality requires matching types; there is no implicit string/number or
integer/float conversion. Numeric range operators also require matching numeric
types. Missing columns do not match comparisons. String ranges are unsupported.
IS NOT NULL tests column presence; SMKV does not store null column values.
Missing projected columns are omitted from the result. Filters run before
projection, so a predicate can use a column that is not returned.
Execution limits
| Bound | Value |
|---|---|
| Total result LIMIT | Default 100; permitted 1–1000 |
| Returned rows per request | At most 100, possibly fewer or zero |
| SQL text | 4096 bytes |
| Tokens | 512 |
| Projected columns | 64 |
| AND predicates | 16 |
| Serialized parsed query | 1536 bytes |
There is no ordering guarantee, snapshot consistency, or secondary-index acceleration. Existing scan work/response limits, admission controls, and permissions apply. Reads and writes retain priority over scans. LIMIT restricts returned rows, not how many records may need examination over multiple pages. Each request does bounded work; continuation requires another explicit request.
CLI and web API
smkv-ctl --seed 127.0.0.1:7381 --timeout-ms 5000 \
query 'SELECT * FROM users LIMIT 10' --database customers
Pass --cursor to continue the same query. --watch is not supported. Output is
JSON regardless of the global display option. There is no dedicated SQL method
in the language SDKs yet.
The SMKV web service exposes GET /api/query?q=...; q is URL-encoded JSON:
{
"sql": "SELECT name FROM users LIMIT 10",
"database": "customers",
"cursor": null
}
sql and database are required; cursor may be omitted or null. This endpoint
belongs to the web service, not the database data or management port. It uses the
web token when configured, rejects cross-origin requests, and requires an
established cluster identity. Its request timeout is five seconds. Errors return
non-success HTTP statuses and text; successful responses use the same typed JSON
page format as the CLI. Malformed SQL returns HTTP 400.
Treat cursors as opaque continuation state. They are not credentials and do not
bypass authorization. Stop when cursor is null, even if limit_remaining is
nonzero. A topology or storage change may require restarting the query.