PizzaSQL ships a fixed set of built-in functions. There are no user-defined functions, no CREATE FUNCTION, and no extension mechanism.
A few functions are declared in the engine’s function catalog (so they parse without an “unknown function” error) but are not implemented in the executor — they return NULL. Those are listed separately so you don’t mistake their presence in autocomplete for real behaviour.
Used in SELECT with or without GROUP BY, and in HAVING.
| Function |
Description |
COUNT(*) |
number of rows |
COUNT(expr) |
number of non-NULL values |
COUNT(DISTINCT expr) |
number of distinct non-NULL values |
SUM(expr) |
sum; integer result when all inputs are integers, otherwise real; NULL when no values |
SUM(DISTINCT expr) |
distinct sum |
AVG(expr) |
average (real); NULL when no values |
MIN(expr) |
minimum, ignoring NULLs |
MAX(expr) |
maximum, ignoring NULLs |
- Aggregates may be nested inside expressions:
SELECT sum(x) / count(x) FROM t.
- On an empty input set,
COUNT returns 0; SUM, AVG, MIN, MAX return NULL.
MIN/MAX also work as scalar functions over multiple arguments: MIN(a, b, c).
TOTAL and GROUP_CONCAT are declared in the catalog but not implemented — do not rely on them.
| Function |
Description |
upper(s) |
uppercase |
lower(s) |
lowercase |
length(s) |
character length |
substr(s, start[, len]) / substring(...) |
1-indexed substring |
trim(s) |
trims whitespace |
replace(s, find, repl) |
replace all occurrences |
instr(s, sub) |
1-indexed position of sub, or 0 |
printf(format, ...) |
fmt.Sprintf-style formatting |
concat(a, b, ...) |
concatenate all arguments as text |
| Function |
Description |
abs(x) |
absolute value |
round(x[, n]) |
round to n decimals (naive implementation; see caveats) |
min(a, b, ...) |
scalar minimum |
max(a, b, ...) |
scalar maximum |
random() |
random 64-bit integer |
| Function |
Description |
coalesce(a, b, ...) |
first non-NULL argument |
ifnull(a, b) |
b when a is NULL, else a |
nullif(a, b) |
NULL when a equals b, else a |
| Function |
Description |
typeof(x) |
"null", "integer", "real", "text", or "blob" |
| Function |
Description |
hex(x) |
uppercase hex of the value’s bytes |
unhex(x) |
decode hex to a string |
zeroblob(n) |
a string of n NUL bytes (capped at 1 MiB) |
| Function |
Description |
date(...) |
YYYY-MM-DD |
time(...) |
HH:MM:SS |
datetime(...) |
YYYY-MM-DD HH:MM:SS |
julianday(...) |
Julian day number |
unixepoch(...) |
Unix seconds (or fractional with subsec) |
strftime(format, ...) |
formatted time |
timediff(a, b) |
±YYYY-MM-DD HH:MM:SS.SSS from b to a |
Date/time functions accept SQLite-style time values and modifiers:
- Time values:
'now', ISO-8601 text (e.g. '2026-01-02 03:04:05'), or a numeric Julian day (optionally followed by unixepoch, julianday, or auto).
- Modifiers:
NNN days|hours|minutes|seconds|months|years, start of day|month|year, weekday N, utc, localtime, subsec/subsecond, and ±YYYY-MM-DD HH:MM:SS.SSS.
- Unknown modifiers are silently ignored rather than erroring.
| Function |
Description |
pizzasql_version() |
engine build version |
sqlite_version() |
same value, for SQLite compatibility |
These names are recognized by the parser/analyzer but return NULL when called. Treat them as unsupported:
ltrim, rtrim
ceil, floor
mod
iif
quote
total, group_concat
last_insert_rowid, changes, total_changes
randomblob is implemented in the executor but not registered with the analyzer, so calls are currently rejected as an unknown function.
The last_insert_rowid gap matters in practice: after an INSERT with an auto-generated key, there is no built-in function to retrieve the generated id. If you need it, insert an explicit value instead of relying on auto-generation.
round uses int64(v*mult + 0.5) and only behaves correctly for non-negative decimal counts; treat it as approximate for edge cases.
random() is not cryptographically secure — do not use it for secrets.
zeroblob is capped at 1 MiB regardless of the requested size.
printf uses Go’s fmt.Sprintf, whose format verbs differ from SQLite’s printf in places.