Skip to content

Commit 360d473

Browse files
author
ci bot
committed
Merge branch 'chip/weird_table_name_handler' into 'enterprise'
Added ID_SEPARTOR to test queries to support non-standard schema and table names See merge request dkinternal/testgen/dataops-testgen!329
2 parents 5fdeeda + b5af463 commit 360d473

File tree

113 files changed

+789
-745
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+789
-745
lines changed

testgen/commands/queries/execute_cat_tests_query.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ class CATTestParams(TypedDict):
1717
class CCATExecutionSQL:
1818
project_code = ""
1919
flavor = ""
20-
concat_operator = ""
2120
test_suite = ""
2221
run_date = ""
2322
test_run_id = ""
@@ -35,8 +34,7 @@ def __init__(self, strProjectCode, strTestSuiteId, strTestSuite, strSQLFlavor, m
3534
self.test_suite_id = strTestSuiteId
3635
self.test_suite = strTestSuite
3736
self.project_code = strProjectCode
38-
flavor_service = get_flavor_service(strSQLFlavor)
39-
self.concat_operator = flavor_service.get_concat_operator()
37+
self.flavor_service = get_flavor_service(strSQLFlavor)
4038
self.flavor = strSQLFlavor
4139
self.max_query_chars = max_query_chars
4240
self.today = date_service.get_now_as_string_with_offset(minutes_offset)
@@ -58,9 +56,9 @@ def _get_query(self, template_file_name: str, sub_directory: str | None = "exec_
5856
"TEST_SUITE_ID": self.test_suite_id,
5957
"TABLE_GROUPS_ID": self.table_groups_id,
6058
"SQL_FLAVOR": self.flavor,
61-
"ID_SEPARATOR": "`" if self.flavor in ("databricks", "bigquery") else '"',
62-
"VARCHAR_TYPE": "STRING" if self.flavor == "bigquery" else "VARCHAR(1000)",
63-
"CONCAT_OPERATOR": self.concat_operator,
59+
"QUOTE": self.flavor_service.quote_character,
60+
"VARCHAR_TYPE": self.flavor_service.varchar_type,
61+
"CONCAT_OPERATOR": self.flavor_service.concat_operator,
6462
"SCHEMA_NAME": self.target_schema,
6563
"TABLE_NAME": self.target_table,
6664
"NOW_DATE": "GETDATE()",
@@ -74,7 +72,7 @@ def _get_query(self, template_file_name: str, sub_directory: str | None = "exec_
7472
query = replace_params(query, params)
7573
query = replace_templated_functions(query, self.flavor)
7674

77-
if no_bind and self.flavor != "databricks":
75+
if no_bind:
7876
# Adding escape character where ':' is referenced
7977
query = query.replace(":", "\\:")
8078

testgen/commands/queries/execute_tests_query.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from testgen.common import date_service, read_template_sql_file
44
from testgen.common.clean_sql import CleanSQL, ConcatColumnList, quote_identifiers
5-
from testgen.common.database.database_service import replace_params
5+
from testgen.common.database.database_service import get_flavor_service, replace_params
66

77

88
class TestParams(TypedDict):
@@ -55,6 +55,7 @@ class CTestExecutionSQL:
5555
def __init__(self, strProjectCode, strFlavor, strTestSuiteId, strTestSuite, minutes_offset=0):
5656
self.project_code = strProjectCode
5757
self.flavor = strFlavor
58+
self.flavor_service = get_flavor_service(strFlavor)
5859
self.test_suite_id = strTestSuiteId
5960
self.test_suite = strTestSuite
6061
self.today = date_service.get_now_as_string_with_offset(minutes_offset)
@@ -101,13 +102,14 @@ def _get_query(
101102
"TEST_SUITE_ID": self.test_suite_id,
102103
"TEST_SUITE": self.test_suite,
103104
"SQL_FLAVOR": self.flavor,
105+
"QUOTE": self.flavor_service.quote_character,
104106
"TEST_RUN_ID": self.test_run_id,
105107
"INPUT_PARAMETERS": self._get_input_parameters(),
106108
"RUN_DATE": self.run_date,
107109
"EXCEPTION_MESSAGE": self.exception_message,
108110
"START_TIME": self.today,
109111
"PROCESS_ID": self.process_id,
110-
"VARCHAR_TYPE": "STRING" if self.flavor in ("databricks", "bigquery") else "VARCHAR",
112+
"VARCHAR_TYPE": self.flavor_service.varchar_type,
111113
"NOW_TIMESTAMP": date_service.get_now_as_string_with_offset(self.minutes_offset),
112114
**{key.upper(): value or "" for key, value in self.test_params.items()},
113115
}
@@ -128,12 +130,12 @@ def _get_query(
128130

129131
subset_condition = self.test_params["subset_condition"]
130132
params["SUBSET_DISPLAY"] = subset_condition.replace(
131-
"'", r"\'" if self.flavor == "bigquery" else "''"
133+
"'", self.flavor_service.escaped_single_quote
132134
) if subset_condition else ""
133135

134136
query = replace_params(query, params)
135137

136-
if no_bind and self.flavor != "databricks":
138+
if no_bind:
137139
# Adding escape character where ':' is referenced
138140
query = query.replace(":", "\\:")
139141

testgen/commands/queries/generate_tests_query.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from typing import ClassVar, TypedDict
33

44
from testgen.common import CleanSQL, date_service, read_template_sql_file
5-
from testgen.common.database.database_service import replace_params
5+
from testgen.common.database.database_service import get_flavor_service, replace_params
66
from testgen.common.read_file import get_template_files
77

88
LOG = logging.getLogger("testgen")
@@ -29,7 +29,10 @@ class CDeriveTestsSQL:
2929

3030
_use_clean = False
3131

32-
def __init__(self):
32+
def __init__(self, flavor):
33+
self.sql_flavor = flavor
34+
self.flavor_service = get_flavor_service(flavor)
35+
3336
today = date_service.get_now_as_string()
3437
self.run_date = today
3538
self.as_of_date = today
@@ -47,7 +50,7 @@ def _get_params(self) -> dict:
4750
"GENERATION_SET": self.generation_set,
4851
"AS_OF_DATE": self.as_of_date,
4952
"DATA_SCHEMA": self.data_schema,
50-
"ID_SEPARATOR": "`" if self.sql_flavor in ("databricks", "bigquery") else '"',
53+
"QUOTE": self.flavor_service.quote_character,
5154
}
5255

5356
def _get_query(self, template_file_name: str, sub_directory: str | None = "generation") -> tuple[str, dict]:

testgen/commands/queries/refresh_data_chars_query.py

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from testgen.common import read_template_sql_file
2-
from testgen.common.database.database_service import replace_params
2+
from testgen.common.database.database_service import get_flavor_service, replace_params
33
from testgen.common.database.flavor.flavor_service import SQLFlavor
44
from testgen.utils import chunk_queries
55

@@ -46,36 +46,30 @@ def _get_query(self, template_file_name: str, sub_directory: str | None = "data_
4646

4747
def _get_table_criteria(self) -> str:
4848
table_criteria = ""
49-
50-
table_ref = "c.table_name"
51-
escape_clause = ""
52-
escaped_underscore = "\\_"
53-
if self.sql_flavor.startswith("mssql"):
54-
escaped_underscore = "[_]"
55-
elif self.sql_flavor == "snowflake":
56-
escaped_underscore = "\\\\_"
57-
escape_clause = "ESCAPE '\\\\'"
58-
elif self.sql_flavor == "redshift":
59-
escaped_underscore = "\\\\_"
60-
elif self.sql_flavor == "redshift_spectrum":
61-
table_ref = "c.tablename"
62-
49+
flavor_service = get_flavor_service(self.sql_flavor)
50+
6351
if self.profiling_table_set:
64-
table_criteria += f" AND {table_ref} IN ({self.profiling_table_set})"
52+
table_criteria += f" AND c.{flavor_service.ddf_table_ref} IN ({self.profiling_table_set})"
6553

6654
if self.profiling_include_mask:
67-
include_table_names = [ item.strip().replace("_", escaped_underscore) for item in self.profiling_include_mask.split(",") ]
55+
include_table_names = [
56+
item.strip().replace("_", flavor_service.escaped_underscore)
57+
for item in self.profiling_include_mask.split(",")
58+
]
6859
table_criteria += f"""
6960
AND (
70-
{" OR ".join([ f"({table_ref} LIKE '{item}' {escape_clause})" for item in include_table_names ])}
61+
{" OR ".join([ f"(c.{flavor_service.ddf_table_ref} LIKE '{item}' {flavor_service.escape_clause})" for item in include_table_names ])}
7162
)
7263
"""
7364

7465
if self.profiling_exclude_mask:
75-
exclude_table_names = [ item.strip().replace("_", escaped_underscore) for item in self.profiling_exclude_mask.split(",") ]
66+
exclude_table_names = [
67+
item.strip().replace("_", flavor_service.escaped_underscore)
68+
for item in self.profiling_exclude_mask.split(",")
69+
]
7670
table_criteria += f"""
7771
AND NOT (
78-
{" OR ".join([ f"({table_ref} LIKE '{item}' {escape_clause})" for item in exclude_table_names ])}
72+
{" OR ".join([ f"(c.{flavor_service.ddf_table_ref} LIKE '{item}' {flavor_service.escape_clause})" for item in exclude_table_names ])}
7973
)
8074
"""
8175

testgen/commands/queries/test_parameter_validation_query.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import typing
22

33
from testgen.common import CleanSQL, date_service, read_template_sql_file
4-
from testgen.common.database.database_service import replace_params
4+
from testgen.common.database.database_service import get_flavor_service, replace_params
55

66

77
class CTestParamValidationSQL:
@@ -19,6 +19,7 @@ class CTestParamValidationSQL:
1919

2020
def __init__(self, strFlavor, strTestSuiteId):
2121
self.flavor = strFlavor
22+
self.flavor_service = get_flavor_service(strFlavor)
2223
self.test_suite_id = strTestSuiteId
2324
self.today = date_service.get_now_as_string()
2425

@@ -35,8 +36,8 @@ def _get_query(self, template_file_name: str, sub_directory: str | None = "valid
3536
"CAT_TEST_IDS": tuple(self.test_ids or []),
3637
"START_TIME": self.today,
3738
"NOW_TIMESTAMP": date_service.get_now_as_string(),
38-
"COLUMNS_TABLE": f"{self.tg_schema}.INFORMATION_SCHEMA.COLUMNS" if self.flavor == "bigquery" else "information_schema.columns",
39-
"ID_SEPARATOR": "`" if self.flavor in ("databricks", "bigquery") else '"',
39+
"DATA_SCHEMA": self.tg_schema,
40+
"QUOTE": self.flavor_service.quote_character,
4041
}
4142
query = replace_params(query, params)
4243
return query, params

testgen/commands/run_generate_tests.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def run_test_gen_queries(table_group_id: str, test_suite: str, generation_set: s
1919
connection = Connection.get_by_table_group(table_group_id)
2020
set_target_db_params(connection.__dict__)
2121

22-
clsTests = CDeriveTestsSQL()
22+
clsTests = CDeriveTestsSQL(connection.sql_flavor)
2323

2424
LOG.info(f"CurrentStep: Retrieving General Parameters for Test Suite {test_suite}")
2525
params = get_test_generation_params(table_group_id, test_suite)
@@ -32,7 +32,6 @@ def run_test_gen_queries(table_group_id: str, test_suite: str, generation_set: s
3232
clsTests.test_suite_id = params["test_suite_id"] if params["test_suite_id"] else ""
3333
clsTests.connection_id = str(connection.connection_id)
3434
clsTests.table_groups_id = table_group_id
35-
clsTests.sql_flavor = connection.sql_flavor
3635
clsTests.data_schema = params["table_group_schema"]
3736
if params["profiling_as_of_date"] is not None:
3837
clsTests.as_of_date = params["profiling_as_of_date"].strftime("%Y-%m-%d %H:%M:%S")

testgen/commands/run_refresh_data_chars.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
execute_db_queries,
88
fetch_dict_from_db,
99
fetch_from_db_threaded,
10+
get_flavor_service,
1011
write_to_app_db,
1112
)
1213
from testgen.common.get_pipeline_parms import TestExecutionParams
@@ -18,12 +19,14 @@
1819
def run_refresh_data_chars_queries(params: TestExecutionParams, run_date: str, spinner: Spinner=None):
1920
LOG.info("CurrentStep: Initializing Data Characteristics Refresh")
2021
sql_generator = CRefreshDataCharsSQL(params, run_date, STAGING_TABLE)
22+
flavor_service = get_flavor_service(params["sql_flavor"])
23+
quote = flavor_service.quote_character
2124

2225
LOG.info("CurrentStep: Getting DDF for table group")
2326
ddf_results = fetch_dict_from_db(*sql_generator.GetDDFQuery(), use_target_db=True)
2427

2528
distinct_tables = {
26-
f"{item['table_schema']}.{item['table_name']}"
29+
f"{quote}{item['table_schema']}{quote}.{quote}{item['table_name']}{quote}"
2730
for item in ddf_results
2831
}
2932
if distinct_tables:
@@ -65,7 +68,7 @@ def run_refresh_data_chars_queries(params: TestExecutionParams, run_date: str, s
6568
item["general_type"],
6669
item["column_type"],
6770
item["db_data_type"],
68-
count_map.get(f"{item['table_schema']}.{item['table_name']}", 0),
71+
count_map.get(f"{quote}{item['table_schema']}{quote}.{quote}{item['table_name']}{quote}", 0),
6972
]
7073
for item in ddf_results
7174
]

testgen/common/clean_sql.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import re
22

3+
from testgen.common.database.database_service import get_flavor_service
4+
35

46
def CleanSQL(strInput: str) -> str:
57
# Use regular expression to remove comment text fenced by /*...*/
@@ -24,20 +26,22 @@ def quote_identifiers(identifiers: str, flavor: str) -> str:
2426
"by",
2527
"having",
2628
]
29+
flavor_service = get_flavor_service(flavor)
30+
quote = flavor_service.quote_character
2731

2832
quoted_values = []
2933
for value in identifiers.split(","):
3034
value = value.strip()
31-
if value.startswith('"') and value.endswith('"'):
35+
if value.startswith(quote) and value.endswith(quote):
3236
quoted_values.append(value)
3337
elif any(
34-
(flavor == "snowflake" and c.lower())
35-
or (flavor != "snowflake" and c.isupper())
38+
(flavor_service.default_uppercase and c.lower())
39+
or (not flavor_service.default_uppercase and c.isupper())
3640
or c.isspace()
3741
or value.lower() in keywords
3842
for c in value
3943
):
40-
quoted_values.append(f'"{value}"')
44+
quoted_values.append(f"{quote}{value}{quote}")
4145
else:
4246
quoted_values.append(value)
4347
return ", ".join(quoted_values)

testgen/common/database/flavor/bigquery_flavor_service.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44

55

66
class BigqueryFlavorService(FlavorService):
7+
8+
quote_character = "`"
9+
escaped_single_quote = "\\'"
10+
varchar_type = "STRING"
11+
712
def get_connection_string_head(self):
813
return "bigquery://"
914

testgen/common/database/flavor/databricks_flavor_service.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55

66
class DatabricksFlavorService(FlavorService):
77

8+
quote_character = "`"
9+
escaped_single_quote = "\\'"
10+
varchar_type = "STRING"
11+
812
def get_connection_string_head(self):
913
return f"{self.flavor}://{self.username}:{quote_plus(self.password)}@"
1014

0 commit comments

Comments
 (0)