Granary_sql.AstSourceSQL abstract syntax tree.
The parser produces values of these types; the semantic analyser (Sema) and planner (Planner) consume them. Every type is exposed concretely because downstream modules pattern-match on the full structure β this module is a pure data surface with no hidden state.
Aggregate functions supported in Phase 2 Task 6.
type scalar_func = | Fn_length| Fn_lower| Fn_upper| Fn_abs| Fn_coalesce| Fn_ifnull| Fn_substrSUBSTR(s, start, len) β 1-indexed
| Fn_trim| Fn_ltrim| Fn_rtrimTRIM, LTRIM, RTRIM β optional 2nd arg for chars
*)| Fn_replaceREPLACE(s, old, new)
*)| Fn_instrINSTR(s, sub) β 1-indexed position or 0
*)| Fn_roundROUND(n, digits)
| Fn_typeofTYPEOF(x) β 'integer'|'real'|'text'|'blob'|'null'
*)| Fn_dateDATE(ts, mod...) β 'YYYY-MM-DD'
| Fn_timeTIME(ts, mod...) β 'HH:MM:SS'
| Fn_datetimeDATETIME(ts, mod...) β 'YYYY-MM-DD HH:MM:SS'
| Fn_strftimeSTRFTIME(fmt, ts, mod...) β formatted string
| Fn_juliandayJULIANDAY(ts, mod...) β float
| Fn_unixepochUNIXEPOCH(ts, mod...) β integer
| Fn_ceilCEIL(x) / CEILING(x) β round up
*)| Fn_floorFLOOR(x) β round down
*)| Fn_sqrtSQRT(x) β square root
*)| Fn_powPOW(x,y) / POWER(x,y) β x^y
*)| Fn_expEXP(x) β e^x
*)| Fn_lnLN(x) β natural log
*)| Fn_logLOG(x) β ln x; LOG(B,x) β log base B of x
*)| Fn_log2LOG2(x) β log base 2
*)| Fn_log10LOG10(x) β log base 10
*)| Fn_signSIGN(x) β -1 | 0 | 1 as integer
*)| Fn_truncTRUNC(x,d) β truncate toward zero
| Fn_piPI() β constant Ο, zero args
*)| Fn_sinSIN(x)
*)| Fn_cosCOS(x)
*)| Fn_tanTAN(x)
*)| Fn_asinASIN(x)
*)| Fn_acosACOS(x)
*)| Fn_atanATAN(x)
*)| Fn_atan2ATAN2(y,x) β two-argument arctangent
*)| Fn_degreesDEGREES(x) β radians to degrees
*)| Fn_radiansRADIANS(x) β degrees to radians
*)| Fn_json_extractjson_extract(json, path)
*)| Fn_json_objectjson_object(k,v,...)
*)| Fn_json_arrayjson_array(v,...)
*)| Fn_json_typejson_type(json,path)
| Fn_json_validjson_valid(json) β 0|1
*)| Fn_json_setjson_set(json, path, val, path, val ...)
| Fn_json_insertjson_insert β insert only if absent
*)| Fn_json_replacejson_replace β update only if present
*)| Fn_json_removejson_remove(json, path, path ...)
| Fn_hexHEX(x) β hex encoding of blob, text, or integer
*)| Fn_charCHAR(x,...) β Unicode code points to UTF-8 string
*)| Fn_unicodeUNICODE(s) β first Unicode code point of string, or NULL
*)| Fn_printfPRINTF(fmt,...) / FORMAT(fmt,...) β printf-style formatting
*)| Fn_zeroblobZEROBLOB(n) β blob of n zero bytes
*)| Fn_randomRANDOM() β random 64-bit integer
*)| Fn_randomblobRANDOMBLOB(n) β random blob of n bytes
*)| Fn_changesCHANGES() β rows affected by last DML
*)| Fn_last_insert_rowidLAST_INSERT_ROWID() β rowid of last INSERT
*)| Fn_total_changesTOTAL_CHANGES() β total rows affected since connection open
*)| Fn_sqlite_versionSQLITE_VERSION() β constant text version string
*)Scalar functions supported in Phase 5 Task 1.
type table_constraint = | TC_unique of string listUNIQUE(col1, col2, ...)
*)| TC_primary_key of {pk_cols : string list;PRIMARY KEY(col1, col2, ...)
*)autoincrement : bool;#312: AUTOINCREMENT appeared on a column inside the table-level PRIMARY KEY(...). Only legal on a single-column INTEGER PK (validated in Granary_sql.Sema); composite is rejected.
}| TC_foreign_key of {local_cols : string list;parent_table : string;parent_cols : string list;on_delete : fk_action;on_update : fk_action;deferrable : bool;}FOREIGN KEY(local_cols) REFERENCES parent_table(parent_cols) ON DELETE/UPDATE action
*)Maintenance mode for a CREATE REACTIVE VIEW (#427). Refresh_auto is the absence of a REFRESH clause β the classifier picks delta or full at CREATE time. Refresh_full/Refresh_delta force the mode; forcing delta on an unmaintainable SELECT shape is a compile error.
type expr = | E_lit of literal| E_col of stringunqualified column reference
*)| E_tbl_col of string * stringqualified: table.col
*)| E_binop of binop * expr * expr| E_not of expr| E_is_null of expr| E_is_not_null of expr| E_neg of exprunary minus
*)| E_bitnot of exprbitwise NOT ~
*)| E_between of expr * expr * exprsubject BETWEEN lo AND hi
*)| E_in of expr * expr listsubject IN (val1, val2, ...)
*)| E_agg of agg_func * expr optionAggregate call; None argument means COUNT( * ).
| E_func of scalar_func * expr listScalar function call.
*)| E_param of paramparameter: ?, ?1, :name, @name, $name
*)| E_match of string * stringE_match (table_name, query_string): WHERE table MATCH 'query'
| E_subquery of stmtscalar subquery: (SELECT ...) in expr position
*)| E_exists of stmtEXISTS (SELECT ...)
*)| E_in_select of expr * stmtx IN (SELECT ...)
*)| E_case of {scrutinee : expr option;None = searched form, Some = simple form
*)branches : (expr * expr) list;(WHEN condition/value, THEN result)
*)else_ : expr option;}| E_cast of expr * tyCAST(expr AS type) β SQLite type coercion
*)| E_window of {func : window_func;args : expr list;window : window_spec;}Window function call: FUNC(...) OVER (PARTITION BY ... ORDER BY ...)
*)| E_collate of expr * collationexpr COLLATE collation_name
*)| E_fts_snippet of {}snippet(table, col_idx, start_tag, end_tag, ellipsis, n_tokens)
*)Expressions, statements, and column_def are mutually recursive because column_def.check embeds an expr, and subquery expressions embed a stmt.
and window_spec = {partition_by : expr list;order_by : order_key list;frame : frame_spec option;}(column_name, qualifier): qualified names like table.col become ("col", Some "table"); bare names become ("col", None).
and stmt = | S_create_table of {name : string;columns : column_def list;constraints : table_constraint list;if_not_exists : bool;without_rowid : bool;WITHOUT ROWID table option (phase 37 / #122). Requires a single-column INTEGER PRIMARY KEY; the PK column's value is used directly as the row's storage key β no auto-rowid.
using_columnstore : bool;}| S_insert of {table : string;columns : string list;named columns; empty = "all in order"
*)values : expr list list;one inner list per VALUES row
*)on_conflict : conflict_action option;returning : expr list;empty = no RETURNING
*)upsert_update : upsert_update option;}| S_insert_select of {table : string;columns : string list;empty = all non-generated columns
*)on_conflict : conflict_action option;select : stmt;}| S_select of {distinct : bool;proj : [ `All | `Cols of string list | `Exprs of (expr * string option) list ];`Exprs supports arbitrary projection expressions (used for aggregates). Plain column projection still parses to `Cols.
table : string;table_alias : string option;optional AS alias for the FROM table
*)joins : join_clause list;empty list = no joins
*)where : expr option;group_by : group_by_item list;column names; empty = no GROUP BY
*)having : expr option;HAVING predicate (may reference aggregates)
*)order : order_key list;empty = no ORDER BY
*)limit : int option;offset : int option;}| S_create_index of {name : string;table : string;columns : expr list;where_clause : expr option;unique : bool;if_not_exists : bool;}| S_update of {table : string;assignments : (string * expr) list;(col_name, new_value_expr)
where : expr option;order : order_key list;limit : int option;offset : int option;returning : expr list;}| S_delete of {table : string;where : expr option;order : order_key list;limit : int option;offset : int option;returning : expr list;}| S_drop_table of {}| S_drop_index of {}| S_alter_table of {table : string;action : alter_action;}| S_begin| S_commit| S_rollback| S_savepoint of stringSAVEPOINT name
*)| S_release of stringRELEASE name
*)| S_rollback_to of stringROLLBACK TO name
*)| S_compound of {op : set_op;left : stmt;right : stmt;order : order_key list;ORDER BY applied to the combined result; empty if absent. Parser lifts a trailing ORDER BY from the right arm so it binds at the compound level (SQL semantics).
*)limit : int option;offset : int option;}| S_create_fts_table of {}| S_pragma of pragma_kind| S_const_select of {exprs : (expr * string option) list;}FROM-less SELECT that evaluates constant expressions β returns one row. Used when a SELECT has no FROM clause. Each entry pairs the expression with an optional column alias.
*)| S_with_cte of {}| S_create_view of {name : string;query : stmt;}| S_create_reactive_view of {name : string;query : stmt;refresh : refresh_mode;}CREATE REACTIVE VIEW name AS query [REFRESH FULL|DELTA] (#427). A declaratively maintained view over the IVM engine. refresh records the user's explicit clause; Refresh_auto leaves the maintenance mode to the classifier at CREATE time.
| S_drop_view of {}| S_create_trigger of {name : string;timing : trigger_timing;event : trigger_event;table : string;when_ : expr option;WHEN clause; None if absent
*)body : stmt list;statements between BEGINβ¦END
*)}| S_drop_trigger of {}| S_explain of {analyze : bool;false = EXPLAIN; true = EXPLAIN ANALYZE
*)stmt : stmt;}| S_vacuumCompact-rebuild the database file in place (phase 37 / #120). Executed by Db.vacuum; surfaces a sema error if invoked on a non-file-backed database.
| S_attach of {path : string;filesystem path to the database file
*)schema : string;schema name under which to register
*)}ATTACH DATABASE 'path' AS schema β phase 40 / #64. Opens a sub-handle and registers it under schema for subsequent statements addressed via PRAGMA active_database = schema.
| S_detach of {}DETACH DATABASE schema β phase 40 / #64. Closes and removes a previously attached sub-handle.
and pragma_kind = | Pragma_table_info of string| Pragma_index_list of string| Pragma_foreign_key_list of string| Pragma_foreign_keys| Pragma_foreign_keys_set of bool| Pragma_recursive_triggers| Pragma_recursive_triggers_set of bool| Pragma_defer_foreign_keys| Pragma_defer_foreign_keys_set of bool| Pragma_user_version| Pragma_user_version_set of int64| Pragma_journal_mode| Pragma_integrity_check| Pragma_wal_checkpoint| Pragma_wal_autocheckpoint| Pragma_wal_autocheckpoint_set of int64| Pragma_synchronous| Pragma_synchronous_set of string| Pragma_wal_batch_commits| Pragma_wal_batch_commits_set of int64| Pragma_wal_batch_interval_ms| Pragma_wal_batch_interval_ms_set of int64| Pragma_database_list| Pragma_active_database| Pragma_active_database_set of string| Pragma_set of string * stringand column_def = {name : string;ty : ty;not_null : bool;primary_key : bool;autoincrement : bool;AUTOINCREMENT on a column PRIMARY KEY (#299). Only ever true for a single-column ascending INTEGER PRIMARY KEY on a rowid table; the placement is validated in Granary_sql.Sema.
pk_desc : bool;#312: PRIMARY KEY DESC on this column. SQLite treats an INTEGER PRIMARY KEY DESC as a NON-alias (hidden rowid + real index), not the rowid alias. Only meaningful when primary_key is set.
default : literal option;check : expr option;fk_ref : (string * string * fk_action * fk_action * bool) option;(parent_table, parent_col, on_delete, on_update, deferrable). None = no FK.
generated_as : (expr * [ `Stored | `Virtual ]) option;GENERATED ALWAYS AS (expr) STORED | VIRTUAL. None = not generated.
}and alter_action = | AA_add_column of column_def| AA_rename_table of string| AA_rename_column of string * string| AA_drop_column of stringcolumn name to drop
*)Render a binary operator as its SQL token (e.g. Eq β "=").
Render a scalar function as its SQL keyword (e.g. Fn_length β "LENGTH").