sql-error-categorizer 0.2.2__tar.gz → 0.2.4__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.
Files changed (65) hide show
  1. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/Makefile +3 -4
  2. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/PKG-INFO +2 -2
  3. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/pyproject.toml +2 -2
  4. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/requirements.txt +1 -1
  5. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/src/sql_error_categorizer/detectors/logical.py +3 -2
  6. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/src/sql_error_categorizer/detectors/syntax.py +8 -0
  7. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_002_ambiguous_column.py +1 -0
  8. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/3_log/test_070_extraneous_column_in_select.py +12 -0
  9. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/3_log/test_071_missing_column_from_select.py +12 -0
  10. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/3_log/test_073_missing_as_from_select.py +21 -1
  11. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/.gitignore +0 -0
  12. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/.readthedocs.yaml +0 -0
  13. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/LICENSE +0 -0
  14. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/README.md +0 -0
  15. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/datasets/catalogs/constraints.json +0 -0
  16. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/datasets/catalogs/miedema.json +0 -0
  17. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/datasets/sql/constraints.sql +0 -0
  18. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/datasets/sql/miedema.sql +0 -0
  19. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/docs/Makefile +0 -0
  20. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/docs/conf.py +0 -0
  21. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/docs/index.rst +0 -0
  22. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/docs/make.bat +0 -0
  23. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/docs/requirements.txt +0 -0
  24. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/src/sql_error_categorizer/__init__.py +0 -0
  25. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/src/sql_error_categorizer/detectors/__init__.py +0 -0
  26. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/src/sql_error_categorizer/detectors/base.py +0 -0
  27. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/src/sql_error_categorizer/detectors/complications.py +0 -0
  28. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/src/sql_error_categorizer/detectors/semantic.py +0 -0
  29. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/test_detector.py +0 -0
  30. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_004_undefined_column.py +0 -0
  31. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_005_undefined_function.py +0 -0
  32. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_006_undefined_parameter.py +0 -0
  33. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_007_undefined_tables.py +0 -0
  34. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_008_invalid_schema_names.py +0 -0
  35. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_009_misspellings.py +0 -0
  36. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_013_data_type_mismatch.py +0 -0
  37. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_014_aggregate_function_outside_select_or_having.py +0 -0
  38. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_015_nested_aggregate_functions.py +0 -0
  39. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_016_extraneous_omitted_grouping_column.py +0 -0
  40. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_017_having_without_group_by.py +0 -0
  41. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_019_using_where_twice.py +0 -0
  42. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_020_missing_from.py +0 -0
  43. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_021_comparison_with_null.py +0 -0
  44. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_022_038_additional_omitted_semicolons.py +0 -0
  45. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_024_duplicate_clause.py +0 -0
  46. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_026_too_many_columns_in_subquery.py +0 -0
  47. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_030_keywords_order.py +0 -0
  48. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_034_curly_square_or_unmatched_brackets.py +0 -0
  49. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_035_is_where_not_applicable.py +0 -0
  50. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/1_syn/test_037_nonstandard_operators.py +0 -0
  51. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/2_sem/test_040_tautological_inconsistent_expressions.py +0 -0
  52. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/2_sem/test_041_distinct_sum_avg.py +0 -0
  53. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/2_sem/test_043_wildcards_without_like.py +0 -0
  54. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/2_sem/test_044_incorrect_wildcards.py +0 -0
  55. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/3_log/test_058_join_on_incorrect_table.py +0 -0
  56. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/3_log/test_059_join_when_join_needs_to_be_omitted.py +0 -0
  57. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/3_log/test_062_missing_join.py +0 -0
  58. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/3_log/test_072_missing_distinct_from_select.py +0 -0
  59. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/4_com/test_083_unnecessary_distinct_in_select.py +0 -0
  60. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/4_com/test_088_like_no_wildcards.py +0 -0
  61. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/4_com/test_092_unnecessary_distinct_in_aggregate_function.py +0 -0
  62. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/4_com/test_095_group_by_with_singleton_groups.py +0 -0
  63. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/4_com/test_097_group_by_can_be_replaced_by_distinct.py +0 -0
  64. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/4_com/test_100_order_by_in_subquery.py +0 -0
  65. {sql_error_categorizer-0.2.2 → sql_error_categorizer-0.2.4}/tests/__init__.py +0 -0
