Statements
This page lists each statement family with its exact grammar, behaviour, and caveats. For expression details (operators, CASE, IN, subqueries) see Expressions & operators.
SELECT
Section titled “SELECT”SELECT [DISTINCT] column [AS alias], ...FROM table [[AS] alias] [JOIN ...]WHERE conditionGROUP BY expr, ...HAVING conditionORDER BY expr [ASC|DESC], ...LIMIT n [OFFSET m];SELECTwithoutFROMevaluates an expression (SELECT 1 + 2,SELECT upper('hi')).DISTINCTde-duplicates the result row set.ORDER BYaccepts expressions, column aliases, and 1-based ordinal positions (ORDER BY 2).LIMIT/OFFSETaccept numeric expressions.- Set operations:
UNION,UNION ALL,INTERSECT, andEXCEPTare supported with standard precedence (INTERSECTbinds tighter thanUNION/EXCEPT). A compound query’sORDER BY/LIMIT/OFFSETapply to the combined result. - Subqueries are supported in
FROM(derived tables require an alias), as scalar expressions, inIN (SELECT ...), and inEXISTS (SELECT ...), including correlated subqueries.
FROM a JOIN b ON a.id = b.a_idFROM a INNER JOIN b ON ...FROM a LEFT [OUTER] JOIN b ON ...FROM a CROSS JOIN bFROM a, b -- implicit cross join, filtered by WHEREINNER,LEFT, andCROSSjoins are fully executed.LEFT JOINproduces a NULL-padded row for unmatched left rows.- Equality joins (
ON a.x = b.y) use a hash join; non-equalityONconditions fall back to a nested loop. RIGHT [OUTER] JOINandFULL [OUTER] JOINparse but are not executed — they return an empty result. Rewrite withLEFT JOIN.NATURAL JOINandUSING (cols)parse but their join condition is ignored, effectively becoming a cross join. Always use an explicitON.
INSERT
Section titled “INSERT”INSERT INTO table [(col, ...)] VALUES (expr, ...), (expr, ...);INSERT INTO table [(col, ...)] SELECT ...;INSERT OR REPLACE INTO table ...;INSERT OR IGNORE INTO table ...;INSERT OR FAIL INTO table ...;INSERT OR ABORT INTO table ...;INSERT INTO table ... ON CONFLICT [(pk)] DO NOTHING;INSERT INTO table ... ON CONFLICT [(pk)] DO UPDATE SET col = expr, ...;- Omitting the column list targets all columns in declaration order.
INSERT ... SELECTbulk-inserts the materialized result.- Conflict handling is driven by the primary key only:
INSERT OR IGNOREsilently skips duplicate-PK rows.INSERT OR REPLACEdeletes the conflicting row and inserts the new one.INSERT OR FAIL/OR ABORTabort on the first duplicate.ON CONFLICT (target) DO NOTHING/DO UPDATE SET ...work only when the conflict is on the primary key; the(target)list must name the PK column (or be omitted).
- Auto-generated integer primary keys (and the implicit rowid) are assigned when no PK value is supplied. There is no
RETURNINGand no way to read back the generated id in the same statement; useSELECT last_insert_rowid()-style patterns with caution (see Functions — the rowid functions are not implemented).
UPDATE and DELETE
Section titled “UPDATE and DELETE”UPDATE table SET col = expr, ... WHERE condition;DELETE FROM table WHERE condition;- Both evaluate the
WHEREcondition per row.UPDATEevaluatesSETexpressions against the row’s current values, soSET balance = balance + 100works. - Omitting
WHEREaffects every row. - No
RETURNING, noORDER BY/LIMITonUPDATE/DELETE.
CREATE TABLE
Section titled “CREATE TABLE”CREATE TABLE [IF NOT EXISTS] table ( column TYPE [PRIMARY KEY] [NOT NULL] [DEFAULT expr] [AUTOINCREMENT], ..., [PRIMARY KEY (col, ...)], [UNIQUE (col, ...)], [CHECK (expr)], [FOREIGN KEY (col) REFERENCES other (col)]);IF NOT EXISTSsilently succeeds if the table already exists.- Only
PRIMARY KEY,NOT NULL, andDEFAULThave an effect.AUTOINCREMENTis accepted but adds no behavior;UNIQUE,CHECK, andFOREIGN KEYare parsed and discarded — see Constraints. - A table-level
PRIMARY KEY (a, b)uses the first named column as the primary key; composite keys are not truly supported. DEFAULT expris evaluated when the table is created, so it must be a constant expression.AUTOINCREMENTis accepted but has no extra behaviour over a plainINTEGER PRIMARY KEY.
ALTER TABLE
Section titled “ALTER TABLE”ALTER TABLE table ADD COLUMN column TYPE [constraints];ALTER TABLE table DROP COLUMN column;ALTER TABLE table RENAME TO new_name;ALTER TABLE table RENAME COLUMN old TO new;ADD COLUMNappends a nullable column;ADD COLUMN IF NOT EXISTS column ...is also accepted.- You cannot drop the primary-key column.
- Renaming is schema-only; index definitions referencing renamed columns are not updated automatically.
CREATE / DROP INDEX and VIEW
Section titled “CREATE / DROP INDEX and VIEW”CREATE [UNIQUE] INDEX [IF NOT EXISTS] name ON table (col [ASC|DESC], ...);DROP INDEX [IF EXISTS] name;
CREATE VIEW [IF NOT EXISTS] view AS SELECT ...;DROP VIEW [IF EXISTS] view;- Index definitions persist, but index entries are rebuilt in memory and only used for single-column equality lookups — see Indexes.
UNIQUEindexes are recorded as unique in the catalog but uniqueness is not enforced.- Views are connection-local and in-memory: they exist only within the connection that created them and are not persisted or shared. See Catalog & schema.
Transactions
Section titled “Transactions”BEGIN [TRANSACTION];COMMIT;ROLLBACK;SAVEPOINT name;RELEASE name;ROLLBACK TO name;- Transactions use an undo log with a database-wide lock — not MVCC. See Transactions.
SAVEPOINToutside a transaction implicitly starts one.- On the managed HTTP endpoint, transaction statements are rejected with
501. Over the PostgreSQL wire proxy, transactions are forwarded and work normally.
PRAGMA and EXPLAIN
Section titled “PRAGMA and EXPLAIN”PRAGMA table_info(t); -- column list for table tPRAGMA table_list; -- all tablesPRAGMA database_list; -- attached databasesPRAGMA version; -- engine version
EXPLAIN stmt; -- simplified opcode listingEXPLAIN QUERY PLAN stmt; -- SCAN/FILTER/SORT/LIMIT description- Only the four
PRAGMAforms above are implemented; any other pragma name errors. EXPLAINoutput is illustrative only — it does not reflect the real execution engine (there is no cost-based planner; see Query lifecycle).
ATTACH / DETACH DATABASE
Section titled “ATTACH / DETACH DATABASE”ATTACH DATABASE 'name' AS alias;DETACH DATABASE alias;ATTACHregisters another database namespace (each database is a key prefix in PizzaKV) under an alias. Aliasesmain,temp, andtemporaryare reserved.DETACHcannot detachmain. Detaching does not drop the underlying database data.
Not supported
Section titled “Not supported”These are rejected at parse time: WITH (CTEs), window functions, RETURNING, WITHOUT ROWID, TRUNCATE, UPSERT (beyond the OR/ON CONFLICT forms), triggers, and CREATE SCHEMA/roles.