Skip to content

Commit c60673b

Browse files
dbt snowflake/fix get relations with quoted identifiers (#1169)
1 parent 4b3966e commit c60673b

File tree

3 files changed

+46
-3
lines changed

3 files changed

+46
-3
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: Fix adapter.get_relation to find quoted case-sensitive relations
3+
time: 2025-06-23T11:00:29.24436-07:00
4+
custom:
5+
Author: prashantpiyush colin-rogers-dbt
6+
Issue: "694"

dbt-snowflake/src/dbt/adapters/snowflake/impl.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,20 +122,37 @@ def _catalog_filter_table(
122122
return super()._catalog_filter_table(lowered, used_schemas)
123123

124124
def _make_match_kwargs(self, database, schema, identifier):
125+
# if any path part is already quoted then consider same casing but without quotes
125126
quoting = self.config.quoting
126-
if identifier is not None and quoting["identifier"] is False:
127+
if self._is_quoted(identifier):
128+
identifier = self._strip_quotes(identifier)
129+
elif identifier is not None and quoting["identifier"] is False:
127130
identifier = identifier.upper()
128131

129-
if schema is not None and quoting["schema"] is False:
132+
if self._is_quoted(schema):
133+
schema = self._strip_quotes(schema)
134+
elif schema is not None and quoting["schema"] is False:
130135
schema = schema.upper()
131136

132-
if database is not None and quoting["database"] is False:
137+
if self._is_quoted(database):
138+
database = self._strip_quotes(database)
139+
elif database is not None and quoting["database"] is False:
133140
database = database.upper()
134141

135142
return filter_null_values(
136143
{"identifier": identifier, "schema": schema, "database": database}
137144
)
138145

146+
def _is_quoted(self, identifier: str) -> bool:
147+
return (
148+
identifier is not None
149+
and identifier.startswith(self.Relation.quote_character)
150+
and identifier.endswith(self.Relation.quote_character)
151+
)
152+
153+
def _strip_quotes(self, identifier: str) -> str:
154+
return identifier.strip(self.Relation.quote_character)
155+
139156
def _get_warehouse(self) -> str:
140157
_, table = self.execute("select current_warehouse() as warehouse", fetch=True)
141158
if len(table) == 0 or len(table[0]) == 0:

dbt-snowflake/tests/unit/test_snowflake_adapter.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,26 @@ def test_authenticator_private_key_string_authentication_no_passphrase(
718718
]
719719
)
720720

721+
def test_get_relation_without_quotes(self):
722+
with mock.patch.object(self.adapter, "list_relations") as list_relations:
723+
list_relations.return_value = [
724+
SnowflakeAdapter.Relation.create(
725+
database="TEST_DATABASE", schema="test_schema", identifier="TEST_TABLE"
726+
)
727+
]
728+
relation = self.adapter.get_relation("test_database", "test_schema", "test_table")
729+
assert relation.render() == "TEST_DATABASE.test_schema.TEST_TABLE"
730+
731+
def test_get_relation_with_quotes(self):
732+
with mock.patch.object(self.adapter, "list_relations") as list_relations:
733+
list_relations.return_value = [
734+
SnowflakeAdapter.Relation.create(
735+
database="test_database", schema="test_schema", identifier="test_TABLE"
736+
)
737+
]
738+
relation = self.adapter.get_relation('"test_database"', "test_schema", '"test_TABLE"')
739+
assert relation.render() == "test_database.test_schema.test_TABLE"
740+
721741

722742
class TestSnowflakeAdapterConversions(TestAdapterConversions):
723743
def test_convert_text_type(self):

0 commit comments

Comments
 (0)