package granary

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Module Granary_sql.AstSource

SQL 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.

Sourcetype ty =
  1. | Ty_int
    (*

    INTEGER column type

    *)
  2. | Ty_text
    (*

    TEXT column type

    *)
  3. | Ty_real
    (*

    REAL (float64) column type

    *)
  4. | Ty_blob
    (*

    BLOB (bytes) column type

    *)
Sourcetype literal =
  1. | L_int of int64
  2. | L_text of string
  3. | L_null
  4. | L_real of float
  5. | L_blob of bytes
  6. | L_current_timestamp
  7. | L_current_date
  8. | L_current_time
Sourcetype param =
  1. | Param_anon
    (*

    ? — assigned next slot in encounter order

    *)
  2. | Param_index of int
    (*

    ?1, ?2 ... — explicit 1-based slot

    *)
  3. | Param_name of string
    (*

    :name @name $name

    *)
Sourcetype conflict_action =
  1. | CA_rollback
  2. | CA_abort
  3. | CA_fail
  4. | CA_ignore
  5. | CA_replace
Sourcetype binop =
  1. | Eq
  2. | Ne
  3. | Lt
  4. | Le
  5. | Gt
  6. | Ge
    (*

    comparison

    *)
  7. | Add
  8. | Sub
  9. | Mul
  10. | Div
    (*

    arithmetic

    *)
  11. | And
  12. | Or
    (*

    logical

    *)
  13. | Concat
    (*

    string concatenation ||

    *)
  14. | Mod
    (*

    modulo %

    *)
  15. | Bit_and
  16. | Bit_or
    (*

    bitwise & |

    *)
  17. | Lshift
  18. | Rshift
    (*

    shift << >>

    *)
  19. | Like
  20. | Glob
    (*

    pattern matching

    *)
Sourcetype agg_func =
  1. | Agg_count
  2. | Agg_sum
  3. | Agg_avg
  4. | Agg_min
  5. | Agg_max
  6. | Agg_group_concat of string option
    (*

    GROUP_CONCAT(col) → None (default sep ","); GROUP_CONCAT(col, 'sep') → Some sep

    *)

Aggregate functions supported in Phase 2 Task 6.

