Skip to content

Commit 26f7631

Browse files
authored
Merge pull request #36 from oracle/feature/quoting
Feature enhancement to support quoting for column names
2 parents 08185a5 + c87d912 commit 26f7631

25 files changed

+1401
-38
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Configuration variables
2-
VERSION=1.1.1
2+
VERSION=1.1.2rc1
33
PROJ_DIR?=$(shell pwd)
44
VENV_DIR?=${PROJ_DIR}/.bldenv
55
BUILD_DIR=${PROJ_DIR}/build

dbt/adapters/oracle/column.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020

2121
from dbt.adapters.base.column import Column
22+
from dbt.adapters.oracle.keyword_catalog import KEYWORDS
2223

2324

2425
@dataclass

dbt/adapters/oracle/impl.py

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
)
2020
from itertools import chain
2121

22+
import agate
23+
2224
import dbt.exceptions
2325
from dbt.adapters.base.relation import BaseRelation, InformationSchema
2426
from dbt.adapters.base.impl import GET_CATALOG_MACRO_NAME
@@ -28,12 +30,15 @@
2830
from dbt.adapters.oracle.column import OracleColumn
2931
from dbt.adapters.oracle.relation import OracleRelation
3032
from dbt.contracts.graph.manifest import Manifest
33+
from dbt.events import AdapterLogger
3134

3235
from dbt.exceptions import raise_compiler_error
3336
from dbt.utils import filter_null_values
3437

38+
from dbt.adapters.oracle.keyword_catalog import KEYWORDS
39+
40+
logger = AdapterLogger("oracle")
3541

36-
import agate
3742

3843
COLUMNS_EQUAL_SQL = '''
3944
with diff_count as (
@@ -232,13 +237,71 @@ def list_relations_without_caching(
232237
))
233238
return relations
234239

240+
@staticmethod
241+
def is_valid_identifier(identifier) -> bool:
242+
"""Returns True if an identifier is valid
243+
244+
An identifier is considered valid if the following conditions are True
245+
246+
1. First character is alphabetic
247+
2. Rest of the characters is either alphanumeric or any one of the literals '#', '$', '_'
248+
249+
"""
250+
# The first character should be alphabetic
251+
if not identifier[0].isalpha():
252+
return False
253+
# Rest of the characters is either alphanumeric or any one of the literals '#', '$', '_'
254+
idx = 1
255+
while idx < len(identifier):
256+
identifier_chr = identifier[idx]
257+
if not identifier_chr.isalnum() and identifier_chr not in ('#', '$', '_'):
258+
return False
259+
idx += 1
260+
return True
261+
262+
@available
263+
def should_identifier_be_quoted(self,
264+
identifier,
265+
models_column_dict=None) -> bool:
266+
"""Returns True if identifier should be quoted else False
267+
268+
An identifier should be quoted in the following 3 cases:
269+
270+
- 1. Identifier is an Oracle keyword
271+
272+
- 2. Identifier is not valid according to the following rules
273+
- First character is alphabetic
274+
- Rest of the characters is either alphanumeric or any one of the literals '#', '$', '_'
275+
276+
- 3. User has enabled quoting for the column in the model configuration
277+
278+
"""
279+
if identifier.upper() in KEYWORDS:
280+
return True
281+
elif not self.is_valid_identifier(identifier):
282+
return True
283+
elif models_column_dict and identifier in models_column_dict:
284+
return models_column_dict[identifier].get('quote', False)
285+
elif models_column_dict and self.quote(identifier) in models_column_dict:
286+
return models_column_dict[self.quote(identifier)].get('quote', False)
287+
return False
288+
289+
@available
290+
def check_and_quote_identifier(self, identifier, models_column_dict=None) -> str:
291+
if self.should_identifier_be_quoted(identifier, models_column_dict):
292+
return self.quote(identifier)
293+
else:
294+
return identifier
295+
235296
@available
236297
def quote_seed_column(
237298
self, column: str, quote_config: Optional[bool]
238299
) -> str:
239300
quote_columns: bool = False
240301
if isinstance(quote_config, bool):
241302
quote_columns = quote_config
303+
elif self.should_identifier_be_quoted(column):
304+
quote_columns = True
242305
elif quote_config is None:
243306
pass
244307
else:

0 commit comments

Comments
 (0)