Appearance
SQL reference
This page lists the SQL that kinedb runs today. Every example in a plain sql block ran on the current build, in the order of this page, in one database. So a later example can use a table that an earlier example created. A -- expect: comment shows a part of the output.
The examples use the embedded mode of the binary, which starts no server:
sh
kinedb --data-dir ./data -e "SHOW TABLES"Some statements need a running server (kinedb --connect host:port, POST /sql, or a client library). The text before such an example says so. The embedded mode refuses them with requires a running server.
Data types
INT: a 64-bit signed integer.FLOAT: a 64-bit floating-point number (IEEE 754).BOOL:trueorfalse.TEXT: a UTF-8 string.BLOB: any bytes.TIMESTAMP: microseconds since the Unix epoch.VECTOR: a list of numbers.
sql
-- expect: OK
CREATE TABLE demo (
id INT,
amount FLOAT,
is_active BOOL,
name TEXT,
data BLOB,
ts TIMESTAMP,
embedding VECTOR,
PRIMARY KEY (id)
);Tables
A table has typed columns and a primary key.
sql
-- expect: OK
CREATE TABLE accounts (
account_id INT,
owner TEXT,
balance FLOAT,
created_at TIMESTAMP,
PRIMARY KEY (account_id)
);List the tables, and show the columns of one table:
sql
-- expect: 2 rows
SHOW TABLES;
-- expect: account_id
DESCRIBE accounts;
-- expect: account_id
SHOW COLUMNS FROM accounts;Drop a table and its data:
sql
CREATE TABLE temp_table (id INT, PRIMARY KEY (id));
DROP TABLE temp_table;INSERT
Insert one row, or several rows in one statement:
sql
INSERT INTO accounts (account_id, owner, balance, created_at)
VALUES (1, 'Alice', 1000.0, 1000000);
INSERT INTO accounts (account_id, owner, balance, created_at)
VALUES
(2, 'Bob', 2000.0, 2000000),
(3, 'Charlie', 3000.0, 3000000),
(4, 'Diana', 4000.0, 4000000);
-- expect: 4
SELECT COUNT(*) FROM accounts;SELECT
sql
-- expect: Alice
SELECT * FROM accounts WHERE account_id = 1;
-- expect: Bob
SELECT owner, balance FROM accounts WHERE owner = 'Bob';WHERE
The comparison operators are =, !=, <, <=, > and >=. AND, OR, NOT and parentheses combine conditions.
sql
-- expect: 1 rows
SELECT * FROM accounts WHERE balance > 2000.0 AND owner != 'Diana';
-- expect: 3 rows
SELECT owner FROM accounts WHERE NOT account_id = 1;
-- expect: Bob
SELECT owner FROM accounts WHERE (account_id = 1 OR account_id = 2) AND balance > 1500.0;IN, BETWEEN, LIKE, ILIKE (not case-sensitive) and IS NULL:
sql
-- expect: 2 rows
SELECT owner FROM accounts WHERE account_id IN (1, 2);
-- expect: 2 rows
SELECT owner FROM accounts WHERE balance BETWEEN 1000.0 AND 2000.0;
-- expect: Alice
SELECT owner FROM accounts WHERE owner LIKE 'Al%';
-- expect: Alice
SELECT owner FROM accounts WHERE owner ILIKE 'al%';
-- expect: 0 rows
SELECT owner FROM accounts WHERE owner IS NULL;ORDER BY, LIMIT and OFFSET
ORDER BY sorts by one or more columns, ASC (the default) or DESC. OFFSET comes after LIMIT.
sql
-- expect: Diana
SELECT owner FROM accounts ORDER BY balance DESC LIMIT 1;
-- expect: 2 rows
SELECT * FROM accounts LIMIT 2;
-- expect: Charlie
SELECT owner FROM accounts ORDER BY account_id LIMIT 1 OFFSET 2;Aggregates
COUNT(*), SUM, AVG, MIN and MAX:
sql
-- expect: 4
SELECT COUNT(*) FROM accounts;
-- expect: 10000
SELECT SUM(balance) FROM accounts;
-- expect: 2500
SELECT AVG(balance) FROM accounts;
-- expect: 1000
SELECT MIN(balance) FROM accounts;
-- expect: 4000
SELECT MAX(balance) FROM accounts;GROUP BY and HAVING
sql
CREATE TABLE orders (
order_id INT,
account_id INT,
amount FLOAT,
PRIMARY KEY (order_id)
);
INSERT INTO orders (order_id, account_id, amount)
VALUES
(101, 1, 100.0),
(102, 1, 200.0),
(103, 2, 150.0),
(104, 3, 300.0),
(105, 3, 250.0);
-- expect: 3 rows
SELECT account_id, COUNT(*) as order_count, SUM(amount) as total
FROM orders
GROUP BY account_id;
-- expect: 2 rows
SELECT account_id, SUM(amount) as total
FROM orders
GROUP BY account_id
HAVING SUM(amount) > 150.0;JOIN
JOIN (inner), LEFT JOIN and RIGHT JOIN join two tables on a condition.
sql
-- expect: Alice
SELECT accounts.owner, orders.order_id
FROM accounts
JOIN orders ON accounts.account_id = orders.account_id
WHERE accounts.account_id = 1;
-- expect: 6 rows
SELECT accounts.owner, orders.order_id
FROM accounts
LEFT JOIN orders ON accounts.account_id = orders.account_id;
-- expect: 5 rows
SELECT accounts.owner, orders.order_id
FROM accounts
RIGHT JOIN orders ON accounts.account_id = orders.account_id;UPDATE
sql
UPDATE accounts SET balance = 1500.0 WHERE account_id = 1;
UPDATE accounts SET balance = balance + 100.0;
-- expect: 1600
SELECT balance FROM accounts WHERE account_id = 1;An UPDATE without WHERE changes every row.
DELETE
sql
DELETE FROM accounts WHERE account_id = 4;
-- expect: 3
SELECT COUNT(*) FROM accounts;Document collections
A document collection holds JSON documents. Each document has a key, _id.
sql
-- expect: OK
CREATE COLLECTION documents TYPE DOCUMENT;INSERT without an _id makes one. PUT '<id>' {...} writes the document at that key, and it replaces a document that is there. GET reads one document by its key.
sql
-- expect: OK
INSERT INTO documents {"name": "Alice", "age": 30};
-- expect: 1 rows
SELECT * FROM documents;
-- expect: OK
PUT 'doc1' {"name": "Bob", "title": "Engineer"} INTO documents;
-- expect: doc1
GET 'doc1' FROM documents;A WHERE reads nested fields with dots. On an array field, = is true when one element of the array is equal to the value.
sql
-- expect: OK
INSERT INTO documents {"_id": "doc2", "name": "Carol", "address": {"city": "Oslo"}, "tags": ["red", "blue"]};
-- expect: Carol
SELECT name FROM documents WHERE address.city = 'Oslo';
-- expect: Carol
SELECT name FROM documents WHERE tags = 'red';UPDATE and DELETE work on documents with any WHERE:
sql
UPDATE documents SET age = 31 WHERE name = 'Alice';
-- expect: 31
SELECT age FROM documents WHERE name = 'Alice';
DELETE FROM documents WHERE _id = 'doc2';
-- expect: 2
SELECT COUNT(*) FROM documents;Key-value collections
A key-value collection holds one value per key.
sql
-- expect: OK
CREATE COLLECTION cache TYPE KV;
-- expect: OK
PUT 'key1' 1000 INTO cache;
-- expect: OK
PUT 'key2' 2000 INTO cache;
-- expect: key1
GET 'key1' FROM cache;
-- expect: OK
DELETE 'key1' FROM cache;Indexes
A secondary index speeds up a WHERE on its column. DESCRIBE SELECT shows the plan of a query.
sql
CREATE INDEX idx_owner ON accounts (owner);
-- expect: 1 rows
SHOW INDEXES;
-- expect: 1 rows
SHOW INDEXES FROM accounts;
-- expect: index scan
DESCRIBE SELECT * FROM accounts WHERE owner = 'Alice';
DROP INDEX idx_owner;Transactions
BEGIN and COMMIT group statements.
sql
BEGIN;
INSERT INTO accounts (account_id, owner, balance, created_at)
VALUES (5, 'Eve', 500.0, 5000000);
COMMIT;
-- expect: 4
SELECT COUNT(*) FROM accounts;A COMMIT can carry an idempotency token. A client that lost its connection asks GET TRANSACTION STATUS whether the commit happened, and it retries only when it did not.
sql
BEGIN;
INSERT INTO accounts (account_id, owner, balance, created_at)
VALUES (6, 'Frank', 600.0, 6000000);
COMMIT WITH TOKEN 'token-unique-001';
-- expect: OK
GET TRANSACTION STATUS 'token-unique-001';TRANSFER moves an amount from one row to another in one atomic step. It needs a server connection:
sql
TRANSFER 10 OF balance ON accounts FROM 1 TO 2;Time travel and history
Every commit keeps the old data readable. AS OF reads a table at a commit (HEAD is the newest), and SHOW COMMITS lists the commits. SHOW COMMIT <hash> shows one commit.
sql
-- expect: 5
SELECT COUNT(*) FROM accounts AS OF HEAD;
-- expect: hash
SHOW COMMITS;Branches
A branch is a named root of the whole database. It costs no copy.
sql
-- expect: OK
CREATE BRANCH dev_branch;
-- expect: 2 rows
SHOW BRANCHES;
-- expect: OK
USE BRANCH dev_branch;
-- expect: OK
USE BRANCH main;
-- expect: OK
DROP BRANCH dev_branch;WATCH: live queries
WATCH <table> [FAST] [VERBOSE] [WHERE <column> <operator> <value>] streams the changes of a table to the client, over the WebSocket of a server connection, until UNWATCH. The embedded mode answers OK, but it has no connection to stream on.
sql
WATCH accounts WHERE balance > 100;
UNWATCH accounts;Databases
A database holds its own tables and collections.
sql
-- expect: OK
CREATE DATABASE mydb;
-- expect: 2 rows
SHOW DATABASES;
DROP DATABASE mydb;USE <database> switches the database of a session. It needs a server connection:
sql
USE mydb;Functions and tickers
A function is a script in kd, the scripting language of kinedb. Its parameters are variables in the body, and return gives the result. Functions and tickers need a server.
sql
CREATE FUNCTION add_one(x) RETURNS VALUE LANGUAGE kd AS $$ return x + 1; $$;
CALL add_one(41);
SHOW FUNCTIONS;
DROP FUNCTION add_one;A ticker calls a function on a schedule. OVERLAP SKIP (the default) skips a run while the last run still works; OVERLAP WAIT waits for it.
sql
CREATE FUNCTION ping() RETURNS VALUE LANGUAGE kd AS $$ return 1; $$;
CREATE TICKER ping_every_minute EVERY 60s CALL ping OVERLAP SKIP;
SHOW TICKERS;
DROP TICKER ping_every_minute;Users, roles and permissions
These statements need a server.
sql
CREATE USER 'alice' PASSWORD 'secret123';
ALTER USER 'alice' SET PASSWORD 'newsecret';
ALTER USER 'alice' REVOKE SESSIONS;
DROP USER 'alice';A permission goes to a target: ANYONE, AUTHENTICATED, ROLE <name>, or MATCH <field> (a rule that matches the user against a field of the row). A WHERE limits the permission to the matching rows. A user gets permissions through roles.
sql
CREATE ROLE analysts;
GRANT ROLE analysts TO 'alice';
GRANT SELECT ON documents TO ROLE analysts;
GRANT SELECT ON documents TO ANYONE WHERE _type = 'public';
GRANT ALL ON orders TO ROLE analysts;
REVOKE SELECT ON documents FROM ROLE analysts;
REVOKE ROLE analysts FROM 'alice';
DROP ROLE analysts;ALTER COLLECTION <name> SET POLICY '<json array>' replaces the whole policy list of a collection:
sql
ALTER COLLECTION documents SET POLICY '[]';Settings and cluster operations
These statements are for operators, and most of them need a server.
sql
SHOW SETTINGS;
SET CLUSTER cluster.slow_query_threshold_ms = 100;
SHOW CLUSTER STATUS;
SHOW CLUSTER QUORUM;
SET CLUSTER QUORUM = 1;
SHOW NODES;
SHOW PEERS;
SHOW RAFTGROUPS;
SHOW RAFTGROUP 0;
SHOW SHARDS;
SHOW PLACEMENT;
SHOW TABLE STATS;
SHOW METRICS;
SHOW SLOW QUERIES;
SHOW MEMORY;
SHOW DISK STATUS;
SHOW SYNC STATUS;
SHOW S3 STATUS;
SHOW ROOTS;
SHOW LEAVES OF accounts LIMIT 100;
CLUSTER VERIFY;
SPLIT SHARD 0 OF accounts AT 'm';
MERGE SHARDS 0 1 OF accounts;
ALTER CLUSTER EVICT NODE 'abc123';
ALTER CLUSTER READMIT NODE 'abc123';
VACUUM;SHOW SETTINGSlists every setting with its value;SET CLUSTER <setting> = <value>changes a cluster setting on every node. See Run kinedb.SHOW NODES,SHOW PEERS,SHOW RAFTGROUPSandSHOW SHARDSshow the members, the Raft groups and the shards.CLUSTER VERIFYchecks that the replicas agree.SPLIT SHARDandMERGE SHARDSsplit and merge shards by hand. The cluster also splits a shard by itself when it grows.ALTER CLUSTER EVICT NODEremoves a node from the cluster, andREADMITlets it back.VACUUMreclaims the space of dead blocks.