Sourcetype scalar_func =
  1. | Fn_length
  2. | Fn_lower
  3. | Fn_upper
  4. | Fn_abs
  5. | Fn_coalesce
  6. | Fn_ifnull
  7. | Fn_substr
    (*

    SUBSTR(s, start, len) — 1-indexed

    *)
  8. | Fn_trim
  9. | Fn_ltrim
  10. | Fn_rtrim
    (*

    TRIM, LTRIM, RTRIM — optional 2nd arg for chars

    *)
  11. | Fn_replace
    (*

    REPLACE(s, old, new)

    *)
  12. | Fn_instr
    (*

    INSTR(s, sub) → 1-indexed position or 0

    *)
  13. | Fn_round
    (*

    ROUND(n, digits)

    *)
  14. | Fn_typeof
    (*

    TYPEOF(x) → 'integer'|'real'|'text'|'blob'|'null'

    *)
  15. | Fn_date
    (*

    DATE(ts, mod...) → 'YYYY-MM-DD'

    *)
  16. | Fn_time
    (*

    TIME(ts, mod...) → 'HH:MM:SS'

    *)
  17. | Fn_datetime
    (*

    DATETIME(ts, mod...) → 'YYYY-MM-DD HH:MM:SS'

    *)
  18. | Fn_strftime
    (*

    STRFTIME(fmt, ts, mod...) → formatted string

    *)
  19. | Fn_julianday
    (*

    JULIANDAY(ts, mod...) → float

    *)
  20. | Fn_unixepoch
    (*

    UNIXEPOCH(ts, mod...) → integer

    *)
  21. | Fn_ceil
    (*

    CEIL(x) / CEILING(x) — round up

    *)
  22. | Fn_floor
    (*

    FLOOR(x) — round down

    *)
  23. | Fn_sqrt
    (*

    SQRT(x) — square root

    *)
  24. | Fn_pow
    (*

    POW(x,y) / POWER(x,y) — x^y

    *)
  25. | Fn_exp
    (*

    EXP(x) — e^x

    *)
  26. | Fn_ln
    (*

    LN(x) — natural log

    *)
  27. | Fn_log
    (*

    LOG(x) → ln x; LOG(B,x) → log base B of x

    *)
  28. | Fn_log2
    (*

    LOG2(x) — log base 2

    *)
  29. | Fn_log10
    (*

    LOG10(x) — log base 10

    *)
  30. | Fn_sign
    (*

    SIGN(x) → -1 | 0 | 1 as integer

    *)
  31. | Fn_trunc
    (*

    TRUNC(x,d) — truncate toward zero

    *)
  32. | Fn_pi
    (*

    PI() — constant π, zero args

    *)
  33. | Fn_sin
    (*

    SIN(x)

    *)
  34. | Fn_cos
    (*

    COS(x)

    *)
  35. | Fn_tan
    (*

    TAN(x)

    *)
  36. | Fn_asin
    (*

    ASIN(x)

    *)
  37. | Fn_acos
    (*

    ACOS(x)

    *)
  38. | Fn_atan
    (*

    ATAN(x)

    *)
  39. | Fn_atan2
    (*

    ATAN2(y,x) — two-argument arctangent

    *)
  40. | Fn_degrees
    (*

    DEGREES(x) — radians to degrees

    *)
  41. | Fn_radians
    (*

    RADIANS(x) — degrees to radians

    *)
  42. | Fn_json_extract
    (*

    json_extract(json, path)

    *)
  43. | Fn_json_object
    (*

    json_object(k,v,...)

    *)
  44. | Fn_json_array
    (*

    json_array(v,...)

    *)
  45. | Fn_json_type
    (*

    json_type(json,path)

    *)
  46. | Fn_json_valid
    (*

    json_valid(json) → 0|1

    *)
  47. | Fn_json_set
    (*

    json_set(json, path, val, path, val ...)

    *)
  48. | Fn_json_insert
    (*

    json_insert — insert only if absent

    *)
  49. | Fn_json_replace
    (*

    json_replace — update only if present

    *)
  50. | Fn_json_remove
    (*

    json_remove(json, path, path ...)

    *)
  51. | Fn_hex
    (*

    HEX(x) — hex encoding of blob, text, or integer

    *)
  52. | Fn_char
    (*

    CHAR(x,...) — Unicode code points to UTF-8 string

    *)
  53. | Fn_unicode
    (*

    UNICODE(s) — first Unicode code point of string, or NULL

    *)
  54. | Fn_printf
    (*

    PRINTF(fmt,...) / FORMAT(fmt,...) — printf-style formatting

    *)
  55. | Fn_zeroblob
    (*

    ZEROBLOB(n) — blob of n zero bytes

    *)
  56. | Fn_random
    (*

    RANDOM() — random 64-bit integer

    *)
  57. | Fn_randomblob
    (*

    RANDOMBLOB(n) — random blob of n bytes

    *)
  58. | Fn_changes
    (*

    CHANGES() — rows affected by last DML

    *)
  59. | Fn_last_insert_rowid
    (*

    LAST_INSERT_ROWID() — rowid of last INSERT

    *)
  60. | Fn_total_changes
    (*

    TOTAL_CHANGES() — total rows affected since connection open

    *)
  61. | Fn_sqlite_version
    (*

    SQLITE_VERSION() — constant text version string

    *)

Scalar functions supported in Phase 5 Task 1.

Sourcetype set_op =
  1. | Union
  2. | Union_all
  3. | Intersect
  4. | Except
Sourcetype trigger_timing =
  1. | TT_before
  2. | TT_after
  3. | TT_instead_of
Sourcetype trigger_event =
  1. | TE_insert
  2. | TE_update
  3. | TE_delete
Sourcetype order_dir =
  1. | Asc
  2. | Desc
Sourcetype collation =
  1. | Collate_binary
  2. | Collate_nocase
  3. | Collate_rtrim
