`-D key=value` injects VALUE wherever `{{key}}` appears in the script. Substitution is textual (no type coercion). Repeat -D for multiple variables.
-D <KEY>=<VALUE>
## Overview `-D KEY=VALUE` injects parameter values into a SQL script before it is executed. The feature is a plain textual replace: every literal occurrence of `{{KEY}}` in the script text is replaced with VALUE, in one pass per key. The mechanism is shared by `run` (where it is user-facing) and by the internal `demo-test` runner. ## Behavior - The script file is read in full and substitution is applied to the entire text before statement splitting runs. - For each `-D KEY=VALUE` pair, the runner builds the pattern `{{KEY}}` and calls a whole-text replace. There is no regex, no word-boundary check, and no escape syntax: if `{{KEY}}` appears anywhere (including inside string literals, comments, or identifiers), it is replaced. - Substitution is single-pass per key in the order the keys are iterated. Values that themselves contain `{{` sequences are NOT re-scanned for further substitution. - Path-like keys receive special handling. If the key name contains the substring `path`, `dir`, or `location`, the value has every `\` rewritten to `/` before substitution. This lets Windows-native paths flow unchanged from a provisioning API into POSIX-style SQL locations. Keys without one of those substrings receive the value verbatim. - No type coercion, no SQL-level quoting, no escaping. If the SQL expects a string literal, the author must wrap the placeholder in quotes in the script itself. - If a `{{KEY}}` placeholder has no corresponding `-D` argument, it is left in the script as-is and will be sent to the compute engine, which almost certainly rejects it as a syntax error. ## Compatibility - Available on `run` only. Piped-stdin execution does not accept `-D` flags; scripts that need parameters must be executed via `run <FILE>`. - The identical substitution function powers demo-test's internal `{{zone_name}}`, `{{data_path}}`, and `{{current_user}}` variables, so behaviour is consistent across both code paths. - The substitution order is unspecified (HashMap iteration). Scripts must not depend on one key's value being substituted before another's; each key should target a unique placeholder.
| Name | Type | Description |
|---|---|---|
KEY | Variable name referenced inside the script as `{{KEY}}`. Case-sensitive. The key is used verbatim to build the placeholder pattern `{{KEY}}`; any characters allowed in a shell argument are allowed in the key, but only exact-match placeholders are substituted. | |
VALUE | Replacement text. Inserted verbatim where `{{KEY}}` appears. No SQL quoting, no type coercion, no escaping. If the key contains the substrings `path`, `dir`, or `location`, backslashes in the value are rewritten to forward slashes before substitution. |
# Basic substitution: inject a zone name and a data path
delta-forge-cli run setup.sql -D zone_name=prod -D data_path=/mnt/prod
# setup.sql:
# CREATE ZONE {{zone_name}} LOCATION '{{data_path}}';
# Multiple variables: repeat -D for each key
delta-forge-cli run migrate.sql -D tenant=acme -D schema=reporting -D retention_days=30
# Path normalisation: keys containing 'path', 'dir', or 'location'
# rewrite backslashes to forward slashes in the VALUE
delta-forge-cli run load.sql -D data_path='C:\data\raw'
# inside load.sql, {{data_path}} expands to C:/data/raw
# Values with spaces must be quoted at the shell
delta-forge-cli run report.sql -D title='Monthly Sales Summary'
# No SQL-level quoting is added; the caller must quote the placeholder
# in the SQL source if the value is meant to be a string literal
# CORRECT: INSERT INTO t VALUES ('{{name}}');
# INCORRECT: INSERT INTO t VALUES ({{name}}); -- unquoted, breaks for strings