sqlspec 0.13.1__py3-none-any.whl → 0.16.2__py3-none-any.whl

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.

Potentially problematic release.


This version of sqlspec might be problematic. Click here for more details.

Files changed (185) hide show
  1. sqlspec/__init__.py +71 -8
  2. sqlspec/__main__.py +12 -0
  3. sqlspec/__metadata__.py +1 -3
  4. sqlspec/_serialization.py +1 -2
  5. sqlspec/_sql.py +930 -136
  6. sqlspec/_typing.py +278 -142
  7. sqlspec/adapters/adbc/__init__.py +4 -3
  8. sqlspec/adapters/adbc/_types.py +12 -0
  9. sqlspec/adapters/adbc/config.py +116 -285
  10. sqlspec/adapters/adbc/driver.py +462 -340
  11. sqlspec/adapters/aiosqlite/__init__.py +18 -3
  12. sqlspec/adapters/aiosqlite/_types.py +13 -0
  13. sqlspec/adapters/aiosqlite/config.py +202 -150
  14. sqlspec/adapters/aiosqlite/driver.py +226 -247
  15. sqlspec/adapters/asyncmy/__init__.py +18 -3
  16. sqlspec/adapters/asyncmy/_types.py +12 -0
  17. sqlspec/adapters/asyncmy/config.py +80 -199
  18. sqlspec/adapters/asyncmy/driver.py +257 -215
  19. sqlspec/adapters/asyncpg/__init__.py +19 -4
  20. sqlspec/adapters/asyncpg/_types.py +17 -0
  21. sqlspec/adapters/asyncpg/config.py +81 -214
  22. sqlspec/adapters/asyncpg/driver.py +284 -359
  23. sqlspec/adapters/bigquery/__init__.py +17 -3
  24. sqlspec/adapters/bigquery/_types.py +12 -0
  25. sqlspec/adapters/bigquery/config.py +191 -299
  26. sqlspec/adapters/bigquery/driver.py +474 -634
  27. sqlspec/adapters/duckdb/__init__.py +14 -3
  28. sqlspec/adapters/duckdb/_types.py +12 -0
  29. sqlspec/adapters/duckdb/config.py +414 -397
  30. sqlspec/adapters/duckdb/driver.py +342 -393
  31. sqlspec/adapters/oracledb/__init__.py +19 -5
  32. sqlspec/adapters/oracledb/_types.py +14 -0
  33. sqlspec/adapters/oracledb/config.py +123 -458
  34. sqlspec/adapters/oracledb/driver.py +505 -531
  35. sqlspec/adapters/psqlpy/__init__.py +13 -3
  36. sqlspec/adapters/psqlpy/_types.py +11 -0
  37. sqlspec/adapters/psqlpy/config.py +93 -307
  38. sqlspec/adapters/psqlpy/driver.py +504 -213
  39. sqlspec/adapters/psycopg/__init__.py +19 -5
  40. sqlspec/adapters/psycopg/_types.py +17 -0
  41. sqlspec/adapters/psycopg/config.py +143 -472
  42. sqlspec/adapters/psycopg/driver.py +704 -825
  43. sqlspec/adapters/sqlite/__init__.py +14 -3
  44. sqlspec/adapters/sqlite/_types.py +11 -0
  45. sqlspec/adapters/sqlite/config.py +208 -142
  46. sqlspec/adapters/sqlite/driver.py +263 -278
  47. sqlspec/base.py +105 -9
  48. sqlspec/{statement/builder → builder}/__init__.py +12 -14
  49. sqlspec/{statement/builder/base.py → builder/_base.py} +184 -86
  50. sqlspec/{statement/builder/column.py → builder/_column.py} +97 -60
  51. sqlspec/{statement/builder/ddl.py → builder/_ddl.py} +61 -131
  52. sqlspec/{statement/builder → builder}/_ddl_utils.py +4 -10
  53. sqlspec/{statement/builder/delete.py → builder/_delete.py} +10 -30
  54. sqlspec/builder/_insert.py +421 -0
  55. sqlspec/builder/_merge.py +71 -0
  56. sqlspec/{statement/builder → builder}/_parsing_utils.py +49 -26
  57. sqlspec/builder/_select.py +170 -0
  58. sqlspec/{statement/builder/update.py → builder/_update.py} +16 -20
  59. sqlspec/builder/mixins/__init__.py +55 -0
  60. sqlspec/builder/mixins/_cte_and_set_ops.py +222 -0
  61. sqlspec/{statement/builder/mixins/_delete_from.py → builder/mixins/_delete_operations.py} +8 -1
  62. sqlspec/builder/mixins/_insert_operations.py +244 -0
  63. sqlspec/{statement/builder/mixins/_join.py → builder/mixins/_join_operations.py} +45 -13
  64. sqlspec/{statement/builder/mixins/_merge_clauses.py → builder/mixins/_merge_operations.py} +188 -30
  65. sqlspec/builder/mixins/_order_limit_operations.py +135 -0
  66. sqlspec/builder/mixins/_pivot_operations.py +153 -0
  67. sqlspec/builder/mixins/_select_operations.py +604 -0
  68. sqlspec/builder/mixins/_update_operations.py +202 -0
  69. sqlspec/builder/mixins/_where_clause.py +644 -0
  70. sqlspec/cli.py +247 -0
  71. sqlspec/config.py +183 -138
  72. sqlspec/core/__init__.py +63 -0
  73. sqlspec/core/cache.py +871 -0
  74. sqlspec/core/compiler.py +417 -0
  75. sqlspec/core/filters.py +830 -0
  76. sqlspec/core/hashing.py +310 -0
  77. sqlspec/core/parameters.py +1237 -0
  78. sqlspec/core/result.py +677 -0
  79. sqlspec/{statement → core}/splitter.py +321 -191
  80. sqlspec/core/statement.py +676 -0
  81. sqlspec/driver/__init__.py +7 -10
  82. sqlspec/driver/_async.py +422 -163
  83. sqlspec/driver/_common.py +545 -287
  84. sqlspec/driver/_sync.py +426 -160
  85. sqlspec/driver/mixins/__init__.py +2 -13
  86. sqlspec/driver/mixins/_result_tools.py +193 -0
  87. sqlspec/driver/mixins/_sql_translator.py +65 -14
  88. sqlspec/exceptions.py +5 -252
  89. sqlspec/extensions/aiosql/adapter.py +93 -96
  90. sqlspec/extensions/litestar/__init__.py +2 -1
  91. sqlspec/extensions/litestar/cli.py +48 -0
  92. sqlspec/extensions/litestar/config.py +0 -1
  93. sqlspec/extensions/litestar/handlers.py +15 -26
  94. sqlspec/extensions/litestar/plugin.py +21 -16
  95. sqlspec/extensions/litestar/providers.py +17 -52
  96. sqlspec/loader.py +423 -104
  97. sqlspec/migrations/__init__.py +35 -0
  98. sqlspec/migrations/base.py +414 -0
  99. sqlspec/migrations/commands.py +443 -0
  100. sqlspec/migrations/loaders.py +402 -0
  101. sqlspec/migrations/runner.py +213 -0
  102. sqlspec/migrations/tracker.py +140 -0
  103. sqlspec/migrations/utils.py +129 -0
  104. sqlspec/protocols.py +51 -186
  105. sqlspec/storage/__init__.py +1 -1
  106. sqlspec/storage/backends/base.py +37 -40
  107. sqlspec/storage/backends/fsspec.py +136 -112
  108. sqlspec/storage/backends/obstore.py +138 -160
  109. sqlspec/storage/capabilities.py +5 -4
  110. sqlspec/storage/registry.py +57 -106
  111. sqlspec/typing.py +136 -115
  112. sqlspec/utils/__init__.py +2 -2
  113. sqlspec/utils/correlation.py +0 -3
  114. sqlspec/utils/deprecation.py +6 -6
  115. sqlspec/utils/fixtures.py +6 -6
  116. sqlspec/utils/logging.py +0 -2
  117. sqlspec/utils/module_loader.py +7 -12
  118. sqlspec/utils/singleton.py +0 -1
  119. sqlspec/utils/sync_tools.py +17 -38
  120. sqlspec/utils/text.py +12 -51
  121. sqlspec/utils/type_guards.py +482 -235
  122. {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/METADATA +7 -2
  123. sqlspec-0.16.2.dist-info/RECORD +134 -0
  124. sqlspec-0.16.2.dist-info/entry_points.txt +2 -0
  125. sqlspec/driver/connection.py +0 -207
  126. sqlspec/driver/mixins/_csv_writer.py +0 -91
  127. sqlspec/driver/mixins/_pipeline.py +0 -512
  128. sqlspec/driver/mixins/_result_utils.py +0 -140
  129. sqlspec/driver/mixins/_storage.py +0 -926
  130. sqlspec/driver/mixins/_type_coercion.py +0 -130
  131. sqlspec/driver/parameters.py +0 -138
  132. sqlspec/service/__init__.py +0 -4
  133. sqlspec/service/_util.py +0 -147
  134. sqlspec/service/base.py +0 -1131
  135. sqlspec/service/pagination.py +0 -26
  136. sqlspec/statement/__init__.py +0 -21
  137. sqlspec/statement/builder/insert.py +0 -288
  138. sqlspec/statement/builder/merge.py +0 -95
  139. sqlspec/statement/builder/mixins/__init__.py +0 -65
  140. sqlspec/statement/builder/mixins/_aggregate_functions.py +0 -250
  141. sqlspec/statement/builder/mixins/_case_builder.py +0 -91
  142. sqlspec/statement/builder/mixins/_common_table_expr.py +0 -90
  143. sqlspec/statement/builder/mixins/_from.py +0 -63
  144. sqlspec/statement/builder/mixins/_group_by.py +0 -118
  145. sqlspec/statement/builder/mixins/_having.py +0 -35
  146. sqlspec/statement/builder/mixins/_insert_from_select.py +0 -47
  147. sqlspec/statement/builder/mixins/_insert_into.py +0 -36
  148. sqlspec/statement/builder/mixins/_insert_values.py +0 -67
  149. sqlspec/statement/builder/mixins/_limit_offset.py +0 -53
  150. sqlspec/statement/builder/mixins/_order_by.py +0 -46
  151. sqlspec/statement/builder/mixins/_pivot.py +0 -79
  152. sqlspec/statement/builder/mixins/_returning.py +0 -37
  153. sqlspec/statement/builder/mixins/_select_columns.py +0 -61
  154. sqlspec/statement/builder/mixins/_set_ops.py +0 -122
  155. sqlspec/statement/builder/mixins/_unpivot.py +0 -77
  156. sqlspec/statement/builder/mixins/_update_from.py +0 -55
  157. sqlspec/statement/builder/mixins/_update_set.py +0 -94
  158. sqlspec/statement/builder/mixins/_update_table.py +0 -29
  159. sqlspec/statement/builder/mixins/_where.py +0 -401
  160. sqlspec/statement/builder/mixins/_window_functions.py +0 -86
  161. sqlspec/statement/builder/select.py +0 -221
  162. sqlspec/statement/filters.py +0 -596
  163. sqlspec/statement/parameter_manager.py +0 -220
  164. sqlspec/statement/parameters.py +0 -867
  165. sqlspec/statement/pipelines/__init__.py +0 -210
  166. sqlspec/statement/pipelines/analyzers/__init__.py +0 -9
  167. sqlspec/statement/pipelines/analyzers/_analyzer.py +0 -646
  168. sqlspec/statement/pipelines/context.py +0 -115
  169. sqlspec/statement/pipelines/transformers/__init__.py +0 -7
  170. sqlspec/statement/pipelines/transformers/_expression_simplifier.py +0 -88
  171. sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +0 -1247
  172. sqlspec/statement/pipelines/transformers/_remove_comments_and_hints.py +0 -76
  173. sqlspec/statement/pipelines/validators/__init__.py +0 -23
  174. sqlspec/statement/pipelines/validators/_dml_safety.py +0 -290
  175. sqlspec/statement/pipelines/validators/_parameter_style.py +0 -370
  176. sqlspec/statement/pipelines/validators/_performance.py +0 -718
  177. sqlspec/statement/pipelines/validators/_security.py +0 -967
  178. sqlspec/statement/result.py +0 -435
  179. sqlspec/statement/sql.py +0 -1704
  180. sqlspec/statement/sql_compiler.py +0 -140
  181. sqlspec/utils/cached_property.py +0 -25
  182. sqlspec-0.13.1.dist-info/RECORD +0 -150
  183. {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/WHEEL +0 -0
  184. {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/licenses/LICENSE +0 -0
  185. {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/licenses/NOTICE +0 -0
@@ -1,115 +0,0 @@
1
- from dataclasses import dataclass, field
2
- from typing import TYPE_CHECKING, Any, Optional
3
-
4
- from sqlglot import exp
5
-
6
- from sqlspec.exceptions import RiskLevel
7
-
8
- if TYPE_CHECKING:
9
- from sqlglot.dialects.dialect import DialectType
10
-
11
- from sqlspec.statement.parameters import ParameterInfo, ParameterNormalizationState
12
- from sqlspec.statement.sql import SQLConfig
13
- from sqlspec.typing import SQLParameterType
14
-
15
- __all__ = ("AnalysisFinding", "SQLProcessingContext", "TransformationLog", "ValidationError")
16
-
17
-
18
- @dataclass
19
- class ValidationError:
20
- """A specific validation issue found during processing."""
21
-
22
- message: str
23
- code: str # e.g., "risky-delete", "missing-where"
24
- risk_level: "RiskLevel"
25
- processor: str # Which processor found it
26
- expression: "Optional[exp.Expression]" = None # Problematic sub-expression
27
-
28
-
29
- @dataclass
30
- class TransformationLog:
31
- """Record of a transformation applied."""
32
-
33
- description: str
34
- processor: str
35
- before: Optional[str] = None # SQL before transform
36
- after: Optional[str] = None # SQL after transform
37
-
38
-
39
- @dataclass
40
- class AnalysisFinding:
41
- """Metadata discovered during analysis."""
42
-
43
- key: str # e.g., "complexity_score", "table_count"
44
- value: Any
45
- processor: str
46
-
47
-
48
- @dataclass
49
- class SQLProcessingContext:
50
- """Carries expression through pipeline and collects all results."""
51
-
52
- # Input
53
- initial_sql_string: str
54
- """The original SQL string input by the user."""
55
-
56
- dialect: "DialectType"
57
- """The SQL dialect to be used for parsing and generation."""
58
-
59
- config: "SQLConfig"
60
- """The configuration for SQL processing for this statement."""
61
-
62
- # Initial state
63
- initial_expression: Optional[exp.Expression] = None
64
- """The initial parsed expression (for diffing/auditing)."""
65
-
66
- # Current state
67
- current_expression: Optional[exp.Expression] = None
68
- """The SQL expression, potentially modified by transformers."""
69
-
70
- # Parameters
71
- initial_parameters: "Optional[SQLParameterType]" = None
72
- """The initial parameters as provided to the SQL object (before merging with kwargs)."""
73
- initial_kwargs: "Optional[dict[str, Any]]" = None
74
- """The initial keyword arguments as provided to the SQL object."""
75
- merged_parameters: "SQLParameterType" = field(default_factory=list)
76
- """Parameters after merging initial_parameters and initial_kwargs."""
77
- parameter_info: "list[ParameterInfo]" = field(default_factory=list)
78
- """Information about identified parameters in the initial_sql_string."""
79
- extracted_parameters_from_pipeline: list[Any] = field(default_factory=list)
80
- """List of parameters extracted by transformers (e.g., ParameterizeLiterals)."""
81
-
82
- # Collected results (processors append to these)
83
- validation_errors: list[ValidationError] = field(default_factory=list)
84
- """Validation errors found during processing."""
85
- analysis_findings: list[AnalysisFinding] = field(default_factory=list)
86
- """Analysis findings discovered during processing."""
87
- transformations: list[TransformationLog] = field(default_factory=list)
88
- """Transformations applied during processing."""
89
-
90
- # General metadata
91
- metadata: dict[str, Any] = field(default_factory=dict)
92
- """General-purpose metadata store."""
93
-
94
- # Flags
95
- input_sql_had_placeholders: bool = False
96
- """Flag indicating if the initial_sql_string already contained placeholders."""
97
- statement_type: Optional[str] = None
98
- """The detected type of the SQL statement (e.g., SELECT, INSERT, DDL)."""
99
- extra_info: dict[str, Any] = field(default_factory=dict)
100
- """Extra information from parameter processing, including normalization state."""
101
-
102
- parameter_normalization: "Optional[ParameterNormalizationState]" = None
103
- """Single source of truth for parameter normalization tracking."""
104
-
105
- @property
106
- def has_errors(self) -> bool:
107
- """Check if any validation errors exist."""
108
- return bool(self.validation_errors)
109
-
110
- @property
111
- def risk_level(self) -> RiskLevel:
112
- """Calculate overall risk from validation errors."""
113
- if not self.validation_errors:
114
- return RiskLevel.SAFE
115
- return max(error.risk_level for error in self.validation_errors)
@@ -1,7 +0,0 @@
1
- """SQL Transformers for the processing pipeline."""
2
-
3
- from sqlspec.statement.pipelines.transformers._expression_simplifier import ExpressionSimplifier, SimplificationConfig
4
- from sqlspec.statement.pipelines.transformers._literal_parameterizer import ParameterizeLiterals
5
- from sqlspec.statement.pipelines.transformers._remove_comments_and_hints import CommentAndHintRemover
6
-
7
- __all__ = ("CommentAndHintRemover", "ExpressionSimplifier", "ParameterizeLiterals", "SimplificationConfig")
@@ -1,88 +0,0 @@
1
- from dataclasses import dataclass
2
- from typing import TYPE_CHECKING, Optional, cast
3
-
4
- from sqlglot.optimizer import simplify
5
-
6
- from sqlspec.exceptions import RiskLevel
7
- from sqlspec.statement.pipelines import ProcessorProtocol, TransformationLog, ValidationError
8
-
9
- if TYPE_CHECKING:
10
- from sqlglot import exp
11
-
12
- from sqlspec.statement.pipelines import SQLProcessingContext
13
-
14
- __all__ = ("ExpressionSimplifier", "SimplificationConfig")
15
-
16
-
17
- @dataclass
18
- class SimplificationConfig:
19
- """Configuration for expression simplification."""
20
-
21
- enable_literal_folding: bool = True
22
- enable_boolean_optimization: bool = True
23
- enable_connector_optimization: bool = True
24
- enable_equality_normalization: bool = True
25
- enable_complement_removal: bool = True
26
-
27
-
28
- class ExpressionSimplifier(ProcessorProtocol):
29
- """Advanced expression optimization using SQLGlot's simplification engine."""
30
-
31
- def __init__(self, enabled: bool = True, config: Optional[SimplificationConfig] = None) -> None:
32
- self.enabled = enabled
33
- self.config = config or SimplificationConfig()
34
-
35
- def process(
36
- self, expression: "Optional[exp.Expression]", context: "SQLProcessingContext"
37
- ) -> "Optional[exp.Expression]":
38
- if not self.enabled or expression is None:
39
- return expression
40
-
41
- original_sql = expression.sql(dialect=context.dialect)
42
-
43
- try:
44
- simplified = simplify.simplify(
45
- expression.copy(), constant_propagation=self.config.enable_literal_folding, dialect=context.dialect
46
- )
47
- except Exception as e:
48
- error = ValidationError(
49
- message=f"Expression simplification failed: {e}",
50
- code="simplification-failed",
51
- risk_level=RiskLevel.LOW,
52
- processor=self.__class__.__name__,
53
- expression=expression,
54
- )
55
- context.validation_errors.append(error)
56
- return expression
57
- else:
58
- simplified_sql = simplified.sql(dialect=context.dialect)
59
- chars_saved = len(original_sql) - len(simplified_sql)
60
-
61
- if original_sql != simplified_sql:
62
- log = TransformationLog(
63
- description=f"Simplified expression (saved {chars_saved} chars)",
64
- processor=self.__class__.__name__,
65
- before=original_sql,
66
- after=simplified_sql,
67
- )
68
- context.transformations.append(log)
69
-
70
- optimizations = []
71
- if self.config.enable_literal_folding:
72
- optimizations.append("literal_folding")
73
- if self.config.enable_boolean_optimization:
74
- optimizations.append("boolean_optimization")
75
- if self.config.enable_connector_optimization:
76
- optimizations.append("connector_optimization")
77
- if self.config.enable_equality_normalization:
78
- optimizations.append("equality_normalization")
79
- if self.config.enable_complement_removal:
80
- optimizations.append("complement_removal")
81
-
82
- context.metadata[self.__class__.__name__] = {
83
- "simplified": original_sql != simplified_sql,
84
- "chars_saved": chars_saved,
85
- "optimizations_applied": optimizations,
86
- }
87
-
88
- return cast("exp.Expression", simplified)