Skip to content

Commit 88c4ff1

Browse files
authored
Merge branch 'dbt-msft:master' into seed-logic-fix
2 parents 8014117 + 024e202 commit 88c4ff1

File tree

12 files changed

+450
-18
lines changed

12 files changed

+450
-18
lines changed

.github/workflows/integration-tests-sqlserver.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
DBT_TEST_USER_3: DBT_TEST_USER_3
3636
COLLATION: ${{ matrix.collation }}
3737
steps:
38-
- uses: actions/checkout@v3
38+
- uses: actions/checkout@v4
3939

4040
- name: Install dependencies
4141
run: pip install -r dev_requirements.txt

.github/workflows/publish-docker.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
packages: write
2121
steps:
2222
- name: Checkout
23-
uses: actions/checkout@v3
23+
uses: actions/checkout@v4
2424

2525
- name: Log in to the Container registry
2626
uses: docker/[email protected]
@@ -50,7 +50,7 @@ jobs:
5050
packages: write
5151
steps:
5252
- name: Checkout
53-
uses: actions/checkout@v3
53+
uses: actions/checkout@v4
5454

5555
- name: Log in to the Container registry
5656
uses: docker/[email protected]

.github/workflows/release-version.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
name: Release new version
1212
runs-on: ubuntu-latest
1313
steps:
14-
- uses: actions/checkout@v3
14+
- uses: actions/checkout@v4
1515

1616
- uses: actions/setup-python@v4
1717
with:

.github/workflows/unit-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
password: ${{ secrets.github_token }}
2929
steps:
3030

31-
- uses: actions/checkout@v3
31+
- uses: actions/checkout@v4
3232

3333
- name: Install dependencies
3434
run: pip install -r dev_requirements.txt

dbt/adapters/sqlserver/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version = "1.8.0"
1+
version = "1.8.0rc1"

dbt/include/sqlserver/macros/adapter/indexes.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
inner join sys.tables {{ information_schema_hints() }}
109109
on sys.indexes.object_id = sys.tables.object_id
110110
where sys.indexes.[name] is not null
111+
and SCHEMA_NAME(sys.tables.schema_id) = '{{ this.schema }}'
111112
and sys.tables.[name] = '{{ this.table }}'
112113
for xml path('')
113114
); exec sp_executesql @drop_remaining_indexes_last;

dbt/include/sqlserver/macros/materializations/models/incremental/incremental.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
{% set strategy_arg_dict = ({'target_relation': target_relation, 'temp_relation': temp_relation, 'unique_key': unique_key, 'dest_columns': dest_columns, 'incremental_predicates': incremental_predicates }) %}
6060
{% set build_sql = strategy_sql_macro_func(strategy_arg_dict) %}
6161

62+
{% do to_drop.append(temp_relation) %}
6263
{% endif %}
6364

6465
{% call statement("main") %}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{% macro sqlserver__get_test_sql(main_sql, fail_calc, warn_if, error_if, limit) -%}
2+
3+
-- Create target schema if it does not
4+
USE [{{ target.database }}];
5+
IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = '{{ target.schema }}')
6+
BEGIN
7+
EXEC('CREATE SCHEMA [{{ target.schema }}]')
8+
END
9+
10+
{% set with_statement_pattern = 'with .+ as\s*\(' %}
11+
{% set re = modules.re %}
12+
{% set is_match = re.search(with_statement_pattern, main_sql, re.IGNORECASE) %}
13+
14+
{% if is_match %}
15+
{% set testview %}
16+
[{{ target.schema }}.testview_{{ range(1300, 19000) | random }}]
17+
{% endset %}
18+
19+
{% set sql = main_sql.replace("'", "''")%}
20+
EXEC('create view {{testview}} as {{ sql }};')
21+
select
22+
{{ "top (" ~ limit ~ ')' if limit != none }}
23+
{{ fail_calc }} as failures,
24+
case when {{ fail_calc }} {{ warn_if }}
25+
then 'true' else 'false' end as should_warn,
26+
case when {{ fail_calc }} {{ error_if }}
27+
then 'true' else 'false' end as should_error
28+
from (
29+
select * from {{testview}}
30+
) dbt_internal_test;
31+
32+
EXEC('drop view {{testview}};')
33+
34+
{% else -%}
35+
select
36+
{{ "top (" ~ limit ~ ')' if limit != none }}
37+
{{ fail_calc }} as failures,
38+
case when {{ fail_calc }} {{ warn_if }}
39+
then 'true' else 'false' end as should_warn,
40+
case when {{ fail_calc }} {{ error_if }}
41+
then 'true' else 'false' end as should_error
42+
from (
43+
{{ main_sql }}
44+
) dbt_internal_test
45+
{%- endif -%}
46+
{%- endmacro %}