@@ -14,6 +14,9 @@ endif
14
14
 
15
15
  .PHONY: install build uninstall documentation test upload download clean coverage
16
16
 
17
+ install: uninstall build
18
+ $(VENV_BIN)/python -m pip install ./dist/*.whl
19
+
17
20
  $(VENV):
18
21
  python -m venv --clear $(VENV)
19
22
  touch -a $(REQUIREMENTS)
@@ -22,10 +25,6 @@ $(VENV):
22
25
  $(VENV)_upgrade: $(VENV)
23
26
  $(VENV_BIN)/python -m pip install --upgrade -r $(REQUIREMENTS)
24
27
 
25
-
26
- install: uninstall build
27
- $(VENV_BIN)/python -m pip install ./dist/*.whl
28
-
29
28
  build: $(VENV)
30
29
  rm -rf dist/
31
30
  $(VENV_BIN)/python -m build
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sql_error_categorizer
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: This project analyses SQL statements and labels possible errors or complications.
5
5
  Project-URL: Repository, https://github.com/DavidePonzini/sql_error_categorizer
6
6
  Project-URL: Documentation, https://sql-error-categorizer.readthedocs.io/en/latest/index.html
@@ -17,7 +17,7 @@ Requires-Dist: pyyaml
17
17
  Requires-Dist: sql-error-taxonomy
18
18
  Requires-Dist: sqlglot
19
19
  Requires-Dist: sqlparse
20
- Requires-Dist: sqlscope
20
+ Requires-Dist: sqlscope>=1.0.15
21
21
  Requires-Dist: z3-solver
22
22
  Description-Content-Type: text/markdown
23
23
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "sql_error_categorizer"
7
- version = "0.2.2"
7
+ version = "0.2.4"
8
8
  authors = [
9
9
  { name="Davide Ponzini", email="davide.ponzini95@gmail.com" },
10
10
  ]
@@ -21,7 +21,7 @@ dependencies = [
21
21
  "pyyaml",
22
22
  "sqlparse",
23
23
  "sqlglot",
24
- "sqlscope",
24
+ "sqlscope>=1.0.15",
25
25
  "sql_error_taxonomy",
26
26
  "z3-solver",
27
27
  "python-dateutil",
@@ -5,7 +5,7 @@ sqlglot==28.0.0
5
5
  z3-solver
6
6
  python-dateutil
7
7
  sql_error_taxonomy>=1.0.1
8
- sqlscope>=1.0.7
8
+ sqlscope>=1.0.15
9
9
 
10
10
  # Dependencies for development
11
11
  ipython
@@ -448,8 +448,9 @@ class LogicalErrorDetector(BaseDetector):
448
448
  if extraneous_columns or missing_columns:
449
449
  return results # skip AS check if column count is already wrong
450
450
 
451
- expected_aliases: set[str] = set.intersection(*[set(col.name for col in sol.main_query.output.columns) for sol in self.solutions])
452
- provided_aliases: set[str] = set(col.name for col in self.query.main_query.output.columns)
451
+ # only consider columns that are actually aliased
452
+ expected_aliases: set[str] = set.intersection(*[set(col.name for col in sol.main_query.output.columns if col.name != col.real_name and not col.name.startswith('_')) for sol in self.solutions])
453
+ provided_aliases: set[str] = set(col.name for col in self.query.main_query.output.columns if col.name != col.real_name and not col.name.startswith('_'))
453
454
 
454
455
  missing_aliases = expected_aliases - provided_aliases
455
456
 
@@ -259,6 +259,10 @@ class SyntaxErrorDetector(BaseDetector):
259
259
  continue
260
260
 
261
261
  for column in select.ast.find_all(exp.Column):
262
+ # skip `table.*` syntax, we only want to check actual column references
263
+ if isinstance(column.this, exp.Star):
264
+ continue
265
+
262
266
  column_name = util.ast.column.get_name(column)
263
267
  table_name = util.ast.column.get_table(column)
264
268
 
@@ -403,6 +407,10 @@ class SyntaxErrorDetector(BaseDetector):
403
407
  continue
404
408
 
405
409
  for column in select.ast.find_all(exp.Column):
410
+ # skip `table.*` syntax, we only want to check actual column references
411
+ if isinstance(column.this, exp.Star):
412
+ continue
413
+
406
414
  column = deepcopy(column) # avoid modifying the original AST until we are sure we want to apply the correction
407
415
  column_str = column.sql()
408
416
  column_name = util.ast.column.get_name(column)
@@ -25,6 +25,7 @@ def test_wrong(query, column, table_aliases, schema):
25
25
 
26
26
  @pytest.mark.parametrize('query,schema', [
27
27
  ('SELECT s.street FROM store s, customer c;', 'miedema'),
28
+ ('SELECT s.* FROM store s, customer c;', 'miedema'),
28
29
  # subqueries
29
30
  ('SELECT * FROM store s, customer c WHERE cid IN (SELECT s2.street FROM store s2, customer c2);', 'miedema'),
30
31
  # CTEs
@@ -90,6 +90,18 @@ def test_wrong(query, solutions, schema, search_path, expected_len, expected_col
90
90
  [],
91
91
  None,
92
92
  ),
93
+ (
94
+ # SELECT t.*
95
+ 'SELECT sid, sname, s.street, s.city FROM store s, customer;',
96
+ ['SELECT store.* FROM store;'],
97
+ 'miedema',
98
+ ),
99
+ (
100
+ # SELECT t.* - inversed
101
+ 'SELECT store.* FROM store;',
102
+ ['SELECT sid, sname, s.street, s.city FROM store s, customer;'],
103
+ 'miedema',
104
+ ),
93
105
  # subqueries
94
106
  (
95
107
  'SELECT a, (SELECT b FROM table2) as sub_col FROM table1;',
@@ -84,6 +84,18 @@ def test_wrong(query, solutions, schema, search_path, expected_len, expected_col
84
84
  ['SELECT cid FROM customer;'],
85
85
  'miedema',
86
86
  ),
87
+ (
88
+ # SELECT t.*
89
+ 'SELECT sid, sname, s.street, s.city FROM store s, customer;',
90
+ ['SELECT store.* FROM store;'],
91
+ 'miedema',
92
+ ),
93
+ (
94
+ # SELECT t.* - inversed
95
+ 'SELECT store.* FROM store;',
96
+ ['SELECT sid, sname, s.street, s.city FROM store s, customer;'],
97
+ 'miedema',
98
+ ),
87
99
  (
88
100
  # no solutions (return no errors)
89
101
  'SELECT a, b, c FROM table1;',
@@ -14,7 +14,21 @@ ERROR = SqlErrors.LOG_73_MISSING_AS_FROM_SELECT
14
14
  'SELECT cid, cname AS street FROM customer;',
15
15
  ['SELECT cid AS id, cname FROM customer;'],
16
16
  'miedema',
17
- ['id', 'cname']
17
+ ['id']
18
+ ),
19
+
20
+ (
21
+ 'SELECT cid, cname AS street FROM customer;',
22
+ ['SELECT cid AS id, cname AS street2 FROM customer;'],
23
+ 'miedema',
24
+ ['id', 'street2']
25
+ ),
26
+ (
27
+ # aliased aggregate in solution (should trigger AS error)
28
+ 'SELECT a AS b, COUNT(*) FROM table1 GROUP BY a;',
29
+ ['SELECT a AS b, COUNT(*) AS c FROM table1 GROUP BY a;'],
30
+ None,
31
+ ['c']
18
32
  )
19
33
  # subqueries -- Not applicable
20
34
  # CTEs -- Not applicable
@@ -54,6 +68,12 @@ def test_wrong(query, solutions, schema, expected):
54
68
  [],
55
69
  None,
56
70
  ),
71
+ (
72
+ # unaliased aggregate in solution (should not trigger AS error)
73
+ 'SELECT a AS b, COUNT(*) AS c FROM table1 GROUP BY a;',
74
+ ['SELECT a AS b, COUNT(*) FROM table1 GROUP BY a;'],
75
+ None,
76
+ ),
57
77
  # subqueries -- Not applicable
58
78
  # CTEs -- Not applicable
59
79
  ])