kura_dialect behaviour (kura v2.0.6)
View SourceSQL dialect behaviour. Translates a portable #kura_query{} AST into
backend-specific SQL.
#kura_query{} is the portable AST: it describes operations as atoms
and tuples, not as SQL strings. The dialect callbacks turn that AST
into SQL bytes appropriate for a given backend.
Today
The canonical implementation is kura_dialect_pg, which targets
PostgreSQL via the pgo driver's $N placeholder convention.
Tomorrow
Adding SQLite or MySQL is a matter of providing another implementation
of this behaviour. Differences (placeholder syntax ? vs $N,
identifier quoting "foo" vs `foo`, RETURNING vs lastrowid,
ON CONFLICT vs ON DUPLICATE KEY UPDATE, LIMIT/OFFSET vs FETCH FIRST) all live in the dialect impl. The AST stays the same.
Public API entry point
Consumers go through kura_query_compiler, which delegates to the
configured dialect module. They do not call this behaviour's
callbacks directly.
Summary
Types
Next placeholder index. Used when composing sub-queries (CTEs, sub-selects in WHERE) so placeholders stay contiguous across the entire compiled statement.
Parameter list in the order the placeholders appear in sql().
Compiled SQL bytes. Implementations are free to return iodata or a binary.
Callbacks
Optional. SQL bytes for a kura column type, used by kura_migrator DDL.
Compile a DELETE-by-primary-key.
Compile a bulk DELETE (DELETE ... WHERE ...) from a query AST.
Optional. SQL bytes for a column default value, used by kura_migrator DDL.
Compile a single-row INSERT (no options).
Compile a single-row INSERT with options (e.g. on_conflict).
Compile a bulk INSERT (multi-row).
Compile a bulk INSERT with options (returning => true | [Field]).
Compile a query AST into {SQL, Params}.
Compile a query AST starting placeholder numbering at StartCounter.
Returns the next free counter so callers can chain sub-compilations.
Compile an UPDATE-by-primary-key.
Compile a bulk UPDATE (UPDATE ... WHERE ...) from a query AST and a SET map.
Types
-type counter() :: pos_integer().
Next placeholder index. Used when composing sub-queries (CTEs, sub-selects in WHERE) so placeholders stay contiguous across the entire compiled statement.
-type params() :: [term()].
Parameter list in the order the placeholders appear in sql().
-type sql() :: iodata().
Compiled SQL bytes. Implementations are free to return iodata or a binary.
Callbacks
-callback column_type(kura_types:kura_type()) -> binary().
Optional. SQL bytes for a kura column type, used by kura_migrator DDL.
Compile a DELETE-by-primary-key.
-callback delete_all(#kura_query{from :: atom() | module() | undefined, select :: [atom() | term()] | {exprs, [term()]}, wheres :: [term()], joins :: [term()], order_bys :: [term()], group_bys :: [atom()], havings :: [term()], limit :: non_neg_integer() | undefined, offset :: non_neg_integer() | undefined, distinct :: boolean() | [atom()], lock :: binary() | undefined, prefix :: binary() | undefined, preloads :: [atom() | {atom(), list()}], ctes :: [{binary(), #kura_query{}}], combinations :: [{union | union_all | intersect | except, #kura_query{}}], include_deleted :: boolean()}) -> {sql(), params()}.
Compile a bulk DELETE (DELETE ... WHERE ...) from a query AST.
Optional. SQL bytes for a column default value, used by kura_migrator DDL.
Compile a single-row INSERT (no options).
Compile a single-row INSERT with options (e.g. on_conflict).
Compile a bulk INSERT (multi-row).
Compile a bulk INSERT with options (returning => true | [Field]).
-callback to_sql(#kura_query{from :: atom() | module() | undefined, select :: [atom() | term()] | {exprs, [term()]}, wheres :: [term()], joins :: [term()], order_bys :: [term()], group_bys :: [atom()], havings :: [term()], limit :: non_neg_integer() | undefined, offset :: non_neg_integer() | undefined, distinct :: boolean() | [atom()], lock :: binary() | undefined, prefix :: binary() | undefined, preloads :: [atom() | {atom(), list()}], ctes :: [{binary(), #kura_query{}}], combinations :: [{union | union_all | intersect | except, #kura_query{}}], include_deleted :: boolean()}) -> {sql(), params()}.
Compile a query AST into {SQL, Params}.
-callback to_sql_from(#kura_query{from :: atom() | module() | undefined, select :: [atom() | term()] | {exprs, [term()]}, wheres :: [term()], joins :: [term()], order_bys :: [term()], group_bys :: [atom()], havings :: [term()], limit :: non_neg_integer() | undefined, offset :: non_neg_integer() | undefined, distinct :: boolean() | [atom()], lock :: binary() | undefined, prefix :: binary() | undefined, preloads :: [atom() | {atom(), list()}], ctes :: [{binary(), #kura_query{}}], combinations :: [{union | union_all | intersect | except, #kura_query{}}], include_deleted :: boolean()}, counter()) -> {sql(), params(), counter()}.
Compile a query AST starting placeholder numbering at StartCounter.
Returns the next free counter so callers can chain sub-compilations.
Compile an UPDATE-by-primary-key.
-callback update_all(#kura_query{from :: atom() | module() | undefined, select :: [atom() | term()] | {exprs, [term()]}, wheres :: [term()], joins :: [term()], order_bys :: [term()], group_bys :: [atom()], havings :: [term()], limit :: non_neg_integer() | undefined, offset :: non_neg_integer() | undefined, distinct :: boolean() | [atom()], lock :: binary() | undefined, prefix :: binary() | undefined, preloads :: [atom() | {atom(), list()}], ctes :: [{binary(), #kura_query{}}], combinations :: [{union | union_all | intersect | except, #kura_query{}}], include_deleted :: boolean()}, map()) -> {sql(), params()}.
Compile a bulk UPDATE (UPDATE ... WHERE ...) from a query AST and a SET map.