inline_sql(...) for short model-specific statements.
For shared lifecycle ordering, failure timing, naming, and identity rules, see the Hooks overview.
Reusable SQL hooks
SQLBuild discovers.sql files recursively under hooks/sql/. Each file defines exactly one hook and must start with a HOOK(...) header as its first non-whitespace content.
hooks/sql/permissions/grant_access.sql
sql("grant_access", ...). Nested directories organize files but do not namespace names: hooks/sql/admin/grant_access.sql is still named grant_access.
HOOK() accepts only an optional, non-empty description. It does not accept a name; rename the file to rename the hook. The SQL after the header must contain one executable statement.
Files beginning with _ are skipped. All other .sql files under hooks/sql/ are parsed as hook resources and must have a valid HOOK() header.
Invoke a named hook
Pass the hook name and its arguments from a model’spre_hooks or post_hooks list:
models/marts/orders.sql
SQL hook arguments
Named SQL hooks declare parameters by using them in the SQL body. Arguments are supplied as named values insql("name", args...):
hooks/sql/record_access.sql
TRUE or FALSE, numbers render directly, and null renders as NULL. Lists render as comma-separated values, applying raw or quoted behavior to each item. For example, @'roles' with roles: ["reader", "writer"] renders as 'reader', 'writer'.
Every referenced argument is required and every supplied argument must be used. Missing arguments, unused arguments, and unsupported values such as maps fail compilation. Raw string arguments are not escaped; use @'name' for data values and reserve @name for trusted SQL structure.
Inline SQL hooks
Useinline_sql("...") for SQL that is specific to one model:
Compile-time context
Both named and inline SQL hooks are compiled in the model’s context. They support:- Project variables such as
@@audit_schema - Environment variables such as
@@ENV:DEPLOY_ROLE - Hook context variables such as
@@CTX:destination.qualified - Enums and constants such as
@enum("role").ANALYSTand@const("retention_days") - Python macros such as
@grant_target("@@CTX:destination.qualified")
@name and @'name' arguments into the hook body. It then resolves interpolation, declarations, and macros in the calling model’s effective context. A supplied argument such as relation: "@@CTX:destination.qualified" therefore resolves to that model’s final target-overridden destination.
${...} config-template syntax is not valid in SQL hooks.
Validation and diagnostics
Every named SQL hook is required to render to exactly one executable statement. This statement-shape check is unconditional, sosql_validation: false and --no-sql-validation do not permit multiple statements or standalone expressions such as 1 + 1.
Full dialect syntax validation runs separately after expansion when the model’s effective SQL-validation gate is enabled: SQL analysis must be enabled, --no-sql-validation must be absent, and the effective project or model sql_validation value must be true.
Common errors include:
- Missing, repeated, or misplaced
HOOK(...)headers - Unsupported header keys, empty descriptions, and missing SQL bodies
- Missing or unused arguments and unsupported argument values
- Unknown named hooks, unquoted hook names, and bare hook strings
- Invalid SQL, multiple statements, or non-statement expressions after compile-time expansion
post_hooks[1] sql("grant_access"). Runtime output preserves the authored hook index and identifies named and inline SQL entries.
