Skip to content

SQL reference ​

smaltdb speaks a dialect of SQLite's SQL. Most SQLite statements and expressions work unchanged; the differences are listed on each statement's page and collected in Differences from SQLite.

This page covers the lexical structure: how the text of a statement is split into literals, identifiers, keywords, parameters and comments. The statements are listed at the end.

Statements and scripts ​

A script is a list of statements separated by ;. Empty statements (;;) are skipped, and the last statement does not need a ;. Each statement runs on its own: in autocommit mode every statement is its own transaction (see Transactions).

sql
CREATE TABLE notes(id INTEGER PRIMARY KEY, body TEXT);
INSERT INTO notes(body) VALUES ('first');;
SELECT * FROM notes
idbody
1first

A syntax error reports SQLite's message plus the position, for example near "FORM": syntax error (line 1, column 10), with the error code SMALT_SYNTAX.

sql
SELECT * FORM notes

Comments ​

FormEnds at
-- textthe end of the line
/* text */the closing */, or the end of the input when there is none

Block comments do not nest.

sql
SELECT 1 /* inline */ + 1 AS two -- trailing comment
two
2

Literals ​

LiteralExamplesValue
Integer42, -7, 0x1FINTEGER
Real1.5, .5, 1e3, 2.5E-3REAL
String'text', 'it''s'TEXT; a quote inside is written twice
Blobx'CAFE', X'00ff'BLOB; an even number of hex digits
NULLNULLNULL
TRUE, FALSETRUEthe integers 1 and 0
CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMPthe current UTC date and time as text (see date and time functions)
sql
SELECT 42 AS i, 0x1F AS hex, 1e3 AS r, 'it''s' AS s, x'CAFE' AS b, TRUE AS t, typeof(1.0) AS ty
ihexrsbtty
42311000it'sx'cafe'1real

Integers are 64-bit. A decimal integer literal outside the 64-bit range becomes a REAL, as in SQLite. A hexadecimal literal is read as a 64-bit two's complement number, so 0xFFFFFFFFFFFFFFFF is -1; one larger than 64 bits is a syntax error (hex literal too big).

sql
SELECT 0xFFFFFFFFFFFFFFFF AS hex, typeof(9223372036854775807) AS max_int, typeof(9223372036854775808) AS beyond
hexmax_intbeyond
-1integerreal

Integers beyond ±(253−1) reach JavaScript as bigint; see Data types.

Digit separators (1_000) are not supported. Double-quoted text is an identifier, never a string: SQLite's fallback that treats an unknown "name" as a string literal does not exist in smaltdb.

sql
SELECT "hello"

The message is no such column: "hello" - should this be a string literal in single-quotes?.

Identifiers ​

An identifier names a table, column, index, view or other object.

FormExample
Plainorders, _tmp, total$2 (letters, digits, _, $; not starting with a digit; any non-ASCII character counts as a letter)
Double quotes"order items", "say ""hi""" (a quote inside is written twice)
Square brackets[order items]
Backticks`order items`

Names are matched without regard to ASCII case, as in SQLite: Orders, ORDERS and "orders" are the same table. The spelling used in CREATE is kept for display.

sql
CREATE TABLE "Order Items"(qty INTEGER);
INSERT INTO [order items] VALUES (3);
SELECT `QTY` FROM "ORDER ITEMS"
QTY
3

Names that start with smalt_ or sqlite_ are reserved for the engine; creating such an object fails with object name reserved for internal use.

Keywords ​

These keywords are reserved: to use one as a name, quote it ("order" works, order does not).

ADD ALL ALTER AND AS AUTOINCREMENT BETWEEN CASE CAST CHECK COLLATE COMMIT CONSTRAINT CREATE CROSS CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP DEFAULT DEFERRABLE DELETE DISTINCT DROP ELSE ESCAPE EXCEPT EXISTS FALSE FOREIGN FROM FULL GLOB GROUP HAVING IN INDEX INDEXED INNER INSERT INTERSECT INTO IS ISNULL JOIN LEFT LIKE LIMIT NATURAL NOT NOTNULL NULL ON OR ORDER OUTER PRIMARY REFERENCES RETURNING RIGHT SELECT SET TABLE THEN TO TRANSACTION TRUE UNION UNIQUE UPDATE USING VALUES WHEN WHERE

All other keywords (ACTION, BEGIN, KEY, REPLACE, TEMP, VIEW, WITH, …) can be used as plain names where the grammar is not ambiguous, as in SQLite. CONNECTION, EXTERNAL and CHANGED are not keywords at all; they only have meaning in external table and REFRESH statements.

sql
CREATE TABLE order(id INTEGER)
sql
CREATE TABLE "order"(id INTEGER, key TEXT, action TEXT);
SELECT name FROM pragma_table_info('order')
name
id
key
action

Parameters ​

A statement can contain parameters, whose values are bound when it runs (see Queries).

FormSlot
?the next slot (one more than the highest so far)
?NNNslot NNN, from 1 to 32766
:name, @name, $namea slot assigned on first use; the same name reuses it

Values are bound from an array, by slot, or from an object whose keys are the names without the prefix ({ name: 1 } binds :name, @name and $name). An array must have exactly as many values as the highest slot, otherwise the statement fails with SMALT_RANGE (statement expects 2 parameter(s), got 3). With an object, every named parameter needs a key (missing value for parameter :name); extra keys are ignored.

ts
const rows = await db.query('SELECT ? + ?2 AS a, :x AS b', [1, 2, 'third']);
const same = await db.query('SELECT :x AS x, @x AS again', { x: 5 });

Column names in results ​

A result column is named by its alias (AS name, or an alias without AS). Without one, a column reference gets the column's name and any other expression gets its source text exactly as written, as in SQLite.

sql
SELECT 1+1, 1 + 1 AS two, upper('a')
1+1twoupper('a')
22A

Statements ​

StatementPage
SELECT, VALUES, WITHSELECT
INSERT, REPLACEINSERT
UPDATEUPDATE
DELETEDELETE
CREATE [TEMP] TABLECREATE TABLE
ALTER TABLEALTER TABLE
DROP TABLE, DROP INDEX, DROP VIEW, DROP MATERIALIZED VIEW, DROP EXTERNAL TABLE, DROP CONNECTIONDROP
CREATE [UNIQUE] INDEXCREATE INDEX
CREATE VIEW, CREATE MATERIALIZED VIEW, REFRESH MATERIALIZED VIEWViews
CREATE CONNECTION, CREATE EXTERNAL TABLEExternal tables
BEGIN, COMMIT, END, ROLLBACK, SAVEPOINT, RELEASETransactions
EXPLAIN, EXPLAIN QUERY PLAN, EXPLAIN ANALYZE, ANALYZEEXPLAIN and ANALYZE
PRAGMAPRAGMA

Expressions, operators and CAST are described in Expressions, and values and column types in Data types. The catalog views are in information_schema, and the functions in the function reference.

Not supported ​

These statements are rejected:

StatementResult
CREATE TRIGGERsyntax error (SMALT_SYNTAX)
DROP TRIGGERSMALT_UNSUPPORTED
ATTACH, DETACHsyntax error
REINDEXsyntax error
VACUUMparsed, then SMALT_UNSUPPORTED
CREATE VIRTUAL TABLEsyntax error
sql
VACUUM

MIT License