Skip to content

Commit 70dbd4b

Browse files
haritamarclaude
andcommitted
fix: resolve Fabric Warehouse compatibility issues found in local testing
- Cast datetime2 to explicit precision (6) to avoid unsupported datetime2(7) - Cast sysutcdatetime()/getdate() to datetime2(6) in current_timestamp macros - Rewrite fabric__insert_as_select to use temp view pattern (Fabric rejects INSERT...EXEC) - Replace CONCAT() with + operator in full_names macros to avoid nvarchar return type - Cast PARSENAME results to varchar in fabric__full_name_split - Cast datename() result to varchar in fabric__edr_day_of_week_expression - Add fabric__generate_surrogate_key using + operator instead of dbt.concat() - Add fabric__schema_change_description_column with varchar cast - Add fabric__edr_list_schemas and fabric__edr_schema_exists using sys.schemas Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e17d7eb commit 70dbd4b

9 files changed

Lines changed: 129 additions & 54 deletions

File tree

integration_tests/dbt_project/macros/schema_utils/list_schemas.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@
3333
{% do return(schemas) %}
3434
{% endmacro %}
3535
36+
{% macro fabric__edr_list_schemas(database) %}
37+
{# Fabric does not support information_schema.schemata; use sys.schemas instead #}
38+
{% set results = run_query("SELECT name FROM sys.schemas") %}
39+
{% set schemas = [] %}
40+
{% for row in results %} {% do schemas.append(row[0]) %} {% endfor %}
41+
{% do return(schemas) %}
42+
{% endmacro %}
43+
3644
{% macro clickhouse__edr_list_schemas(database) %}
3745
{% set results = run_query("SHOW DATABASES") %}
3846
{% set schemas = [] %}

integration_tests/dbt_project/macros/schema_utils/schema_exists.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@
3939
{% do return(result | length > 0) %}
4040
{% endmacro %}
4141
42+
{% macro fabric__edr_schema_exists(database, schema_name) %}
43+
{% set safe_schema = schema_name | replace("'", "''") %}
44+
{% set result = run_query(
45+
"SELECT name FROM sys.schemas WHERE lower(name) = lower('"
46+
~ safe_schema
47+
~ "')"
48+
) %}
49+
{% do return(result | length > 0) %}
50+
{% endmacro %}
51+
4252
{% macro clickhouse__edr_schema_exists(database, schema_name) %}
4353
{% set safe_schema = schema_name | replace("'", "''") %}
4454
{% set result = run_query(

macros/edr/data_monitoring/schema_changes/get_columns_changes_query.sql

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -183,37 +183,7 @@
183183
column_name,
184184
'schema_change' as test_type,
185185
change as test_sub_type,
186-
case
187-
when change = 'column_added'
188-
then
189-
{{
190-
dbt.concat(
191-
["'The column \"'", "column_name", "'\" was added'"]
192-
)
193-
}}
194-
when change = 'column_removed'
195-
then
196-
{{
197-
dbt.concat(
198-
["'The column \"'", "column_name", "'\" was removed'"]
199-
)
200-
}}
201-
when change = 'type_changed'
202-
then
203-
{{
204-
dbt.concat(
205-
[
206-
"'The type of \"'",
207-
"column_name",
208-
"'\" was changed from '",
209-
"pre_data_type",
210-
"' to '",
211-
"data_type",
212-
]
213-
)
214-
}}
215-
else null
216-
end as test_results_description
186+
{{ elementary.schema_change_description_column() }}
217187
from all_column_changes {{ elementary.schema_changes_query_group_by() }}
218188

219189
)
@@ -272,6 +242,62 @@
272242
group by full_table_name, change, column_name, data_type, pre_data_type, detected_at
273243
{% endmacro %}
274244

245+
{% macro schema_change_description_column() %}
246+
{{ return(adapter.dispatch("schema_change_description_column", "elementary")()) }}
247+
{% endmacro %}
248+
249+
{% macro default__schema_change_description_column() %}
250+
case
251+
when change = 'column_added'
252+
then {{ dbt.concat(["'The column \"'", "column_name", "'\" was added'"]) }}
253+
when change = 'column_removed'
254+
then {{ dbt.concat(["'The column \"'", "column_name", "'\" was removed'"]) }}
255+
when change = 'type_changed'
256+
then
257+
{{
258+
dbt.concat(
259+
[
260+
"'The type of \"'",
261+
"column_name",
262+
"'\" was changed from '",
263+
"pre_data_type",
264+
"' to '",
265+
"data_type",
266+
]
267+
)
268+
}}
269+
else null
270+
end as test_results_description
271+
{% endmacro %}
272+
273+
{% macro fabric__schema_change_description_column() %}
274+
{#- Fabric does not support nvarchar; CONCAT() returns nvarchar so we cast to varchar. -#}
275+
cast(
276+
case
277+
when change = 'column_added'
278+
then {{ dbt.concat(["'The column \"'", "column_name", "'\" was added'"]) }}
279+
when change = 'column_removed'
280+
then
281+
{{ dbt.concat(["'The column \"'", "column_name", "'\" was removed'"]) }}
282+
when change = 'type_changed'
283+
then
284+
{{
285+
dbt.concat(
286+
[
287+
"'The type of \"'",
288+
"column_name",
289+
"'\" was changed from '",
290+
"pre_data_type",
291+
"' to '",
292+
"data_type",
293+
]
294+
)
295+
}}
296+
else null
297+
end as varchar(4000)
298+
) as test_results_description
299+
{% endmacro %}
300+
275301
{% macro fabric__get_column_changes_from_baseline_cur(
276302
model_relation, full_table_name, model_baseline_relation
277303
) %}

macros/edr/system/system_utils/full_names.sql

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,14 @@
1414
{%- endmacro %}
1515

1616
{% macro fabric__full_table_name(alias) -%}
17+
{# Use + operator instead of concat() to avoid nvarchar return type #}
1718
{% if alias is defined %} {%- set alias_dot = alias ~ "." %} {% endif %}
1819
upper(
19-
concat(
20-
{{ alias_dot }}database_name,
21-
'.',
22-
{{ alias_dot }}schema_name,
23-
'.',
24-
{{ alias_dot }}table_name
25-
)
20+
cast({{ alias_dot }}database_name as varchar(256))
21+
+ '.'
22+
+ cast({{ alias_dot }}schema_name as varchar(256))
23+
+ '.'
24+
+ cast({{ alias_dot }}table_name as varchar(256))
2625
)
2726
{%- endmacro %}
2827

@@ -42,7 +41,7 @@
4241
{%- endmacro %}
4342

4443
{% macro fabric__full_schema_name() -%}
45-
upper(concat(database_name, '.', schema_name))
44+
upper(cast(database_name as varchar(256)) + '.' + cast(schema_name as varchar(256)))
4645
{%- endmacro %}
4746

4847
{% macro clickhouse__full_schema_name() -%}
@@ -63,7 +62,10 @@
6362

6463
{% macro fabric__full_column_name() -%}
6564
upper(
66-
concat(database_name, '.', schema_name, '.', table_name, '.', column_name)
65+
cast(database_name as varchar(256))
66+
+ '.' + cast(schema_name as varchar(256))
67+
+ '.' + cast(table_name as varchar(256))
68+
+ '.' + cast(column_name as varchar(256))
6769
)
6870
{%- endmacro %}
6971

@@ -103,13 +105,14 @@
103105

104106

105107
{% macro fabric__full_name_split(part_name) %}
106-
{# T-SQL: use PARSENAME which splits dotted names (parts numbered right-to-left) #}
108+
{# T-SQL: use PARSENAME which splits dotted names (parts numbered right-to-left).
109+
PARSENAME returns nvarchar which Fabric does not support, so cast to varchar. #}
107110
{%- if part_name == "database_name" -%} {%- set part_index = 3 -%}
108111
{%- elif part_name == "schema_name" -%} {%- set part_index = 2 -%}
109112
{%- elif part_name == "table_name" -%} {%- set part_index = 1 -%}
110113
{%- else -%} {{ return("") }}
111114
{%- endif -%}
112-
replace(parsename(full_table_name, {{ part_index }}), '"', '') as {{ part_name }}
115+
cast(replace(parsename(full_table_name, {{ part_index }}), '"', '') as varchar(256)) as {{ part_name }}
113116
{% endmacro %}
114117

115118
{% macro bigquery__full_name_split(part_name) %}

macros/utils/cross_db_utils/current_timestamp.sql

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,13 @@
8484
cast(current_timestamp at time zone 'UTC' as timestamp(6))
8585
{%- endmacro -%}
8686

87-
{% macro fabric__edr_current_timestamp() -%} getdate() {%- endmacro -%}
87+
{% macro fabric__edr_current_timestamp() -%}
88+
cast(getdate() as datetime2(6))
89+
{%- endmacro -%}
8890

89-
{% macro fabric__edr_current_timestamp_in_utc() -%} sysutcdatetime() {%- endmacro -%}
91+
{% macro fabric__edr_current_timestamp_in_utc() -%}
92+
cast(sysutcdatetime() as datetime2(6))
93+
{%- endmacro -%}
9094

9195
{% macro dremio__edr_current_timestamp() -%} current_timestamp() {%- endmacro -%}
9296

macros/utils/cross_db_utils/day_of_week.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
{% endmacro %}
6565

6666
{% macro fabric__edr_day_of_week_expression(date_expr) %}
67-
datename(weekday, {{ date_expr }})
67+
cast(datename(weekday, {{ date_expr }}) as varchar(30))
6868
{% endmacro %}
6969

7070
-- fmt: off

macros/utils/cross_db_utils/generate_surrogate_key.sql

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,27 @@
3838
{{ hash_macro(concat_macro(field_sqls)) }}
3939
{%- endmacro -%}
4040

41+
{%- macro fabric__generate_surrogate_key(fields) -%}
42+
{#- Fabric does not support nvarchar; dbt.concat() uses CONCAT() which returns
43+
nvarchar(4000). Use + operator with explicit varchar casts instead. -#}
44+
{% set hash_macro = dbt.hash or dbt_utils.hash %}
45+
{% set default_null_value = "" %}
46+
{%- set field_sqls = [] -%}
47+
{%- for field in fields -%}
48+
{%- do field_sqls.append(
49+
"coalesce(cast("
50+
~ field
51+
~ " as "
52+
~ elementary.edr_type_string()
53+
~ "), '"
54+
~ default_null_value
55+
~ "')"
56+
) -%}
57+
{%- if not loop.last %} {%- do field_sqls.append("'-'") -%} {%- endif -%}
58+
{%- endfor -%}
59+
{{ hash_macro(field_sqls | join(" + ")) }}
60+
{%- endmacro -%}
61+
4162
{%- macro clickhouse__generate_surrogate_key(fields) -%}
4263
{% set concat_macro = dbt.concat or dbt_utils.concat %}
4364
{% set hash_macro = dbt.hash or dbt_utils.hash %}

macros/utils/data_types/data_type.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,4 @@
143143

144144
{% macro dremio__edr_type_timestamp() %} timestamp {% endmacro %}
145145

146-
{% macro fabric__edr_type_timestamp() %} datetime2 {% endmacro %}
146+
{% macro fabric__edr_type_timestamp() %} datetime2(6) {% endmacro %}

macros/utils/table_operations/insert_as_select.sql

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,18 @@
2323
{% endmacro %}
2424

2525
{% macro fabric__insert_as_select(table_relation, select_query) %}
26-
{#- T-SQL does not allow CTEs after INSERT INTO (WITH is parsed as a
27-
table hint), and nested CTEs are also invalid.
28-
Use INSERT ... EXEC(sp_executesql ...) to execute the select_query
29-
as a nested batch whose result set feeds the INSERT. -#}
30-
{%- set escaped_query = select_query | replace("'", "''") -%}
26+
{#- Fabric does not support INSERT ... EXEC or CTEs after INSERT INTO.
27+
Wrap the select_query in a temp view, then INSERT ... SELECT from it.
28+
Fabric also forbids 3-part names in DROP VIEW, so use schema.identifier only. -#}
29+
{%- set tmp_view_name = (
30+
table_relation.schema ~ "." ~ table_relation.identifier ~ "__ins_vw"
31+
) -%}
3132
{%- set insert_query %}
32-
insert into {{ table_relation }}
33-
exec sp_executesql N'{{ escaped_query }}'
34-
{{ elementary.get_query_settings() }}
33+
IF OBJECT_ID('{{ tmp_view_name }}', 'V') IS NOT NULL DROP VIEW {{ tmp_view_name }};
34+
EXEC('CREATE VIEW {{ tmp_view_name }} AS {{ select_query | replace("'", "''") }}');
35+
INSERT INTO {{ table_relation }}
36+
SELECT * FROM {{ tmp_view_name }};
37+
DROP VIEW {{ tmp_view_name }};
3538
{%- endset %}
3639
{{ return(insert_query) }}
3740
{% endmacro %}

0 commit comments

Comments
 (0)