Sourcetype frame_unit =
  1. | Frame_rows
  2. | Frame_range
Sourcetype frame_bound =
  1. | FB_unbounded_preceding
  2. | FB_preceding of int
  3. | FB_current_row
  4. | FB_following of int
  5. | FB_unbounded_following
Sourcetype frame_spec = {
  1. unit : frame_unit;
  2. start : frame_bound;
  3. end_ : frame_bound;
}
Sourcetype join_kind =
  1. | Inner
  2. | Left
Sourcetype fk_action = Granary_catalog.Catalog.fk_action =
  1. | FA_no_action
  2. | FA_restrict
  3. | FA_cascade
  4. | FA_set_null
  5. | FA_set_default
Sourcetype table_constraint =
  1. | TC_unique of string list
    (*

    UNIQUE(col1, col2, ...)

    *)
  2. | TC_primary_key of {
    1. pk_cols : string list;
      (*

      PRIMARY KEY(col1, col2, ...)

      *)
    2. 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.

      *)
    }
  3. | TC_foreign_key of {
    1. local_cols : string list;
    2. parent_table : string;
    3. parent_cols : string list;
    4. on_delete : fk_action;
    5. on_update : fk_action;
    6. deferrable : bool;
    }
    (*

    FOREIGN KEY(local_cols) REFERENCES parent_table(parent_cols) ON DELETE/UPDATE action

    *)
Sourcetype refresh_mode =
  1. | Refresh_auto
  2. | Refresh_full
  3. | Refresh_delta

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.

