Skip to content

Commit 9caa591

Browse files
committed
Better quoting for relation names
- Removed hardcoding of quoting configurations from all macros. Config should be picked from dbt project config - Added 4 new test cases for relation names
1 parent c5595af commit 9caa591

File tree

6 files changed

+223
-18
lines changed

6 files changed

+223
-18
lines changed

dbt/include/oracle/macros/adapters.sql

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,9 @@
9494
{%- set sql_header = config.get('sql_header', none) -%}
9595

9696
{{ sql_header if sql_header is not none }}
97-
9897
create {% if temporary -%}
9998
global temporary
100-
{%- endif %} table {{ relation.include(schema=(not temporary)).quote(schema=False, identifier=False) }}
99+
{%- endif %} table {{ relation.include(schema=(not temporary)) }}
101100
{% if temporary -%} on commit preserve rows {%- endif %}
102101
as
103102
{{ sql }}
@@ -112,7 +111,7 @@
112111

113112
create {% if temporary -%}
114113
global temporary
115-
{%- endif %} table {{ relation.include(schema=(not temporary)).quote(schema=False, identifier=False) }}
114+
{%- endif %} table {{ relation.include(schema=(not temporary)) }}
116115
{% if temporary -%} on commit preserve rows {%- endif %}
117116
as
118117
{{ sql }}
@@ -122,7 +121,7 @@
122121
{%- set sql_header = config.get('sql_header', none) -%}
123122

124123
{{ sql_header if sql_header is not none }}
125-
create or replace view {{ relation.include(False, True, True).quote(schema=False, identifier=False) }} as
124+
create or replace view {{ relation }} as
126125
{{ sql }}
127126

