Skip to content

feat(snowflake): add interactive table materialization support - #1798

Closed
jimmyxie-figma wants to merge 16 commits into
dbt-labs:mainfrom
jimmyxie-figma:rxie/snowflake-interactive-table-support
Closed

feat(snowflake): add interactive table materialization support#1798
jimmyxie-figma wants to merge 16 commits into
dbt-labs:mainfrom
jimmyxie-figma:rxie/snowflake-interactive-table-support

Conversation

@jimmyxie-figma

@jimmyxie-figma jimmyxie-figma commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

Add support for Snowflake Interactive Tables as a new materialization type (materialized='interactive_table'), addressing the GA of Snowflake's interactive analytics feature.

Interactive tables are optimized for low-latency, high-concurrency queries when used with interactive warehouses. They support both static (one-time populate) and dynamic (auto-refresh via TARGET_LAG) variants.

Key changes:

  • New InteractiveTable relation type and config dataclass
  • CREATE/REPLACE/DROP SQL macros for interactive table DDL
  • Materialization macro with create/replace/no-op routing
  • Detection via is_interactive column in SHOW OBJECTS/TABLES
  • Catalog integration for dbt docs
  • 20 unit tests for config parsing and changeset detection

Since Snowflake has no ALTER INTERACTIVE TABLE, all config changes require CREATE OR REPLACE (full refresh).

Refs: #1780
Made-with: Cursor

resolves #1780
docs dbt-labs/docs.getdbt.com/#

Problem

Solution

Checklist

  • I have read the contributing guide and understand what's expected of me
  • I have run this code in development and it appears to resolve the stated issue
  • This PR includes tests, or tests are not required/relevant for this PR
  • This PR has no interface changes (e.g. macros, cli, logs, json artifacts, config files, adapter interface, etc) or this PR has already received feedback and approval from Product or DX

Add support for Snowflake Interactive Tables as a new materialization
type (`materialized='interactive_table'`), addressing the GA of
Snowflake's interactive analytics feature.

Interactive tables are optimized for low-latency, high-concurrency
queries when used with interactive warehouses. They support both static
(one-time populate) and dynamic (auto-refresh via TARGET_LAG) variants.

Key changes:
- New `InteractiveTable` relation type and config dataclass
- CREATE/REPLACE/DROP SQL macros for interactive table DDL
- Materialization macro with create/replace/no-op routing
- Detection via `is_interactive` column in SHOW OBJECTS/TABLES
- Catalog integration for `dbt docs`
- 20 unit tests for config parsing and changeset detection

Since Snowflake has no ALTER INTERACTIVE TABLE, all config changes
require CREATE OR REPLACE (full refresh).

Refs: dbt-labs#1780
Made-with: Cursor
@jimmyxie-figma
jimmyxie-figma requested a review from a team as a code owner March 23, 2026 17:05
@cla-bot

cla-bot Bot commented Mar 23, 2026

Copy link
Copy Markdown

Thanks for your pull request, and welcome to our community! We require contributors to sign our Contributor License Agreement and we don't seem to have your signature on file. Check out this article for more information on why we have a CLA.

In order for us to review and merge your code, please submit the Individual Contributor License Agreement form attached above above. If you have questions about the CLA, or if you believe you've received this message in error, please reach out through a comment on this PR.

CLA has not been signed by users: @jimmyxie-figma

The is_dynamic check in _parse_list_relations_result only matched 'Y',
while the adjacent is_interactive and is_iceberg checks accepted both
'Y' and 'YES'. This inconsistency could cause dynamic tables to be
misidentified as regular tables if Snowflake returns 'YES'.

Made-with: Cursor
@cla-bot cla-bot Bot added the cla:yes The PR author has signed the CLA label Mar 23, 2026
The get_create_interactive_table_as_sql macro accepted sql as a
parameter but ignored it, using the compiled_code global instead.
This is fragile and inconsistent with the replace macro. Now passes
the sql parameter through to the inner macro.

Made-with: Cursor
1. describe_interactive_table: filter SHOW TABLES results to exact name
   match, since LIKE uses pattern matching and can return multiple rows.

2. target_lag removal detection: remove the `is not None` guard so that
   switching from dynamic to static (removing target_lag) is properly
   detected as a config change requiring CREATE OR REPLACE.

