Skip to content

Commit 5348b5d

Browse files
dbt snowflake/quote columns when altering (#1176)
1 parent c60673b commit 5348b5d

File tree

3 files changed

+132
-2
lines changed

3 files changed

+132
-2
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: Fixes
2+
body: quote columns when altering tables for incremental materialization
3+
time: 2025-06-26T16:12:48.423782-07:00
4+
custom:
5+
Author: skadyan colin-rogers-dbt
6+
Issue: "695"

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@
170170
{% set sql -%}
171171
alter {{ relation.get_ddl_prefix_for_alter() }} {{ relation_type }} {{ relation.render() }} add column
172172
{% for column in add_columns %}
173-
{{ column.name }} {{ column.data_type }}{{ ',' if not loop.last }}
173+
{{ adapter.quote(column.name) }} {{ column.data_type }}{{ ',' if not loop.last }}
174174
{% endfor %}
175175
{%- endset -%}
176176

@@ -183,7 +183,7 @@
183183
{% set sql -%}
184184
alter {{ relation.get_ddl_prefix_for_alter() }} {{ relation_type }} {{ relation.render() }} drop column
185185
{% for column in remove_columns %}
186-
{{ column.name }}{{ ',' if not loop.last }}
186+
{{ adapter.quote(column.name) }}{{ ',' if not loop.last }}
187187
{% endfor %}
188188
{%- endset -%}
189189

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,131 @@
11
from dbt.tests.adapter.incremental.test_incremental_on_schema_change import (
22
BaseIncrementalOnSchemaChange,
3+
BaseIncrementalOnSchemaChangeSetup,
34
)
5+
from dbt.tests.util import run_dbt
6+
import pytest
47

58

69
class TestIncrementalOnSchemaChange(BaseIncrementalOnSchemaChange):
710
pass
11+
12+
13+
# New fixtures for testing column names with spaces and special characters
14+
_MODEL_A_SPECIAL_COLUMNS = """
15+
{{
16+
config(materialized='table')
17+
}}
18+
19+
with source_data as (
20+
21+
select 1 as id, 'aaa' as "field with space", 'bbb' as "field-with-dash", 111 as "field@special", 'TTT' as "field.with.dots"
22+
union all select 2 as id, 'ccc' as "field with space", 'ddd' as "field-with-dash", 222 as "field@special", 'UUU' as "field.with.dots"
23+
union all select 3 as id, 'eee' as "field with space", 'fff' as "field-with-dash", 333 as "field@special", 'VVV' as "field.with.dots"
24+
union all select 4 as id, 'ggg' as "field with space", 'hhh' as "field-with-dash", 444 as "field@special", 'WWW' as "field.with.dots"
25+
union all select 5 as id, 'iii' as "field with space", 'jjj' as "field-with-dash", 555 as "field@special", 'XXX' as "field.with.dots"
26+
union all select 6 as id, 'kkk' as "field with space", 'lll' as "field-with-dash", 666 as "field@special", 'YYY' as "field.with.dots"
27+
28+
)
29+
30+
select id
31+
,"field with space"
32+
,"field-with-dash"
33+
,"field@special"
34+
,"field.with.dots"
35+
36+
from source_data
37+
"""
38+
39+
_MODEL_INCREMENTAL_APPEND_NEW_COLUMNS_SPECIAL = """
40+
{{
41+
config(
42+
materialized='incremental',
43+
unique_key='id',
44+
on_schema_change='append_new_columns'
45+
)
46+
}}
47+
48+
WITH source_data AS (SELECT * FROM {{ ref('model_a_special_columns') }} )
49+
50+
{% if is_incremental() %}
51+
52+
SELECT id,
53+
"field with space",
54+
"field-with-dash",
55+
"field@special",
56+
"field.with.dots"
57+
FROM source_data WHERE id NOT IN (SELECT id from {{ this }} )
58+
59+
{% else %}
60+
61+
SELECT id,
62+
"field with space",
63+
"field-with-dash"
64+
FROM source_data where id <= 3
65+
66+
{% endif %}
67+
"""
68+
69+
_MODEL_INCREMENTAL_APPEND_NEW_COLUMNS_SPECIAL_TARGET = """
70+
{{
71+
config(materialized='table')
72+
}}
73+
74+
with source_data as (
75+
76+
select * from {{ ref('model_a_special_columns') }}
77+
78+
)
79+
80+
select id
81+
,"field with space"
82+
,"field-with-dash"
83+
,CASE WHEN id <= 3 THEN NULL ELSE "field@special" END AS "field@special"
84+
,CASE WHEN id <= 3 THEN NULL ELSE "field.with.dots" END AS "field.with.dots"
85+
86+
from source_data
87+
"""
88+
89+
90+
class TestIncrementalOnSchemaChangeSpecialColumns(BaseIncrementalOnSchemaChangeSetup):
91+
"""Test incremental models with on_schema_change when column names contain spaces and special characters"""
92+
93+
@pytest.fixture(scope="class")
94+
def models(self):
95+
return {
96+
"model_a_special_columns.sql": _MODEL_A_SPECIAL_COLUMNS,
97+
"incremental_append_new_columns_special.sql": _MODEL_INCREMENTAL_APPEND_NEW_COLUMNS_SPECIAL,
98+
"incremental_append_new_columns_special_target.sql": _MODEL_INCREMENTAL_APPEND_NEW_COLUMNS_SPECIAL_TARGET,
99+
}
100+
101+
def test_incremental_append_new_columns_with_special_characters(self, project):
102+
"""Test that incremental models with on_schema_change='append_new_columns' work correctly with column names containing spaces and special characters"""
103+
104+
# First run - creates initial table with id, "field with space", "field-with-dash"
105+
run_dbt(
106+
[
107+
"run",
108+
"--models",
109+
"model_a_special_columns incremental_append_new_columns_special incremental_append_new_columns_special_target",
110+
]
111+
)
112+
113+
# Second run - should append new columns "field@special" and "field.with.dots"
114+
run_dbt(
115+
[
116+
"run",
117+
"--models",
118+
"model_a_special_columns incremental_append_new_columns_special incremental_append_new_columns_special_target",
119+
]
120+
)
121+
122+
# Verify that the incremental model matches the target
123+
from dbt.tests.util import check_relations_equal
124+
125+
check_relations_equal(
126+
project.adapter,
127+
[
128+
"incremental_append_new_columns_special",
129+
"incremental_append_new_columns_special_target",
130+
],
131+
)

0 commit comments

Comments
 (0)