tests/functional/adapter/mssql/test_index.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@
5454
select * from {{ ref('raw_data') }}
5555
"""
5656

57+
drop_schema_model = """
58+
{{
59+
config({
60+
"materialized": 'table',
61+
"post-hook": [
62+
"{{ drop_all_indexes_on_table() }}",
63+
]
64+
})
65+
}}
66+
select * from {{ ref('raw_data') }}
67+
"""
68+
5769
base_validation = """
5870
with base_query AS (
5971
select i.[name] as index_name,
@@ -107,6 +119,21 @@
107119
"""
108120
)
109121

122+
other_index_count = (
123+
base_validation
124+
+ """
125+
SELECT
126+
*
127+
FROM
128+
base_query
129+
WHERE
130+
schema_name='{schema_name}'
131+
AND
132+
table_view='{schema_name}.{table_name}'
133+
134+
"""
135+
)
136+
110137

111138
class TestIndex:
112139
@pytest.fixture(scope="class")
@@ -143,3 +170,77 @@ def test_create_index(self, project):
143170
"Nonclustered unique index": 4,
144171
}
145172
assert schema_dict == expected
173+
174+
175+
class TestIndexDropsOnlySchema:
176+
@pytest.fixture(scope="class")
177+
def project_config_update(self):
178+
return {"name": "generic_tests"}
179+
180+
@pytest.fixture(scope="class")
181+
def seeds(self):
182+
return {
183+
"raw_data.csv": index_seed_csv,
184+
"schema.yml": index_schema_base_yml,
185+
}
186+
187+
@pytest.fixture(scope="class")
188+
def models(self):
189+
return {
190+
"index_model.sql": drop_schema_model,
191+
"index_ccs_model.sql": model_sql_ccs,
192+
"schema.yml": model_yml,
193+
}
194+
195+
def create_table_and_index_other_schema(self, project):
196+
_schema = project.test_schema + "other"
197+
create_sql = f"""
198+
USE [{project.database}];
199+
IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = '{_schema}')
200+
BEGIN
201+
EXEC('CREATE SCHEMA [{_schema}]')
202+
END
203+
"""
204+
205+
create_table = f"""
206+
CREATE TABLE {_schema}.index_model (
207+
IDCOL BIGINT
208+
)
209+
"""
210+
211+
create_index = f"""
212+
CREATE INDEX sample_schema ON {_schema}.index_model (IDCOL)
213+
"""
214+
with get_connection(project.adapter):
215+
project.adapter.execute(create_sql, fetch=True)
216+
project.adapter.execute(create_table)
217+
project.adapter.execute(create_index)
218+
219+
def drop_schema_artifacts(self, project):
220+
_schema = project.test_schema + "other"
221+
drop_index = f"DROP INDEX IF EXISTS sample_schema ON {_schema}.index_model"
222+
drop_table = f"DROP TABLE IF EXISTS {_schema}.index_model"
223+
drop_schema = f"DROP SCHEMA IF EXISTS {_schema}"
224+
225+
with get_connection(project.adapter):
226+
project.adapter.execute(drop_index, fetch=True)
227+
project.adapter.execute(drop_table)
228+
project.adapter.execute(drop_schema)
229+
230+
def validate_other_schema(self, project):
231+
with get_connection(project.adapter):
232+
result, table = project.adapter.execute(
233+
other_index_count.format(
234+
schema_name=project.test_schema + "other", table_name="index_model"
235+
),
236+
fetch=True,
237+
)
238+
239+
assert len(table.rows) == 1
240+
241+
def test_create_index(self, project):
242+
self.create_table_and_index_other_schema(project)
243+
run_dbt(["seed"])
244+
run_dbt(["run"])
245+
self.validate_other_schema(project)
246+
self.drop_schema_artifacts(project)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import pytest
2+
from dbt.tests.util import get_connection, run_dbt
3+
4+
model_sql = """
5+
SELECT 1 AS data
6+
"""
7+
8+
table_mat = """
9+
{{
10+
config({
11+
"materialized": 'table'
12+
})
13+
}}
14+
SELECT 1 AS data
15+
"""
16+
17+
view_mat = """
18+
{{
19+
config({
20+
"materialized": 'view'
21+
})
22+
}}
23+
SELECT 1 AS data
24+
"""
25+
26+
schema = """
27+
version: 2
28+
models:
29+
- name: mat_object
30+
"""
31+
32+
33+
class BaseTableView:
34+
def create_object(self, project, sql):
35+
with get_connection(project.adapter):
36+
project.adapter.execute(sql, fetch=True)
37+
38+
39+
class TestTabletoView(BaseTableView):
40+
"""Test if changing from a table object to a view object correctly replaces"""
41+
42+
@pytest.fixture(scope="class")
43+
def models(self):
44+
return {"mat_object.sql": view_mat, "schema.yml": schema}
45+
46+
def test_passes(self, project):
47+
self.create_object(
48+
project, f"SELECT * INTO {project.test_schema}.mat_object FROM ({model_sql}) t"
49+
)
50+
run_dbt(["run"])
51+
52+
53+
class TestViewtoTable(BaseTableView):
54+
"""Test if changing from a view object to a table object correctly replaces"""
55+
56+
@pytest.fixture(scope="class")
57+
def models(self):
58+
return {"mat_object.sql": table_mat, "schema.yml": schema}
59+
60+
def test_passes(self, project):
61+
self.create_object(project, f"CREATE VIEW {project.test_schema}.mat_object AS {model_sql}")
62+
run_dbt(["run"])

0 commit comments

Comments
 (0)