3. catalog.sql: remove is_interactive reference from information_schema
   query. Per Snowflake docs, is_interactive only exists in SHOW TABLES
   output (BCR-2165), not in information_schema.tables. The column
   reference would cause the catalog query to fail.

4. Remove unused Union import from interactive_table.py.

5. Always include 'text' in describe_interactive_table base_columns
   since parse_relation_results depends on it for the query field.

6. Add unit test for target_lag removal change detection.

Made-with: Cursor
In _parse_list_relations_result, the interactive table and dynamic table
type assignments used self.Relation.InteractiveTable/DynamicTable which
are classproperties returning plain str values. This created a type
inconsistency with the SnowflakeRelationType enum returned by
get_relation_type on line 345. Now uses SnowflakeRelationType enum
members directly, matching the Optional[SnowflakeRelationType] type
annotation on the relation's type field.

Made-with: Cursor

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Snowflake interactive_table materialization to dbt-snowflake, including relation/config plumbing, DDL macros, metadata detection for catalog/docs, and unit tests.

Changes:

  • Introduces SnowflakeRelationType.InteractiveTable plus interactive-table config parsing + changeset detection.
  • Adds interactive table DDL + materialization macros (create/replace/drop/describe) and wires them into generic relation macros.
  • Extends adapter metadata/caching to recognize interactive tables and adds unit tests + changelog entry.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
dbt-snowflake/tests/unit/test_renamed_relations.py Adds InteractiveTable to renameable relation types test.
dbt-snowflake/tests/unit/test_interactive_table_config.py New unit tests for config parsing/validation and changeset detection.
dbt-snowflake/tests/unit/test_alter_relation_comment_macro.py Extends mock relation to include is_interactive_table.
dbt-snowflake/src/dbt/include/snowflake/macros/relations/replace.sql Routes replace SQL generation for interactive tables.
dbt-snowflake/src/dbt/include/snowflake/macros/relations/interactive_table/replace.sql Implements CREATE OR REPLACE INTERACTIVE TABLE DDL macro.
dbt-snowflake/src/dbt/include/snowflake/macros/relations/interactive_table/rename.sql Adds rename macro for interactive tables.
dbt-snowflake/src/dbt/include/snowflake/macros/relations/interactive_table/drop.sql Adds drop macro for interactive tables.
dbt-snowflake/src/dbt/include/snowflake/macros/relations/interactive_table/describe.sql Adds describe macro calling adapter method.
dbt-snowflake/src/dbt/include/snowflake/macros/relations/interactive_table/create.sql Implements CREATE INTERACTIVE TABLE AS DDL macro.
dbt-snowflake/src/dbt/include/snowflake/macros/relations/drop.sql Routes drop SQL generation for interactive tables.
dbt-snowflake/src/dbt/include/snowflake/macros/relations/create.sql Routes create SQL generation for interactive tables.
dbt-snowflake/src/dbt/include/snowflake/macros/materializations/interactive_table.sql New interactive_table materialization with config-change behavior.
dbt-snowflake/src/dbt/include/snowflake/macros/adapters.sql Treats interactive tables like tables for comment/column comment macros.
dbt-snowflake/src/dbt/adapters/snowflake/relation.py Adds InteractiveTable type helpers and interactive config changeset detection.
dbt-snowflake/src/dbt/adapters/snowflake/relation_configs/policies.py Adds InteractiveTable enum member.
dbt-snowflake/src/dbt/adapters/snowflake/relation_configs/interactive_table.py New config dataclass + changeset types for interactive tables.
dbt-snowflake/src/dbt/adapters/snowflake/relation_configs/init.py Exports interactive-table config classes.
dbt-snowflake/src/dbt/adapters/snowflake/impl.py Adds interactive-table detection in listing/catalog + implements describe_interactive_table.
dbt-snowflake/.changes/unreleased/Features-20260323-100000.yaml Adds changelog entry for the new feature.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

{% if existing_relation.is_dynamic_table and target_relation.is_dynamic_table %}
{{ snowflake__get_replace_dynamic_table_sql(target_relation, sql) }}

{% elif target_relation.is_interactive_table %}

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