Sourcetype expr =
  1. | E_lit of literal
  2. | E_col of string
    (*

    unqualified column reference

    *)
  3. | E_tbl_col of string * string
    (*

    qualified: table.col

    *)
  4. | E_binop of binop * expr * expr
  5. | E_not of expr
  6. | E_is_null of expr
  7. | E_is_not_null of expr
  8. | E_neg of expr
    (*

    unary minus

    *)
  9. | E_bitnot of expr
    (*

    bitwise NOT ~

    *)
  10. | E_between of expr * expr * expr
    (*

    subject BETWEEN lo AND hi

    *)
  11. | E_in of expr * expr list
    (*

    subject IN (val1, val2, ...)

    *)
  12. | E_agg of agg_func * expr option
    (*

    Aggregate call; None argument means COUNT( * ).

    *)
  13. | E_func of scalar_func * expr list
    (*

    Scalar function call.

    *)
  14. | E_param of param
    (*

    parameter: ?, ?1, :name, @name, $name

    *)
  15. | E_match of string * string
    (*

    E_match (table_name, query_string): WHERE table MATCH 'query'

    *)
  16. | E_subquery of stmt
    (*

    scalar subquery: (SELECT ...) in expr position

    *)
  17. | E_exists of stmt
    (*

    EXISTS (SELECT ...)

    *)
  18. | E_in_select of expr * stmt
    (*

    x IN (SELECT ...)

    *)
  19. | E_case of {
    1. scrutinee : expr option;
      (*

      None = searched form, Some = simple form

      *)
    2. branches : (expr * expr) list;
      (*

      (WHEN condition/value, THEN result)

      *)
    3. else_ : expr option;
    }
  20. | E_cast of expr * ty
    (*

    CAST(expr AS type) — SQLite type coercion

    *)
  21. | E_window of {
    1. func : window_func;
    2. args : expr list;
    3. window : window_spec;
    }
    (*

    Window function call: FUNC(...) OVER (PARTITION BY ... ORDER BY ...)

    *)
  22. | E_collate of expr * collation
    (*

    expr COLLATE collation_name

    *)
  23. | E_fts_snippet of {
    1. table : string;
    2. col_idx : int;
    3. start_tag : string;
    4. end_tag : string;
    5. ellipsis : string;
    6. n_tokens : int;
    }
    (*

    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.

Sourceand window_func =
  1. | WF_row_number
  2. | WF_rank
  3. | WF_dense_rank
  4. | WF_ntile
  5. | WF_lag
  6. | WF_lead
  7. | WF_first_value
  8. | WF_last_value
  9. | WF_nth_value
  10. | WF_agg of agg_func
  11. | WF_percent_rank
  12. | WF_cume_dist
Sourceand window_spec = {
  1. partition_by : expr list;
  2. order_by : order_key list;
  3. frame : frame_spec option;
}
Sourceand order_key = {
  1. expr : expr;
  2. dir : order_dir;
  3. nulls : [ `Nulls_first | `Nulls_last ] option;
}
Sourceand join_clause = {
  1. kind : join_kind;
  2. table : string;
    (*

    right-side table name

    *)
  3. alias : string option;
    (*

    optional alias — used in E_tbl_col resolution

    *)
  4. on : expr;
    (*

    join condition (predicate over both tables)

    *)
}
Sourceand upsert_update = {
  1. conflict_cols : string list;
  2. assignments : (string * expr) list;
}
Sourceand group_by_item = string * string option

(column_name, qualifier): qualified names like table.col become ("col", Some "table"); bare names become ("col", None).

Sourceand stmt =
  1. | S_create_table of {
    1. name : string;
    2. columns : column_def list;
    3. constraints : table_constraint list;
    4. if_not_exists : bool;
    5. 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.

      *)
    6. using_columnstore : bool;
    }
  2. | S_insert of {
    1. table : string;
    2. columns : string list;
      (*

      named columns; empty = "all in order"

      *)
    3. values : expr list list;
      (*

      one inner list per VALUES row

      *)
    4. on_conflict : conflict_action option;
    5. returning : expr list;
      (*

      empty = no RETURNING

      *)
    6. upsert_update : upsert_update option;
    }
  3. | S_insert_select of {
    1. table : string;
    2. columns : string list;
      (*

      empty = all non-generated columns

      *)
    3. on_conflict : conflict_action option;
    4. select : stmt;
    }
  4. | S_select of {
    1. distinct : bool;
    2. 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.

      *)
    3. table : string;
    4. table_alias : string option;
      (*

      optional AS alias for the FROM table

      *)
    5. joins : join_clause list;
      (*

      empty list = no joins

      *)
    6. where : expr option;
    7. group_by : group_by_item list;
      (*

      column names; empty = no GROUP BY

      *)
    8. having : expr option;
      (*

      HAVING predicate (may reference aggregates)

      *)
    9. order : order_key list;
      (*

      empty = no ORDER BY

      *)
    10. limit : int option;
    11. offset : int option;
    }
  5. | S_create_index of {
    1. name : string;
    2. table : string;
    3. columns : expr list;
    4. where_clause : expr option;
    5. unique : bool;
    6. if_not_exists : bool;
    }
  6. | S_update of {
    1. table : string;
    2. assignments : (string * expr) list;
      (*

      (col_name, new_value_expr)

      *)
    3. where : expr option;
    4. order : order_key list;
    5. limit : int option;
    6. offset : int option;
    7. returning : expr list;
    }
  7. | S_delete of {
    1. table : string;
    2. where : expr option;
    3. order : order_key list;
    4. limit : int option;
    5. offset : int option;
    6. returning : expr list;
    }
  8. | S_drop_table of {
    1. name : string;
    2. if_exists : bool;
    }
  9. | S_drop_index of {
    1. name : string;
    2. if_exists : bool;
    }
  10. | S_alter_table of {
    1. table : string;
    2. action : alter_action;
    }
  11. | S_begin
  12. | S_commit
  13. | S_rollback
  14. | S_savepoint of string
    (*

    SAVEPOINT name

    *)
  15. | S_release of string
    (*

    RELEASE name

    *)
  16. | S_rollback_to of string
    (*

    ROLLBACK TO name

    *)
  17. | S_compound of {
    1. op : set_op;
    2. left : stmt;
    3. right : stmt;
    4. 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).

      *)
    5. limit : int option;
    6. offset : int option;
    }
  18. | S_create_fts_table of {
    1. name : string;
    2. columns : string list;
    }
  19. | S_pragma of pragma_kind
  20. | S_const_select of {
    1. 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.

    *)
  21. | S_with_cte of {
    1. name : string;
    2. def : stmt;
    3. query : stmt;
    4. recursive : bool;
    }
  22. | S_create_view of {
    1. name : string;
    2. query : stmt;
    }
  23. | S_create_reactive_view of {
    1. name : string;
    2. query : stmt;
    3. 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.

    *)
  24. | S_drop_view of {
    1. name : string;
    2. if_exists : bool;
    }
  25. | S_create_trigger of {
    1. name : string;
    2. timing : trigger_timing;
    3. event : trigger_event;
    4. table : string;
    5. when_ : expr option;
      (*

      WHEN clause; None if absent

      *)
    6. body : stmt list;
      (*

      statements between BEGIN…END

      *)
    }
  26. | S_drop_trigger of {
    1. name : string;
    2. if_exists : bool;
    }
  27. | S_explain of {
    1. analyze : bool;
      (*

      false = EXPLAIN; true = EXPLAIN ANALYZE

      *)
    2. stmt : stmt;
    }
  28. | S_vacuum
    (*

    Compact-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.

    *)
  29. | S_attach of {
    1. path : string;
      (*

      filesystem path to the database file

      *)
    2. 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.

    *)
  30. | S_detach of {
    1. schema : string;
      (*

      schema name to detach

      *)
    }
    (*

    DETACH DATABASE schema — phase 40 / #64. Closes and removes a previously attached sub-handle.

    *)
