sql-data-guard 0.1.5__tar.gz → 0.1.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sql_data_guard-0.1.5/src/sql_data_guard.egg-info → sql_data_guard-0.1.6}/PKG-INFO +1 -1
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/pyproject.toml +1 -1
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/src/sql_data_guard/restriction_verification.py +1 -1
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/src/sql_data_guard/sql_data_guard.py +15 -14
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6/src/sql_data_guard.egg-info}/PKG-INFO +1 -1
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/test/test_sql_guard_curr_unit.py +5 -3
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/test/test_sql_guard_unit.py +27 -1
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/test/test_sql_guard_updates_unit.py +4 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/LICENSE.md +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/README.md +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/setup.cfg +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/src/sql_data_guard/__init__.py +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/src/sql_data_guard/rest/__init__.py +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/src/sql_data_guard/rest/sql_data_guard_rest.py +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/src/sql_data_guard/restriction_validation.py +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/src/sql_data_guard/verification_context.py +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/src/sql_data_guard/verification_utils.py +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/src/sql_data_guard.egg-info/SOURCES.txt +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/src/sql_data_guard.egg-info/dependency_links.txt +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/src/sql_data_guard.egg-info/requires.txt +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/src/sql_data_guard.egg-info/top_level.txt +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/test/test_duckdb_unit.py +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/test/test_rest_api_unit.py +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/test/test_sql_guard_joins_unit.py +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/test/test_sql_guard_llm.py +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/test/test_sql_guard_validation_unit.py +0 -0
- {sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/test/test_utils.py +0 -0
{sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/src/sql_data_guard/restriction_verification.py
RENAMED
|
@@ -130,7 +130,7 @@ def _verify_restriction(
|
|
|
130
130
|
# Handle IN condition correctly
|
|
131
131
|
if isinstance(exp, expr.In):
|
|
132
132
|
expr_values = [str(val.this) for val in exp.expressions]
|
|
133
|
-
return
|
|
133
|
+
return all(v in values for v in expr_values)
|
|
134
134
|
|
|
135
135
|
# Handle EQ (=) condition
|
|
136
136
|
if isinstance(exp, expr.EQ) and isinstance(exp.right, expr.Condition):
|
|
@@ -79,7 +79,7 @@ def _verify_where_clause(
|
|
|
79
79
|
):
|
|
80
80
|
where_clause = select_statement.find(expr.Where)
|
|
81
81
|
if where_clause:
|
|
82
|
-
for sub in where_clause.find_all(expr.Subquery):
|
|
82
|
+
for sub in where_clause.find_all(expr.Subquery, expr.Exists):
|
|
83
83
|
_verify_query_statement(sub.this, context)
|
|
84
84
|
_verify_static_expression(select_statement, context)
|
|
85
85
|
verify_restrictions(select_statement, context, from_tables)
|
|
@@ -136,12 +136,10 @@ def _verify_query_statement(query_statement: expr.Query, context: VerificationCo
|
|
|
136
136
|
_add_table_alias(cte, context)
|
|
137
137
|
_verify_query_statement(cte.this, context)
|
|
138
138
|
from_tables = _verify_from_tables(context, query_statement)
|
|
139
|
-
if
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
_verify_order_by_clause(context, query_statement)
|
|
144
|
-
return query_statement
|
|
139
|
+
if context.can_fix:
|
|
140
|
+
_verify_select_clause(context, query_statement, from_tables)
|
|
141
|
+
_verify_where_clause(context, query_statement, from_tables)
|
|
142
|
+
_verify_sub_queries(context, query_statement)
|
|
145
143
|
|
|
146
144
|
|
|
147
145
|
def _verify_from_tables(context, query_statement):
|
|
@@ -156,11 +154,12 @@ def _verify_from_tables(context, query_statement):
|
|
|
156
154
|
return from_tables
|
|
157
155
|
|
|
158
156
|
|
|
159
|
-
def
|
|
160
|
-
for exp_type in [expr.Order, expr.Offset]:
|
|
157
|
+
def _verify_sub_queries(context, query_statement):
|
|
158
|
+
for exp_type in [expr.Order, expr.Offset, expr.Limit, expr.Group, expr.Having]:
|
|
161
159
|
for exp in find_direct(query_statement, exp_type):
|
|
162
|
-
|
|
163
|
-
|
|
160
|
+
if exp:
|
|
161
|
+
for sub in exp.find_all(expr.Subquery):
|
|
162
|
+
_verify_query_statement(sub.this, context)
|
|
164
163
|
|
|
165
164
|
|
|
166
165
|
def _verify_select_clause(
|
|
@@ -289,6 +288,8 @@ def _get_from_clause_tables(
|
|
|
289
288
|
def _add_table_alias(exp: expr.Expression, context: VerificationContext):
|
|
290
289
|
for table_alias in find_direct(exp, expr.TableAlias):
|
|
291
290
|
if isinstance(table_alias, expr.TableAlias):
|
|
292
|
-
|
|
293
|
-
col.alias_or_name for col in table_alias.columns
|
|
294
|
-
|
|
291
|
+
if len(table_alias.columns) > 0:
|
|
292
|
+
column_names = {col.alias_or_name for col in table_alias.columns}
|
|
293
|
+
else:
|
|
294
|
+
column_names = {c for c in exp.this.named_selects}
|
|
295
|
+
context.dynamic_tables[table_alias.alias_or_name] = column_names
|
|
@@ -701,10 +701,12 @@ class TestSQLOrderRestrictions:
|
|
|
701
701
|
verify_sql_test(
|
|
702
702
|
sql,
|
|
703
703
|
config,
|
|
704
|
-
errors=
|
|
705
|
-
|
|
704
|
+
errors={
|
|
705
|
+
"Missing restriction for table: orders column: account_id value: [124]"
|
|
706
|
+
},
|
|
707
|
+
fix="SELECT product_name FROM orders WHERE (account_id IN (123, 124, 125)) AND account_id = 124",
|
|
706
708
|
cnn=cnn,
|
|
707
|
-
data=[("Product
|
|
709
|
+
data=[("Product B",)],
|
|
708
710
|
)
|
|
709
711
|
|
|
710
712
|
def test_id_greater_than_122_should_return_error(self, config):
|
|
@@ -6,8 +6,8 @@ from typing import Generator
|
|
|
6
6
|
|
|
7
7
|
import pytest
|
|
8
8
|
|
|
9
|
+
from conftest import verify_sql_test
|
|
9
10
|
from sql_data_guard import verify_sql
|
|
10
|
-
from conftest import verify_sql_test, verify_sql_test_data
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def _get_resource(file_name: str) -> str:
|
|
@@ -354,6 +354,32 @@ class TestTrino:
|
|
|
354
354
|
)
|
|
355
355
|
|
|
356
356
|
|
|
357
|
+
class TestTrinoWithRestrictions:
|
|
358
|
+
@pytest.fixture(scope="class")
|
|
359
|
+
def config(self) -> dict:
|
|
360
|
+
return {
|
|
361
|
+
"tables": [
|
|
362
|
+
{
|
|
363
|
+
"table_name": "accounts",
|
|
364
|
+
"columns": ["id", "day", "product_name"],
|
|
365
|
+
"restrictions": [
|
|
366
|
+
{"column": "id", "value": 123},
|
|
367
|
+
],
|
|
368
|
+
}
|
|
369
|
+
]
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
@pytest.mark.skip(reason="Bug in sqlglot. Waiting for fix")
|
|
373
|
+
def test_date_add(self, config):
|
|
374
|
+
verify_sql_test(
|
|
375
|
+
"SELECT id FROM accounts WHERE DATE(day) >= DATE_ADD('day', -7, CURRENT_DATE)",
|
|
376
|
+
config,
|
|
377
|
+
dialect="trino",
|
|
378
|
+
errors={"Missing restriction for table: accounts column: id value: 123"},
|
|
379
|
+
fix="SELECT id FROM accounts WHERE DATE(day) >= DATE_ADD('day', -7, CURRENT_DATE) AND id = 123",
|
|
380
|
+
)
|
|
381
|
+
|
|
382
|
+
|
|
357
383
|
class TestRestrictionsWithDifferentDataTypes:
|
|
358
384
|
@pytest.fixture(scope="class")
|
|
359
385
|
def config(self) -> dict:
|
|
@@ -705,6 +705,10 @@ class TestMultipleRestriction:
|
|
|
705
705
|
verify_sql_test(
|
|
706
706
|
"""SELECT id FROM products1 WHERE id IN (324, 233)""",
|
|
707
707
|
config,
|
|
708
|
+
errors={
|
|
709
|
+
"Missing restriction for table: products1 column: id value: [324, 224]"
|
|
710
|
+
},
|
|
711
|
+
fix="SELECT id FROM products1 WHERE (id IN (324, 233)) AND id IN (324, 224)",
|
|
708
712
|
cnn=cnn,
|
|
709
713
|
data=[["324"]],
|
|
710
714
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/src/sql_data_guard/rest/sql_data_guard_rest.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sql_data_guard-0.1.5 → sql_data_guard-0.1.6}/src/sql_data_guard.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|