snowflake__get_replace_sql routes to the interactive-table replace DDL based only on target_relation.is_interactive_table. This means a type change (e.g., existing plain table/view -> interactive table) will also use CREATE OR REPLACE INTERACTIVE TABLE ... instead of the default replace flow, whereas dynamic tables only use the in-place CREATE OR REPLACE path when both existing and target are dynamic. To keep behavior consistent and avoid relying on cross-type replace semantics, gate this branch on existing_relation.is_interactive_table and target_relation.is_interactive_table and fall back to default__get_replace_sql otherwise.

Suggested change
{% elif target_relation.is_interactive_table %}
{% elif existing_relation.is_interactive_table and target_relation.is_interactive_table %}

Copilot uses AI. Check for mistakes.

@jimmyxie-figma jimmyxie-figma Mar 23, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dynamic table pattern requires both sides because it has ALTER support and needs to distinguish between replace DT with DT vs replace something else with DT. But interactive tables have no ALTER, so CREATE OR REPLACE INTERACTIVE TABLE is always the correct DDL regardless of the existing type.

Consider the scenario: existing is a view, target is an interactive table (user changed materialized from 'view' to 'interactive_table'). The materialization correctly calls get_replace_sql because not existing_relation.is_interactive_table is true.

Current code (only checks target): Routes to snowflake__get_replace_interactive_table_sql, which generates CREATE OR REPLACE INTERACTIVE TABLE .... This works -- Snowflake's CREATE OR REPLACE atomically drops the old object and creates the new one.

Copilot suggestion (checks both), The branch wouldn't match (existing view is not interactive), so it falls to default__get_replace_sql, which would generate standard CREATE OR REPLACE TABLE/VIEW DDL, not a valid CREATE OR REPLACE INTERACTIVE TABLE. The model would fail.

Comment thread dbt-snowflake/src/dbt/adapters/snowflake/impl.py Outdated
Comment thread dbt-snowflake/src/dbt/adapters/snowflake/impl.py
Comment on lines 320 to +352
columns = ["database_name", "schema_name", "name", "kind", "is_dynamic", "is_iceberg"]
schema_objects = schema_objects.rename(
column_names=[col.lower() for col in schema_objects.column_names]
)
return [self._parse_list_relations_result(obj) for obj in schema_objects.select(columns)]
available_columns = [c.lower() for c in schema_objects.column_names]
has_is_interactive = "is_interactive" in available_columns
if has_is_interactive:
columns.append("is_interactive")
return [
self._parse_list_relations_result(obj, has_is_interactive=has_is_interactive)
for obj in schema_objects.select(columns)
]

def _parse_list_relations_result(self, result: "agate.Row") -> SnowflakeRelation:
database, schema, identifier, relation_type, is_dynamic, is_iceberg = result
def _parse_list_relations_result(
self, result: "agate.Row", has_is_interactive: bool = False
) -> SnowflakeRelation:
if has_is_interactive:
database, schema, identifier, relation_type, is_dynamic, is_iceberg, is_interactive = (
result
)
else:
database, schema, identifier, relation_type, is_dynamic, is_iceberg = result
is_interactive = None

try:
relation_type = self.Relation.get_relation_type(relation_type.lower())
except ValueError:
relation_type = self.Relation.External

if relation_type == self.Relation.Table and is_dynamic == "Y":
relation_type = self.Relation.DynamicTable
if relation_type == self.Relation.Table and is_interactive in ("Y", "YES"):
relation_type = SnowflakeRelationType.InteractiveTable
elif relation_type == self.Relation.Table and is_dynamic in ("Y", "YES"):
relation_type = SnowflakeRelationType.DynamicTable

Copilot AI Mar 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

list_relations_without_caching() only looks for and selects an is_interactive column, and _parse_list_relations_result() only treats values in ("Y", "YES") as truthy. If Snowflake exposes interactive-table metadata under a different column name (e.g. is_adaptive per the referenced release notes) or as a boolean (true/false), interactive tables won't be detected correctly. Consider checking for alternate column names/representations and mapping them into a single is_interactive flag before parsing.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@colin-k-rogers

colin-k-rogers commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

@jimmyxie-figma thanks for the contribution! Take a look at Copilot's suggestions at first glance they're correct.

Also please run our code formatter via:
pre-commit run --show-diff-on-failure --color=always --all-files

jimmyxie-figma and others added 3 commits March 23, 2026 19:04
Refactor interactive flag detection to handle both `is_interactive` and
`is_adaptive` column names from Snowflake metadata. Fix mypy union-attr
error on nullable identifier by guarding with `or ""`. Add quoting-aware
identifier matching in describe_interactive_table. Add unit tests for the
new flag detection helpers.

