From c3895bac1a579552f4baf1c5e02024f3ddc19d60 Mon Sep 17 00:00:00 2001 From: Charlie Dowler Date: Thu, 30 Apr 2026 21:21:29 +0100 Subject: [PATCH 1/9] docs: add query introspection guide [SPK-392] Adds a developer guide covering the new ld.query.fields and ld.query.filters Liquid checks. Covers what to check, where it works, the {% raw %} requirement for dbt YAML, and three worked examples: - smart_revenue: a metric that defaults to a built-in filter but respects the user's filter when applied - active_users: composes ld.parameters with ld.query.filters in the same Liquid block - a custom dimension built in the UI from the explore, no PR needed Wires the page into the Developer guides nav after using-parameters, and adds a related-link from the parameters page. Co-Authored-By: Claude Opus 4.7 (1M context) --- docs.json | 1 + guides/developer/query-introspection.mdx | 289 +++++++++++++++++++++++ guides/developer/using-parameters.mdx | 7 +- 3 files changed, 296 insertions(+), 1 deletion(-) create mode 100644 guides/developer/query-introspection.mdx diff --git a/docs.json b/docs.json index bbf8ea5d..6cc6a50f 100644 --- a/docs.json +++ b/docs.json @@ -196,6 +196,7 @@ "guides/developer/validating-your-content", "guides/developer/renaming-models-and-fields", "guides/developer/using-parameters", + "guides/developer/query-introspection", "guides/developer/caching", "guides/developer/timezones", "guides/developer/explores", diff --git a/guides/developer/query-introspection.mdx b/guides/developer/query-introspection.mdx new file mode 100644 index 00000000..5e0482a7 --- /dev/null +++ b/guides/developer/query-introspection.mdx @@ -0,0 +1,289 @@ +--- +title: "How to use query introspection" +sidebarTitle: Query introspection +--- + +**Query introspection** lets a dimension or metric branch its SQL based on what's in the current query — which fields the user selected, and which fields they filtered on. The same definition can produce a different `SELECT` clause for every query. + +This is useful for "smart" metrics that adapt to the question being asked. For example, a `total_revenue` metric that defaults to completed orders only — but stops applying that filter the moment the user filters status themselves. + +## What you can check + +Inside a `sql:` block, two new Liquid checks are available: + +| Check | Returns true when… | +| :--- | :--- | +| `{% if ld.query.fields contains "table.field" %}` | The named field is selected or grouped in the current query | +| `{% if ld.query.filters contains "table.field" %}` | A filter is applied to the named field in the current query | + +Both checks accept the **dotted field id** in the form `{table_name}.{field_name}` — same identifier you'd see in the URL of an explore. The check covers **both dimensions and metrics**, so `ld.query.fields contains "orders.total_order_amount"` works for a metric being selected. + +You can use either `ld.query` or the longer `lightdash.query` — they're aliases. + + + These are **Liquid template tags** (`{% %}`), not the Lightdash parameter substitution syntax (`${...}`). They're evaluated server-side when a query runs, before the SQL is sent to your warehouse. + + +## Where you can use it + +Query introspection works anywhere `sql:` is evaluated at query time: + +1. **Dimension SQL** in your [dbt YAML](/references/dimensions) +2. **Metric SQL** in your [dbt YAML](/references/metrics) +3. **Additional dimensions** in your dbt YAML +4. **Custom dimensions** created via the UI ([custom fields](/guides/custom-fields)) + +It does **not** work in: + +- **Table calculations** — these run client-side after results return, not in the query SQL. +- **Rich text templates** — those use a different engine (`${value.formatted}`) and run after the query, not before. + +## Wrapping in `{% raw %}` for dbt YAML + +dbt's Jinja engine also uses `{% %}` delimiters, and it will choke on Liquid-specific tags like `{% elsif %}`. You must wrap any Liquid block in `{% raw %} ... {% endraw %}` so dbt passes it through untouched. Lightdash then evaluates the unwrapped Liquid at query time. + +```yaml +sql: | + {% raw %}{% if ld.query.filters contains "orders.status" %} + SUM(${TABLE}.amount) + {% else %} + SUM(CASE WHEN ${TABLE}.status = 'completed' THEN ${TABLE}.amount ELSE 0 END) + {% endif %}{% endraw %} +``` + + + When you create a **custom dimension via the UI**, no `{% raw %}` wrapper is needed — the SQL goes straight to Lightdash without passing through dbt. + + +## Examples + +### Smart-default filter (filter-aware metric) + +A revenue metric that defaults to "completed orders only" — but if the user filters on status themselves, the metric respects their filter instead. + + + + ```yaml + models: + - name: orders + columns: + - name: amount + meta: + metrics: + smart_revenue: + type: number + label: Smart Revenue (filter-aware) + format: usd + sql: | + {% raw %}{% if ld.query.filters contains "orders.status" %} + SUM(${TABLE}.amount) + {% else %} + SUM(CASE WHEN ${TABLE}.status = 'completed' THEN ${TABLE}.amount ELSE 0 END) + {% endif %}{% endraw %} + ``` + + + ```yaml + models: + - name: orders + columns: + - name: amount + config: + meta: + metrics: + smart_revenue: + type: number + label: Smart Revenue (filter-aware) + format: usd + sql: | + {% raw %}{% if ld.query.filters contains "orders.status" %} + SUM(${TABLE}.amount) + {% else %} + SUM(CASE WHEN ${TABLE}.status = 'completed' THEN ${TABLE}.amount ELSE 0 END) + {% endif %}{% endraw %} + ``` + + + ```yaml + type: model + name: orders + + metrics: + smart_revenue: + type: number + label: Smart Revenue (filter-aware) + format: usd + sql: | + {% raw %}{% if ld.query.filters contains "orders.status" %} + SUM(${TABLE}.amount) + {% else %} + SUM(CASE WHEN ${TABLE}.status = 'completed' THEN ${TABLE}.amount ELSE 0 END) + {% endif %}{% endraw %} + ``` + + + +**Result:** + +| The user's query | SQL Lightdash sends to the warehouse | +| :--- | :--- | +| No filter on `status` | `SUM(CASE WHEN status = 'completed' THEN amount ELSE 0 END)` | +| `status IN ('returned')` | `SUM(amount)` | + +The `CASE WHEN` disappears entirely once the user applies their own filter — the metric stops second-guessing them. + +### Default to a parameter, but back off when the user filters + +A common pattern: a metric should default to some sensible time window — the last 30 days, say — but if the user applies their own date filter, the default shouldn't fight them. This composes a [parameter](/guides/developer/using-parameters) for the default with a `ld.query.filters` check for the override. + + + + ```yaml + models: + - name: events + meta: + parameters: + lookback_days: + label: Lookback days + type: number + default: 30 + columns: + - name: user_id + meta: + metrics: + active_users: + type: count_distinct + description: | + Distinct users in the lookback window. The lookback + window comes from the `lookback_days` parameter — but + if the user filters event_date themselves, that filter + wins. + sql: | + {% raw %}{% if ld.query.filters contains "events.event_date" %} + ${TABLE}.user_id + {% else %} + CASE + WHEN ${TABLE}.event_date >= CURRENT_DATE - INTERVAL '{{ ld.parameters.events.lookback_days }} days' + THEN ${TABLE}.user_id + END + {% endif %}{% endraw %} + ``` + + + ```yaml + models: + - name: events + config: + meta: + parameters: + lookback_days: + label: Lookback days + type: number + default: 30 + columns: + - name: user_id + config: + meta: + metrics: + active_users: + type: count_distinct + description: | + Distinct users in the lookback window. The lookback + window comes from the `lookback_days` parameter — but + if the user filters event_date themselves, that filter + wins. + sql: | + {% raw %}{% if ld.query.filters contains "events.event_date" %} + ${TABLE}.user_id + {% else %} + CASE + WHEN ${TABLE}.event_date >= CURRENT_DATE - INTERVAL '{{ ld.parameters.events.lookback_days }} days' + THEN ${TABLE}.user_id + END + {% endif %}{% endraw %} + ``` + + + ```yaml + type: model + name: events + + parameters: + lookback_days: + label: Lookback days + type: number + default: 30 + + metrics: + active_users: + type: count_distinct + sql: | + {% raw %}{% if ld.query.filters contains "events.event_date" %} + ${TABLE}.user_id + {% else %} + CASE + WHEN ${TABLE}.event_date >= CURRENT_DATE - INTERVAL '{{ ld.parameters.events.lookback_days }} days' + THEN ${TABLE}.user_id + END + {% endif %}{% endraw %} + ``` + + + +**Result:** + +| The user's query | What `active_users` counts | +| :--- | :--- | +| No filter on `event_date` | Users active in the last `lookback_days` (default 30) | +| `event_date >= '2026-01-01'` | Users active in the user-selected window — parameter ignored | + +The parameter sets the default; introspection lets the user override. Two systems composing in one block — both `ld.parameters.x` and `ld.query.filters` are resolved before the SQL leaves Lightdash. + +### A custom dimension built in the UI, no PR required + +Query introspection isn't only for fields defined in YAML. Any user with edit access to a chart can spin up a one-off introspection-aware dimension from the explore, save it with the chart, and share it — without touching dbt or opening a PR. + +**Open the explore → Dimensions sidebar → Add → Custom dimension → Custom SQL.** Paste the Liquid block directly into the SQL field. **No `{% raw %}` wrapper needed** — the SQL goes straight to Lightdash without passing through dbt. + +```liquid +{% if ld.query.fields contains "orders.status" %} + CASE WHEN ${TABLE}.status = 'returned' THEN 'returned' + WHEN ${TABLE}.status = 'completed' THEN 'completed' + ELSE 'in flight' END +{% else %} + 'all orders' +{% endif %} +``` + +**The use case:** an analyst on a customer call gets asked *"can we group by completion state real quick?"* They open the explore, paste this in, save the chart, share the link. No model PR, no merge, no waiting on CI. The custom dimension lives on the saved chart and goes through the same query-time renderer as a YAML-defined field. + +This is the workflow query introspection unlocks for analysts who don't write dbt. + +### More patterns + +- **Skip an expensive operation when not needed** — wrap a window function or a `LEFT JOIN`-driven calculation in `{% if ld.query.fields contains "joined_table.field" %}` so the cost only shows up when the user has selected something that needs it. +- **Drill-aware defaults** — a `time_grain` dimension that returns `DATE_TRUNC('day', ...)` when the user is grouping at day level, but `${TABLE}.event_date` when they're not, avoiding a needless function call. +- **Self-narrating labels** — a string dimension that returns a different value depending on what's filtered, useful for embedded tiles and exports where the viewer can't see filter chips. + +## How to find a field's dotted id + +The dotted id is `{explore_table_name}.{field_name}`: + +- **`explore_table_name`** is the name of the model in the explore (the dbt model name, or the joined-table label/key) +- **`field_name`** is the YAML key for the dimension or metric (not the label) + +If you're not sure, hover the field in the Lightdash sidebar — the field id appears in the URL when the field is added to a query (e.g. `dimensions=["orders_status"]` becomes `"orders.status"` for the `contains` check). + +## Things to know + +- **`else` is safe by default.** If the field id you reference doesn't exist in the explore, the check returns false and the `else` branch fires. A typo in the field name will not throw an error. +- **Both checks see the full query.** The introspection covers every dimension, metric, and filter in the query — not just the field you're branching from. +- **Combine with parameters.** Liquid blocks can mix `ld.query.*` checks with `ld.parameters.*` checks in the same template. Both are resolved before the SQL leaves Lightdash. +- **No effect on existing SQL.** If a field's `sql:` doesn't contain a Liquid block, nothing changes — the renderer skips it entirely. Adopting query introspection on one field doesn't affect any others. + +## Related + +- [How to use parameters](/guides/developer/using-parameters) — the companion feature for `${ld.parameters.x}` substitution and `{% if ld.parameters.x == ... %}` Liquid blocks +- [Dimensions reference](/references/dimensions) +- [Metrics reference](/references/metrics) +- [Custom fields](/guides/custom-fields) — using query introspection in UI-created custom dimensions diff --git a/guides/developer/using-parameters.mdx b/guides/developer/using-parameters.mdx index ec7de7dd..b4da1fff 100644 --- a/guides/developer/using-parameters.mdx +++ b/guides/developer/using-parameters.mdx @@ -811,4 +811,9 @@ Here are some best practices to follow when using parameters: 2. **Provide default values**: Set default values for parameters to ensure queries work even if users don't set parameter values 3. **Add descriptions**: Include clear descriptions for parameters to help users understand their purpose 4. **Consider using options_from_dimension**: For parameters that should match values in your data, use `options_from_dimension` to dynamically populate options -5. **Consider performance**: Be mindful of how parameters affect query performance, especially with large datasets \ No newline at end of file +5. **Consider performance**: Be mindful of how parameters affect query performance, especially with large datasets + + +## Related + +- [Query introspection](/guides/developer/query-introspection) — branch a dimension or metric's SQL based on which fields the user has selected or filtered on, without needing a parameter dropdown. \ No newline at end of file From ea906f206807bf037f9ca4f0def4afd9755761d7 Mon Sep 17 00:00:00 2001 From: Charlie Dowler Date: Thu, 30 Apr 2026 21:30:51 +0100 Subject: [PATCH 2/9] docs: correct table-calculation claim in query introspection guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Table calculations run as SQL in a wrapping SELECT, not client-side, and Liquid blocks inside them are evaluated by the same render pipeline as dimensions and metrics. The previous note said neither — claiming they ran client-side and didn't support introspection. Rewrote it as a practical "don't reach for this here" caveat instead of an incorrect technical claim. Co-Authored-By: Claude Opus 4.7 (1M context) --- guides/developer/query-introspection.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/developer/query-introspection.mdx b/guides/developer/query-introspection.mdx index 5e0482a7..46d8da42 100644 --- a/guides/developer/query-introspection.mdx +++ b/guides/developer/query-introspection.mdx @@ -32,10 +32,10 @@ Query introspection works anywhere `sql:` is evaluated at query time: 2. **Metric SQL** in your [dbt YAML](/references/metrics) 3. **Additional dimensions** in your dbt YAML 4. **Custom dimensions** created via the UI ([custom fields](/guides/custom-fields)) +5. **Table calculations** — Liquid is evaluated, but introspection is rarely useful here. A table calculation already knows the rows and columns it's operating on, so `ld.query.fields contains "..."` mostly tells you what you can already see. Stick to dimensions and metrics unless you have a clear reason. It does **not** work in: -- **Table calculations** — these run client-side after results return, not in the query SQL. - **Rich text templates** — those use a different engine (`${value.formatted}`) and run after the query, not before. ## Wrapping in `{% raw %}` for dbt YAML From d152bfc4424d4eeb5f636859d4ed47e3b66191f3 Mon Sep 17 00:00:00 2001 From: Charlie Dowler Date: Thu, 30 Apr 2026 21:38:55 +0100 Subject: [PATCH 3/9] docs: tighten query introspection wording MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - drop the rich-text "does not work in" section: rich-text/markdown tiles aren't a SQL pipeline at all, so calling out a "different engine (${value.formatted})" was misleading - clarify joined-table dotted-id: it's the value under `join:`, not the `label` — avoids "Order Customer.first_name" guesses --- guides/developer/query-introspection.mdx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/guides/developer/query-introspection.mdx b/guides/developer/query-introspection.mdx index 46d8da42..230c0ac4 100644 --- a/guides/developer/query-introspection.mdx +++ b/guides/developer/query-introspection.mdx @@ -34,10 +34,6 @@ Query introspection works anywhere `sql:` is evaluated at query time: 4. **Custom dimensions** created via the UI ([custom fields](/guides/custom-fields)) 5. **Table calculations** — Liquid is evaluated, but introspection is rarely useful here. A table calculation already knows the rows and columns it's operating on, so `ld.query.fields contains "..."` mostly tells you what you can already see. Stick to dimensions and metrics unless you have a clear reason. -It does **not** work in: - -- **Rich text templates** — those use a different engine (`${value.formatted}`) and run after the query, not before. - ## Wrapping in `{% raw %}` for dbt YAML dbt's Jinja engine also uses `{% %}` delimiters, and it will choke on Liquid-specific tags like `{% elsif %}`. You must wrap any Liquid block in `{% raw %} ... {% endraw %}` so dbt passes it through untouched. Lightdash then evaluates the unwrapped Liquid at query time. @@ -269,8 +265,8 @@ This is the workflow query introspection unlocks for analysts who don't write db The dotted id is `{explore_table_name}.{field_name}`: -- **`explore_table_name`** is the name of the model in the explore (the dbt model name, or the joined-table label/key) -- **`field_name`** is the YAML key for the dimension or metric (not the label) +- **`explore_table_name`** is the dbt model name. For a joined table, it's the value under `join:` in the explore's joins config — not the join's `label`. +- **`field_name`** is the YAML key for the dimension or metric — not the label. If you're not sure, hover the field in the Lightdash sidebar — the field id appears in the URL when the field is added to a query (e.g. `dimensions=["orders_status"]` becomes `"orders.status"` for the `contains` check). From 8d2cc593cf1be3a250bcf1ef32aa9dedd6f693e6 Mon Sep 17 00:00:00 2001 From: Charlie Dowler Date: Thu, 30 Apr 2026 22:09:48 +0100 Subject: [PATCH 4/9] docs: describe table-calc introspection without prescription Replace the opinionated "rarely useful, stick to dimensions and metrics" guidance with a factual description of what each check returns inside a table calculation. Calls out the asymmetry between fields (largely tautological) and filters (genuinely informative, since filter context isn't in the result columns). --- guides/developer/query-introspection.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/developer/query-introspection.mdx b/guides/developer/query-introspection.mdx index 230c0ac4..2f283c88 100644 --- a/guides/developer/query-introspection.mdx +++ b/guides/developer/query-introspection.mdx @@ -32,7 +32,7 @@ Query introspection works anywhere `sql:` is evaluated at query time: 2. **Metric SQL** in your [dbt YAML](/references/metrics) 3. **Additional dimensions** in your dbt YAML 4. **Custom dimensions** created via the UI ([custom fields](/guides/custom-fields)) -5. **Table calculations** — Liquid is evaluated, but introspection is rarely useful here. A table calculation already knows the rows and columns it's operating on, so `ld.query.fields contains "..."` mostly tells you what you can already see. Stick to dimensions and metrics unless you have a clear reason. +5. **Table calculations** — Liquid is evaluated. `ld.query.fields contains "..."` is true for any column the table calculation can reference, since selected dimensions and metrics make up the result set. `ld.query.filters contains "..."` reflects the dimension and metric filters applied to the underlying query, which aren't otherwise visible in the table calculation's input. ## Wrapping in `{% raw %}` for dbt YAML From e82208278a91dfcbd3adcc3cb941b42b0ec501fe Mon Sep 17 00:00:00 2001 From: Charlie Dowler Date: Thu, 30 Apr 2026 22:12:03 +0100 Subject: [PATCH 5/9] docs: shorten table-calc bullet to match list style The other "where it works" bullets are one-liners; the table-calc bullet was a paragraph. Trim it so the list reads consistently. --- guides/developer/query-introspection.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/developer/query-introspection.mdx b/guides/developer/query-introspection.mdx index 2f283c88..d6939bd9 100644 --- a/guides/developer/query-introspection.mdx +++ b/guides/developer/query-introspection.mdx @@ -32,7 +32,7 @@ Query introspection works anywhere `sql:` is evaluated at query time: 2. **Metric SQL** in your [dbt YAML](/references/metrics) 3. **Additional dimensions** in your dbt YAML 4. **Custom dimensions** created via the UI ([custom fields](/guides/custom-fields)) -5. **Table calculations** — Liquid is evaluated. `ld.query.fields contains "..."` is true for any column the table calculation can reference, since selected dimensions and metrics make up the result set. `ld.query.filters contains "..."` reflects the dimension and metric filters applied to the underlying query, which aren't otherwise visible in the table calculation's input. +5. **Table calculations** ## Wrapping in `{% raw %}` for dbt YAML From 075ef1b531659fce940f41f02f140546b82ab06e Mon Sep 17 00:00:00 2001 From: Charlie Dowler Date: Thu, 30 Apr 2026 22:12:53 +0100 Subject: [PATCH 6/9] docs: add table-calc behaviour note below the list Move the explanation into a Note callout so the list stays one-line per item, but readers still see the asymmetry between ld.query.fields (largely tautological) and ld.query.filters (useful because filter context isn't in the result columns). --- guides/developer/query-introspection.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/guides/developer/query-introspection.mdx b/guides/developer/query-introspection.mdx index d6939bd9..9bdb63ff 100644 --- a/guides/developer/query-introspection.mdx +++ b/guides/developer/query-introspection.mdx @@ -34,6 +34,10 @@ Query introspection works anywhere `sql:` is evaluated at query time: 4. **Custom dimensions** created via the UI ([custom fields](/guides/custom-fields)) 5. **Table calculations** + + Inside a table calculation, `ld.query.fields contains "..."` is true for any column the table calc can reference, since selected dimensions and metrics make up the result set. `ld.query.filters contains "..."` is more useful — filter context isn't otherwise visible in the table calculation's input. + + ## Wrapping in `{% raw %}` for dbt YAML dbt's Jinja engine also uses `{% %}` delimiters, and it will choke on Liquid-specific tags like `{% elsif %}`. You must wrap any Liquid block in `{% raw %} ... {% endraw %}` so dbt passes it through untouched. Lightdash then evaluates the unwrapped Liquid at query time. From 11789769cbc6e2124521c578a49b8be593b7cf5a Mon Sep 17 00:00:00 2001 From: Charlie Dowler Date: Thu, 30 Apr 2026 22:15:10 +0100 Subject: [PATCH 7/9] docs: restore original table-calc guidance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The factual parts of the original wording hold up — `ld.query.fields` is largely redundant inside a table calculation, and "stick to dimensions and metrics" is the right default steer for analysts. --- guides/developer/query-introspection.mdx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/guides/developer/query-introspection.mdx b/guides/developer/query-introspection.mdx index 9bdb63ff..230c0ac4 100644 --- a/guides/developer/query-introspection.mdx +++ b/guides/developer/query-introspection.mdx @@ -32,11 +32,7 @@ Query introspection works anywhere `sql:` is evaluated at query time: 2. **Metric SQL** in your [dbt YAML](/references/metrics) 3. **Additional dimensions** in your dbt YAML 4. **Custom dimensions** created via the UI ([custom fields](/guides/custom-fields)) -5. **Table calculations** - - - Inside a table calculation, `ld.query.fields contains "..."` is true for any column the table calc can reference, since selected dimensions and metrics make up the result set. `ld.query.filters contains "..."` is more useful — filter context isn't otherwise visible in the table calculation's input. - +5. **Table calculations** — Liquid is evaluated, but introspection is rarely useful here. A table calculation already knows the rows and columns it's operating on, so `ld.query.fields contains "..."` mostly tells you what you can already see. Stick to dimensions and metrics unless you have a clear reason. ## Wrapping in `{% raw %}` for dbt YAML From 76f485a5fb44d8557eab73891afc231de904bccc Mon Sep 17 00:00:00 2001 From: Charlie Dowler Date: Thu, 30 Apr 2026 22:17:26 +0100 Subject: [PATCH 8/9] docs: drop table-calc bullet from "Where you can use it" The Liquid + introspection feature was scoped to dimensions and metrics in the original design. Liquid happening to evaluate inside table calculations is an incidental side-effect of where the renderer runs in the query pipeline, not a deliberate feature surface. Don't advertise it as supported. --- guides/developer/query-introspection.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/guides/developer/query-introspection.mdx b/guides/developer/query-introspection.mdx index 230c0ac4..9798447a 100644 --- a/guides/developer/query-introspection.mdx +++ b/guides/developer/query-introspection.mdx @@ -32,7 +32,6 @@ Query introspection works anywhere `sql:` is evaluated at query time: 2. **Metric SQL** in your [dbt YAML](/references/metrics) 3. **Additional dimensions** in your dbt YAML 4. **Custom dimensions** created via the UI ([custom fields](/guides/custom-fields)) -5. **Table calculations** — Liquid is evaluated, but introspection is rarely useful here. A table calculation already knows the rows and columns it's operating on, so `ld.query.fields contains "..."` mostly tells you what you can already see. Stick to dimensions and metrics unless you have a clear reason. ## Wrapping in `{% raw %}` for dbt YAML From fdbf24f85e713c26704baaf7f3b5f335d7c64296 Mon Sep 17 00:00:00 2001 From: Charlie Dowler Date: Thu, 30 Apr 2026 22:39:14 +0100 Subject: [PATCH 9/9] docs: tighten query-introspection page and add UI screenshot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Drop "anywhere sql: is evaluated" intro that overstated scope - Note that join `alias:` overrides the model name in dotted ids - Replace URL-derived field-id tip with a sidebar-hover instruction - Flag that date dimensions expand into per-interval ids — `event_date` won't match a filter on `event_date_day` - Add the Create Custom Dimension dialog screenshot to the UI example Co-Authored-By: Claude Opus 4.7 (1M context) --- guides/developer/query-introspection.mdx | 14 +++++++++++--- .../query-introspection-custom-dimension.png | Bin 0 -> 51732 bytes 2 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 images/guides/developer/query-introspection-custom-dimension.png diff --git a/guides/developer/query-introspection.mdx b/guides/developer/query-introspection.mdx index 9798447a..3112c8ef 100644 --- a/guides/developer/query-introspection.mdx +++ b/guides/developer/query-introspection.mdx @@ -26,7 +26,7 @@ You can use either `ld.query` or the longer `lightdash.query` — they're aliase ## Where you can use it -Query introspection works anywhere `sql:` is evaluated at query time: +Query introspection works in these places: 1. **Dimension SQL** in your [dbt YAML](/references/dimensions) 2. **Metric SQL** in your [dbt YAML](/references/metrics) @@ -240,6 +240,13 @@ Query introspection isn't only for fields defined in YAML. Any user with edit ac **Open the explore → Dimensions sidebar → Add → Custom dimension → Custom SQL.** Paste the Liquid block directly into the SQL field. **No `{% raw %}` wrapper needed** — the SQL goes straight to Lightdash without passing through dbt. +Create Custom Dimension dialog with a Liquid query introspection block + ```liquid {% if ld.query.fields contains "orders.status" %} CASE WHEN ${TABLE}.status = 'returned' THEN 'returned' @@ -264,14 +271,15 @@ This is the workflow query introspection unlocks for analysts who don't write db The dotted id is `{explore_table_name}.{field_name}`: -- **`explore_table_name`** is the dbt model name. For a joined table, it's the value under `join:` in the explore's joins config — not the join's `label`. +- **`explore_table_name`** is the dbt model name. For a joined table, use the `alias:` value if one is set on the join — otherwise the value under `join:`. It's never the join's `label`. - **`field_name`** is the YAML key for the dimension or metric — not the label. -If you're not sure, hover the field in the Lightdash sidebar — the field id appears in the URL when the field is added to a query (e.g. `dimensions=["orders_status"]` becomes `"orders.status"` for the `contains` check). +If you're not sure, hover a field in the Lightdash sidebar — the tooltip shows the underlying YAML name and the table it belongs to. Combine them as `{table}.{field}` (with a dot, not the underscore that appears in URLs and CSS ids). ## Things to know - **`else` is safe by default.** If the field id you reference doesn't exist in the explore, the check returns false and the `else` branch fires. A typo in the field name will not throw an error. +- **Date dimensions are expanded into per-interval field ids.** A column like `event_date` with time intervals enabled becomes `event_date_day`, `event_date_week`, `event_date_month`, etc. — each is its own id. `ld.query.filters contains "events.event_date"` will not match a filter on `events.event_date_day`. Use `or` to match every interval you care about, or check the specific one you expect. - **Both checks see the full query.** The introspection covers every dimension, metric, and filter in the query — not just the field you're branching from. - **Combine with parameters.** Liquid blocks can mix `ld.query.*` checks with `ld.parameters.*` checks in the same template. Both are resolved before the SQL leaves Lightdash. - **No effect on existing SQL.** If a field's `sql:` doesn't contain a Liquid block, nothing changes — the renderer skips it entirely. Adopting query introspection on one field doesn't affect any others. diff --git a/images/guides/developer/query-introspection-custom-dimension.png b/images/guides/developer/query-introspection-custom-dimension.png new file mode 100644 index 0000000000000000000000000000000000000000..2ed8be91a1ea492323d2a9ecefe6c2cf0d06e84d GIT binary patch literal 51732 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

(vFZFK%e5So4YC`dfgr;^zP=F#M?Ahd-8 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 literal 0 HcmV?d00001