Sourceand pragma_kind =
  1. | Pragma_table_info of string
  2. | Pragma_index_list of string
  3. | Pragma_foreign_key_list of string
  4. | Pragma_foreign_keys
  5. | Pragma_foreign_keys_set of bool
  6. | Pragma_recursive_triggers
  7. | Pragma_recursive_triggers_set of bool
  8. | Pragma_defer_foreign_keys
  9. | Pragma_defer_foreign_keys_set of bool
  10. | Pragma_user_version
  11. | Pragma_user_version_set of int64
  12. | Pragma_journal_mode
  13. | Pragma_integrity_check
  14. | Pragma_wal_checkpoint
  15. | Pragma_wal_autocheckpoint
  16. | Pragma_wal_autocheckpoint_set of int64
  17. | Pragma_synchronous
  18. | Pragma_synchronous_set of string
  19. | Pragma_wal_batch_commits
  20. | Pragma_wal_batch_commits_set of int64
  21. | Pragma_wal_batch_interval_ms
  22. | Pragma_wal_batch_interval_ms_set of int64
  23. | Pragma_database_list
  24. | Pragma_active_database
  25. | Pragma_active_database_set of string
  26. | Pragma_set of string * string
Sourceand column_def = {
  1. name : string;
  2. ty : ty;
  3. not_null : bool;
  4. primary_key : bool;
  5. 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.

    *)
  6. 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.

    *)
  7. default : literal option;
  8. check : expr option;
  9. fk_ref : (string * string * fk_action * fk_action * bool) option;
    (*

    (parent_table, parent_col, on_delete, on_update, deferrable). None = no FK.

    *)
  10. generated_as : (expr * [ `Stored | `Virtual ]) option;
    (*

    GENERATED ALWAYS AS (expr) STORED | VIRTUAL. None = not generated.

    *)
}
Sourceand alter_action =
  1. | AA_add_column of column_def
  2. | AA_rename_table of string
  3. | AA_rename_column of string * string
  4. | AA_drop_column of string
    (*

    column name to drop

    *)
Sourceval binop_to_sql : binop -> string

Render a binary operator as its SQL token (e.g. Eq"=").

Sourceval func_to_sql : scalar_func -> string

Render a scalar function as its SQL keyword (e.g. Fn_length"LENGTH").

Sourceval expr_to_sql : expr -> string

Serialise an expression back to SQL text, used for CHECK-constraint round-tripping. Raises Failure on forms with no SQL surface (aggregates, MATCH, subqueries, EXISTS, window calls, and BLOB literals).