Made-with: Cursor
…ined error

Annotate the relation_configs class variable with
ClassVar[Dict[str, Type[SnowflakeRelationConfigBase]]] so mypy
recognizes that dict values have from_relation_config().

Made-with: Cursor

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@sfc-gh-yostrinsky

Copy link
Copy Markdown
Contributor

@jimmyxie-figma There are a few references here to "is_adaptive" which is completely irrelevant. It's actually a warehouse indicator and not a table indicator. They should be removed.

… table indicator

Simplify interactive table detection to only check the is_interactive
column. Remove _INTERACTIVE_TABLE_COLUMN_NAMES, _TRUTHY_FLAG_VALUES,
_is_interactive_flag(), _get_interactive_flag() helpers and their tests.

Made-with: Cursor
…n_results

Interactive tables always require cluster_by. If Snowflake metadata
returns an empty or sentinel value, raise a CompilationError rather
than silently setting cluster_by to None, which would violate the
str type annotation on the dataclass field.

Made-with: Cursor
@sfc-gh-yostrinsky

Copy link
Copy Markdown
Contributor

LGTM

@colin-k-rogers

Copy link
Copy Markdown
Contributor

Will this work with dbt docs generate? We probably need macro updates to catalog macros like here:

when is_dynamic = 'YES' and table_type = 'BASE TABLE' THEN 'DYNAMIC TABLE'

@jimmyxie-figma

Copy link
Copy Markdown
Contributor Author

Will this work with dbt docs generate? We probably need macro updates to catalog macros like here:

when is_dynamic = 'YES' and table_type = 'BASE TABLE' THEN 'DYNAMIC TABLE'

No, this won’t work with dbt docs generate. The issue is that Snowflake’s information_schema.tables view reports interactive tables, like hybrid tables, as BASE TABLE in TABLE_TYPE. There isn’t an IS_INTERACTIVE or IS_HYBRID field there that dbt could use to tell them apart. Since dbt docs generate relies on the catalog macro and that macro queries information_schema.tables.

The only reliable way to identify interactive tables today is through SHOW TABLES or SHOW OBJECTS, which expose an is_interactive field. But using that in catalog generation would add a lot of complexity, either by requiring per-table lookups or by stitching together SHOW output with information_schema.columns. That feels like too much complexity for a pretty narrow edge case, especially since hybrid tables already have the same limitation today.

So if we want docs support here, we’d probably need catalog macro changes like the ones you linked. And if Snowflake ever adds IS_INTERACTIVE to information_schema.tables, the fix on the dbt side would be straightforward.

@sfc-gh-kasher

Copy link
Copy Markdown

Hey @colin-rogers-dbt, is having that column a blocker? Or can this be taken as a follow up? I can check with the team to see if this can be added. But in the mean time, can we unblock this PR if that works?

@sfc-gh-kasher

Copy link
Copy Markdown

Hey @colin-rogers-dbt, any luck getting to this?

@colin-k-rogers

Copy link
Copy Markdown
Contributor

While I wouldn't consider dbt docs an edge case ( it's a very popular command) I do think it can be taken as a fast follow in a separate PR.

@sfc-gh-kasher I think we can proceed with this in the short term as a known, if serious, limitation but we'll want to address prior to release. Adding to information_schema.tables would be ideal as @jimmyxie-figma is correct that the available workarounds are going to be less performant and hacky.

@colin-k-rogers

Copy link
Copy Markdown
Contributor

@jimmyxie-figma sorry should have caught this earlier but can you add some functional tests here?

Specifically adding an interactive table test case here:

@sfc-gh-kasher

sfc-gh-kasher commented Apr 15, 2026

Copy link
Copy Markdown

I do think it can be taken as a fast follow in a separate PR.

I'll work with the team to get this added soon. Thanks for the flexibility. Let's get this out and we can do this as a fast follow as you mentioned.

I think we can proceed with this in the short term as a known, if serious, limitation but we'll want to address prior to release.

@colin-rogers-dbt, just to confirm, are you open to releasing this with the current version with the known limitation while we work internally to get this support for information_schema.tables? I have already started those conversation so I am hoping to make progress on that pretty soon.

@colin-k-rogers

Copy link
Copy Markdown
Contributor