128127
{% endmacro %}
@@ -205,7 +204,7 @@
205204
{% macro oracle__alter_relation_comment(relation, comment) %}
206205
{% set escaped_comment = oracle_escape_comment(comment) %}
207206
{# "comment on table" even for views #}
208-
comment on table {{ relation.include(False, True, True).quote(schema=False, identifier=False) }} is {{ escaped_comment }}
207+
comment on table {{ relation }} is {{ escaped_comment }}
209208
{% endmacro %}
210209

211210
{% macro oracle__persist_docs(relation, model, for_relation, for_columns) -%}
@@ -218,7 +217,7 @@
218217
{% set comment = column_dict[column_name]['description'] %}
219218
{% set escaped_comment = oracle_escape_comment(comment) %}
220219
{% call statement('alter _column comment', fetch_result=False) -%}
221-
comment on column {{ relation.include(False, True, True).quote(schema=False, identifier=False) }}.{{ column_name }} is {{ escaped_comment }}
220+
comment on column {{ relation }}.{{ column_name }} is {{ escaped_comment }}
222221
{%- endcall %}
223222
{% endfor %}
224223
{% endif %}
@@ -234,16 +233,16 @@
234233
{%- set tmp_column = column_name + "__dbt_alter" -%}
235234

236235
{% call statement('alter_column_type 1', fetch_result=False) %}
237-
alter table {{ relation.include(False, True, True).quote(schema=False, identifier=False) }} add {{ tmp_column }} {{ new_column_type }}
236+
alter table {{ relation }} add {{ tmp_column }} {{ new_column_type }}
238237
{% endcall %}
239238
{% call statement('alter_column_type 2', fetch_result=False) %}
240-
update {{ relation.include(False, True, True).quote(schema=False, identifier=False) }} set {{ tmp_column }} = {{ column_name }}
239+
update {{ relation }} set {{ tmp_column }} = {{ column_name }}
241240
{% endcall %}
242241
{% call statement('alter_column_type 3', fetch_result=False) %}
243-
alter table {{ relation.include(False, True, True).quote(schema=False, identifier=False) }} drop column {{ column_name }} cascade constraints
242+
alter table {{ relation }} drop column {{ column_name }} cascade constraints
244243
{% endcall %}
245244
{% call statement('alter_column_type 4', fetch_result=False) %}
246-
alter table {{ relation.include(False, True, True).quote(schema=False, identifier=False) }} rename column {{ tmp_column }} to {{ column_name }}
245+
alter table {{ relation }} rename column {{ tmp_column }} to {{ column_name }}
247246
{% endcall %}
248247

249248
{% endmacro %}
@@ -257,7 +256,7 @@
257256
pragma EXCEPTION_INIT(attempted_ddl_on_in_use_GTT, -14452);
258257
BEGIN
259258
SAVEPOINT start_transaction;
260-
EXECUTE IMMEDIATE 'DROP {{ relation.type }} {{ relation.include(False, True, True).quote(schema=False, identifier=False) }} cascade constraint';
259+
EXECUTE IMMEDIATE 'DROP {{ relation.type }} {{ relation }} cascade constraint';
261260
COMMIT;
262261
EXCEPTION
263262
WHEN attempted_ddl_on_in_use_GTT THEN
@@ -272,14 +271,14 @@
272271
{#-- To avoid `ORA-01702: a view is not appropriate here` we check that the relation to be truncated is a table #}
273272
{% if relation.is_table %}
274273
{% call statement('truncate_relation') -%}
275-
truncate table {{ relation.include(False, True, True).quote(schema=False, identifier=False) }}
274+
truncate table {{ relation }}
276275
{%- endcall %}
277276
{% endif %}
278277
{% endmacro %}
279278

280279
{% macro oracle__rename_relation(from_relation, to_relation) -%}
281280
{% call statement('rename_relation') -%}
282-
ALTER {{ from_relation.type }} {{ from_relation.include(False, True, True).quote(schema=False, identifier=False) }} rename to {{ to_relation.include(False, False, True).quote(schema=False, identifier=False) }}
281+
ALTER {{ from_relation.type }} {{ from_relation }} rename to {{ to_relation.include(schema=False) }}
283282
{%- endcall %}
284283
{% endmacro %}
285284

dbt/include/oracle/macros/materializations/snapshot/snapshot.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@
5151

5252
snapshotted_data as (
5353

54-
select {{ target_relation.quote(schema=False, identifier=False) }}.*,
54+
select {{ target_relation }}.*,
5555
{{ strategy.unique_key }} as dbt_unique_key
5656

57-
from {{ target_relation.quote(schema=False, identifier=False) }}
57+
from {{ target_relation }}
5858
where dbt_valid_to is null
5959

6060
),

dbt/include/oracle/macros/materializations/snapshot/snapshot_merge.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
{% do dest_cols_csv.append("d." + column) %}
2828
{% endfor %}
2929

30-
merge into {{ target.quote(schema=False, identifier=False) }} d
31-
using {{ source.quote(schema=False, identifier=False) }} s
30+
merge into {{ target }} d
31+
using {{ source }} s
3232
on (s.dbt_scd_id = d.dbt_scd_id)
3333

3434
when matched

dbt/include/oracle/macros/materializations/snapshot/strategies.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
{%- set target_table = node.get('alias', node.get('name')) -%}
8585

8686
{%- set target_relation = adapter.get_relation(database=node_database, schema=node.schema, identifier=target_table) -%}
87-
{%- set existing_cols = get_columns_in_query('select * from ' ~ target_relation.quote(schema=False, identifier=False)) -%}
87+
{%- set existing_cols = get_columns_in_query('select * from ' ~ target_relation) -%}
8888
{%- set ns = namespace() -%} {# handle for-loop scoping with a namespace #}
8989
{%- set ns.column_added = false -%}
9090

dbt/include/oracle/macros/materializations/table/table.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
{% set identifier = model['alias'] %}
1919
{% set tmp_identifier = model['name'] + '__dbt_tmp' %}
2020
{% set backup_identifier = model['name'] + '__dbt_backup' %}
21+
{{ log("SCHEMA __<>>>><<>>>>>>>>>>" ~ schema, info=True) }}
2122

2223
{% set old_relation = adapter.get_relation(database=database, schema=schema, identifier=identifier) %}
24+
{{ log("FOUND OLD RELATION __<>>>><<>>>>>>>>>>" ~ old_relation, info=True) }}
2325
{% set target_relation = api.Relation.create(identifier=identifier,
2426
schema=schema,
2527
database=database,
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
"""
2+
Copyright (c) 2022, Oracle and/or its affiliates.
3+
Copyright (c) 2020, Vitor Avancini
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
https://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
"""
17+
18+
import pytest
19+
20+
import datetime
21+
22+
from dbt.tests.util import run_dbt, relation_from_name
23+
24+
25+
# seeds/my_seed.csv
26+
seed_csv = """
27+
user_id,user_name,birth_date,income,last_login_date
28+
1,Easton,1981-05-20,40000,2022-04-25T08:57:59
29+
2,Lillian,1978-09-03,54000,2022-04-25T08:58:59
30+
3,Jeremiah,1982-03-11,10000,2022-04-25T09:57:59
31+
4,Nolan,1976-05-06,900000,2022-04-25T09:58:59
32+
""".lstrip()
33+
34+
# models/foo.sql
35+
my_model_foo_sql = """
36+
{{config(materialized='table',
37+
alias="foo")}}
38+
SELECT * FROM {{ ref('seed') }}
39+
"""
40+
41+
# models/foo2.sql
42+
my_model_foo2_sql = """
43+
{{config(materialized='table',
44+
alias="Foo")}}
45+
SELECT * FROM {{ ref('seed') }}
46+
"""
47+
48+
49+
class TestQuotedLowerCaseTableName:
50+
51+
@pytest.fixture(scope="class")
52+
def seeds(self):
53+
return {
54+
"seed.csv": seed_csv,
55+
}
56+
57+
@pytest.fixture(scope="class")
58+
def models(self):
59+
return {
60+
"my_model_foo.sql": my_model_foo_sql,
61+
}
62+
63+
@pytest.fixture(scope="class")
64+
def project_config_update(self):
65+
return {
66+
"quoting": {
67+
"database": False,
68+
"schema": False,
69+
"identifier": True
70+
},
71+
}
72+
73+
def test_run_dbt(self, project):
74+
"""
75+
- run seed
76+
- run model
77+
78+
"""
79+
results = run_dbt(['seed'])
80+
assert len(results) == 1
81+
82+
results = run_dbt(['run'])
83+
assert len(results) == 1
84+
85+
results = run_dbt(['run'])
86+
assert len(results) == 1
87+
88+
sql = 'SELECT COUNT(*) from "foo"'
89+
result = project.run_sql(sql, fetch="all")
90+
assert result == [(4,)]
91+
92+
93+
class TestQuotedTitleCaseTableName:
94+
95+
@pytest.fixture(scope="class")
96+
def seeds(self):
97+
return {
98+
"seed.csv": seed_csv,
99+
}
100+
101+
@pytest.fixture(scope="class")
102+
def models(self):
103+
return {
104+
"my_model_foo.sql": my_model_foo2_sql,
105+
}
106+
107+
@pytest.fixture(scope="class")
108+
def project_config_update(self):
109+
return {
110+
"quoting": {
111+
"database": False,
112+
"schema": False,
113+
"identifier": True
114+
},
115+
}
116+
117+
def test_run_dbt(self, project):
118+
"""
119+
- run seed
120+
- run model
121+
122+
"""
123+
results = run_dbt(['seed'])
124+
assert len(results) == 1
125+
126+
results = run_dbt(['run'])
127+
assert len(results) == 1
128+
129+
results = run_dbt(['run'])
130+
assert len(results) == 1
131+
132+
sql = 'SELECT COUNT(*) from "Foo"'
133+
result = project.run_sql(sql, fetch="all")
134+
assert result == [(4,)]
135+
136+
137+
class TestUnQuotedLowerCaseTableName:
138+
139+
@pytest.fixture(scope="class")
140+
def seeds(self):
141+
return {
142+
"seed.csv": seed_csv,
143+
}
144+
145+
@pytest.fixture(scope="class")
146+
def models(self):
147+
return {
148+
"my_model_foo.sql": my_model_foo_sql,
149+
}
150+
151+
def test_run_dbt(self, project):
152+
"""
153+
- run seed
154+
- run model
155+
156+
"""
157+
results = run_dbt(['seed'])
158+
assert len(results) == 1
159+
160+
results = run_dbt(['run'])
161+
assert len(results) == 1
162+
163+
results = run_dbt(['run'])
164+
assert len(results) == 1
165+
166+
sql = 'SELECT COUNT(*) from FOO'
167+
result = project.run_sql(sql, fetch="all")
168+
assert result == [(4,)]
169+
170+
171+
class TestUnQuotedTitleCaseTableName:
172+
173+
@pytest.fixture(scope="class")
174+
def seeds(self):
175+
return {
176+
"seed.csv": seed_csv,
177+
}
178+
179+
@pytest.fixture(scope="class")
180+
def models(self):
181+
return {
182+
"my_model_foo.sql": my_model_foo2_sql,
183+
}
184+
185+
def test_run_dbt(self, project):
186+
"""
187+
- run seed
188+
- run model
189+
190+
"""
191+
results = run_dbt(['seed'])
192+
assert len(results) == 1
193+
194+
results = run_dbt(['run'])
195+
assert len(results) == 1
196+
197+
results = run_dbt(['run'])
198+
assert len(results) == 1
199+
200+
sql = 'SELECT COUNT(*) from FOO'
201+
result = project.run_sql(sql, fetch="all")
202+
assert result == [(4,)]
203+
204+

0 commit comments

Comments
 (0)