I do think it can be taken as a fast follow in a separate PR.

I'll work with the team to get this added soon. Thanks for the flexibility. Let's get this out and we can do this as a fast follow as you mentioned.

I think we can proceed with this in the short term as a known, if serious, limitation but we'll want to address prior to release.

@colin-rogers-dbt, just to confirm, are you open to releasing this with the current version with the known limitation while we work internally to get this support for information_schema.tables? I have already started those conversation so I am hoping to make progress on that pretty soon.

yes, I think that should be fine in the short term.

@sfc-gh-kasher

Copy link
Copy Markdown

Thanks @colin-rogers-dbt, can you review the PR in that case? If you're not the right person, can you get this reviewed by the team?

@colin-k-rogers

Copy link
Copy Markdown
Contributor

@jimmyxie-figma sorry should have caught this earlier but can you add some functional tests here?

@sfc-gh-kasher was waiting on this comment but it might have gotten lost in the shuffle of our other convo.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

dbt-snowflake/src/dbt/include/snowflake/macros/adapters.sql:118

  • snowflake__alter_column_comment now treats interactive tables as table (same as dynamic tables), but there’s no unit test coverage validating this new branch. Consider adding a macro test that sets relation.is_interactive_table = True and asserts the generated alter table ... alter ... SQL uses the correct relation type/prefix.
{% macro snowflake__alter_column_comment(relation, column_dict) -%}
    {% set existing_columns = adapter.get_columns_in_relation(relation) | map(attribute="name") | list %}
    {% if relation.is_dynamic_table or relation.is_interactive_table -%}
        {% set relation_type = "table" %}
    {% else -%}
        {% set relation_type = relation.type %}
    {% endif %}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 95 to 101
{% macro snowflake__alter_relation_comment(relation, relation_comment) -%}
{%- if relation.is_dynamic_table -%}
{%- set relation_type = 'dynamic table' -%}
{%- elif relation.is_interactive_table -%}
{%- set relation_type = 'table' -%}
{%- else -%}
{%- set relation_type = relation.type -%}

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new interactive-table branch in snowflake__alter_relation_comment isn’t covered by the existing macro unit tests (this file has tests for regular/dynamic/iceberg paths only). Add a test case with relation.is_interactive_table = True to assert the expected comment on table ... SQL so the new conditional path is exercised and guarded against regressions.

Copilot uses AI. Check for mistakes.
@sfc-gh-kasher

sfc-gh-kasher commented Apr 23, 2026

Copy link
Copy Markdown

@jimmyxie-figma sorry should have caught this earlier but can you add some functional tests here?
@sfc-gh-kasher was waiting on this comment but it might have gotten lost in the shuffle of our other convo.

Hey @jimmyxie-figma, did you get a chance to check the above? Is there anything more that we need to add?

@colin-rogers-dbt, what would be the next steps? Do we need those tests?

@colin-k-rogers

Copy link
Copy Markdown
Contributor

Ran the functional tests I added in jimmyxie-figma#1 against a real Snowflake account. 5/10 pass, 5/10 fail — all failures share the same root cause, which looks like a real bug in this PR:

Failure

On the second dbt run for an interactive_table model, adapter.describe_interactive_table raises:

tuple.index(x): x not in tuple

Root cause

In dbt-snowflake/src/dbt/adapters/snowflake/impl.py (≈ line 706), describe_interactive_table does:

base_columns = ["name", "schema_name", "database_name", "text", "cluster_by"]
...
selected = exact_match.select(base_columns)

But SHOW TABLES doesn't return text, schema_name, or database_name columns — those come from SHOW DYNAMIC TABLES. agate.Table.select on missing columns throws tuple.index.

Similarly, parse_relation_results reads interactive_table.get("schema_name" / "database_name" / "text"), which will all be None.

Impact

Any interactive_table model succeeds on first run, then fails on every subsequent run (config-change detection, no-op, on_configuration_change=apply|continue|fail, and even repeated runs with no changes).

What passes

All first-run paths:

  • static create, dynamic create, missing-cluster_by compile error, missing-snowflake_warehouse compile error, --full-refresh replace.

What fails

All second-run paths:

  • test_cluster_by_change_triggers_replace
  • test_target_lag_change_triggers_replace
  • test_continue_skips_rebuild
  • test_fail_raises_on_config_change
  • test_noop_run_does_not_replace

Happy to help patch describe_interactive_table (use SHOW TABLES columns that actually exist, or switch to a different metadata source for the query text) if useful.

@sfc-gh-kasher

Copy link
Copy Markdown

Happy to help patch describe_interactive_table (use SHOW TABLES columns that actually exist, or switch to a different metadata source for the query text) if useful.

Thanks @colin-rogers-dbt, that would be super helpful if you can fix that.

@sriramr98

Copy link
Copy Markdown
Contributor

Hey @jimmyxie-figma . I looked at the code and it looks like there's one more issue wrt the the SHOW TABLES query in describe_interactive_table

Problem

The function describe_interactive_table  uses SHOW TABLES LIKE '...'  which doesn't return target_lag or warehouse. So config-change detection was broken: a no-op rerun of a dynamic interactive table would always look like "target_lag changed from None → '2 minutes'" and trigger a CREATE OR REPLACE.

Assessment

Snowflake doesn't expose target_lag and warehouse for interactive tables through any tabular documented metadata view that I can find. The realistic options are:

  1. Parse GET_DDL with regex — documented function, predictable output, but regex parsing of DDL is fragile and can break if Snowflake changes the rendering.
  2. Use undocumented SHOW INTERACTIVE TABLES — clean tabular result, but depending on undocumented surface is a maintenance risk.
  3. Drop target_lag / warehouse from change detection — only detect cluster_by changes. This breaks test_target_lag_change_triggers_replace, and the no-op test for dynamic interactive tables would always false-positive. So this isn't really viable as-is — it would require also redesigning the test expectations and the user contract (e.g. "to change target_lag, run with --full-refresh").
  4. Don't detect any config changes for interactive tables. Always require --full-refresh to alter them. Simple, honest, no parsing. But the PR's tests are explicitly built around config-change detection, so this is a feature reduction.

Solution

Until we're able to get target_lag  and warehouse through a metadata query, the only option we have is to always require --full-refresh to alter these interactive tables.

@itsnamangoyal

Copy link
Copy Markdown
Contributor

Hey @jimmyxie-figma - picked this up to validate against a Snowflake account now that SHOW INTERACTIVE TABLES is GA and documented (docs). The change-detection issue @sriramr98 called out is fixable now, but a few additional things turned up while testing. Here's what needs to change:

1 - describe_interactive_table in dbt-snowflake/src/dbt/adapters/snowflake/impl.py — switch to SHOW INTERACTIVE TABLES

SHOW TABLES returns neither target_lag nor warehouse for interactive tables, and it also lacks schema_name, database_name, and text. SHOW INTERACTIVE TABLES returns all of them (verified against a live account):

show_sql = f"show interactive tables like '{relation.identifier}' in schema {database}.{schema}"

2 - Column name is refresh_warehouse, not warehouse

SHOW INTERACTIVE TABLES exposes the refresh warehouse as refresh_warehouse. Two spots to update:

impl.py ~L702: if "refresh_warehouse" in available_columns: base_columns.append("refresh_warehouse")
relation_configs/interactive_table.py L111: interactive_table.get("refresh_warehouse")

3 - cluster_by is returned wrapped in parens — needs normalization

Snowflake stores cluster_by='id' as '(id)' in the metadata output. Without stripping, every re-run sees 'id' != '(id)' and triggers a spurious CREATE OR REPLACE. In parse_relation_results:

cluster_by_val = str(cluster_by_raw).strip()
if cluster_by_val.startswith("(") and cluster_by_val.endswith(")"):
cluster_by_val = cluster_by_val[1:-1].strip()

4 - Functional tests

@colin-rogers-dbt already wrote a functional test suite in jimmyxie-figma#1. I ran it against a real Snowflake account on top of the fixes above — all 10 tests pass.

Out of scope but worth noting: interactive tables are most useful when attached to an interactive warehouse via ALTER WAREHOUSE … ADD TABLES (…). The current materialization doesn't do this, so users get an interactive table without the low-latency cache benefits. Suggest tracking that as a follow-up PR with a dedicated interactive_warehouse config and its own functional test.

@sfc-gh-kasher

Copy link
Copy Markdown

Hey @jimmyxie-figma, would you be able to help with the above pointers?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:approve-public-fork-ci cla:yes The PR author has signed the CLA

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Snowflake Interactive Table support

7 participants