sqlspec 0.14.0__py3-none-any.whl → 0.15.0__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.
- sqlspec/__init__.py +50 -25
- sqlspec/__main__.py +12 -0
- sqlspec/__metadata__.py +1 -3
- sqlspec/_serialization.py +1 -2
- sqlspec/_sql.py +256 -120
- sqlspec/_typing.py +278 -142
- sqlspec/adapters/adbc/__init__.py +4 -3
- sqlspec/adapters/adbc/_types.py +12 -0
- sqlspec/adapters/adbc/config.py +115 -248
- sqlspec/adapters/adbc/driver.py +462 -353
- sqlspec/adapters/aiosqlite/__init__.py +18 -3
- sqlspec/adapters/aiosqlite/_types.py +13 -0
- sqlspec/adapters/aiosqlite/config.py +199 -129
- sqlspec/adapters/aiosqlite/driver.py +230 -269
- sqlspec/adapters/asyncmy/__init__.py +18 -3
- sqlspec/adapters/asyncmy/_types.py +12 -0
- sqlspec/adapters/asyncmy/config.py +80 -168
- sqlspec/adapters/asyncmy/driver.py +260 -225
- sqlspec/adapters/asyncpg/__init__.py +19 -4
- sqlspec/adapters/asyncpg/_types.py +17 -0
- sqlspec/adapters/asyncpg/config.py +82 -181
- sqlspec/adapters/asyncpg/driver.py +285 -383
- sqlspec/adapters/bigquery/__init__.py +17 -3
- sqlspec/adapters/bigquery/_types.py +12 -0
- sqlspec/adapters/bigquery/config.py +191 -258
- sqlspec/adapters/bigquery/driver.py +474 -646
- sqlspec/adapters/duckdb/__init__.py +14 -3
- sqlspec/adapters/duckdb/_types.py +12 -0
- sqlspec/adapters/duckdb/config.py +415 -351
- sqlspec/adapters/duckdb/driver.py +343 -413
- sqlspec/adapters/oracledb/__init__.py +19 -5
- sqlspec/adapters/oracledb/_types.py +14 -0
- sqlspec/adapters/oracledb/config.py +123 -379
- sqlspec/adapters/oracledb/driver.py +507 -560
- sqlspec/adapters/psqlpy/__init__.py +13 -3
- sqlspec/adapters/psqlpy/_types.py +11 -0
- sqlspec/adapters/psqlpy/config.py +93 -254
- sqlspec/adapters/psqlpy/driver.py +505 -234
- sqlspec/adapters/psycopg/__init__.py +19 -5
- sqlspec/adapters/psycopg/_types.py +17 -0
- sqlspec/adapters/psycopg/config.py +143 -403
- sqlspec/adapters/psycopg/driver.py +706 -872
- sqlspec/adapters/sqlite/__init__.py +14 -3
- sqlspec/adapters/sqlite/_types.py +11 -0
- sqlspec/adapters/sqlite/config.py +202 -118
- sqlspec/adapters/sqlite/driver.py +264 -303
- sqlspec/base.py +105 -9
- sqlspec/{statement/builder → builder}/__init__.py +12 -14
- sqlspec/{statement/builder → builder}/_base.py +120 -55
- sqlspec/{statement/builder → builder}/_column.py +17 -6
- sqlspec/{statement/builder → builder}/_ddl.py +46 -79
- sqlspec/{statement/builder → builder}/_ddl_utils.py +5 -10
- sqlspec/{statement/builder → builder}/_delete.py +6 -25
- sqlspec/{statement/builder → builder}/_insert.py +6 -64
- sqlspec/builder/_merge.py +56 -0
- sqlspec/{statement/builder → builder}/_parsing_utils.py +3 -10
- sqlspec/{statement/builder → builder}/_select.py +11 -56
- sqlspec/{statement/builder → builder}/_update.py +12 -18
- sqlspec/{statement/builder → builder}/mixins/__init__.py +10 -14
- sqlspec/{statement/builder → builder}/mixins/_cte_and_set_ops.py +48 -59
- sqlspec/{statement/builder → builder}/mixins/_insert_operations.py +22 -16
- sqlspec/{statement/builder → builder}/mixins/_join_operations.py +1 -3
- sqlspec/{statement/builder → builder}/mixins/_merge_operations.py +3 -5
- sqlspec/{statement/builder → builder}/mixins/_order_limit_operations.py +3 -3
- sqlspec/{statement/builder → builder}/mixins/_pivot_operations.py +4 -8
- sqlspec/{statement/builder → builder}/mixins/_select_operations.py +21 -36
- sqlspec/{statement/builder → builder}/mixins/_update_operations.py +3 -14
- sqlspec/{statement/builder → builder}/mixins/_where_clause.py +52 -79
- sqlspec/cli.py +4 -5
- sqlspec/config.py +180 -133
- sqlspec/core/__init__.py +63 -0
- sqlspec/core/cache.py +873 -0
- sqlspec/core/compiler.py +396 -0
- sqlspec/core/filters.py +828 -0
- sqlspec/core/hashing.py +310 -0
- sqlspec/core/parameters.py +1209 -0
- sqlspec/core/result.py +664 -0
- sqlspec/{statement → core}/splitter.py +321 -191
- sqlspec/core/statement.py +651 -0
- sqlspec/driver/__init__.py +7 -10
- sqlspec/driver/_async.py +387 -176
- sqlspec/driver/_common.py +527 -289
- sqlspec/driver/_sync.py +390 -172
- sqlspec/driver/mixins/__init__.py +2 -19
- sqlspec/driver/mixins/_result_tools.py +168 -0
- sqlspec/driver/mixins/_sql_translator.py +6 -3
- sqlspec/exceptions.py +5 -252
- sqlspec/extensions/aiosql/adapter.py +93 -96
- sqlspec/extensions/litestar/config.py +0 -1
- sqlspec/extensions/litestar/handlers.py +15 -26
- sqlspec/extensions/litestar/plugin.py +16 -14
- sqlspec/extensions/litestar/providers.py +17 -52
- sqlspec/loader.py +424 -105
- sqlspec/migrations/__init__.py +12 -0
- sqlspec/migrations/base.py +92 -68
- sqlspec/migrations/commands.py +24 -106
- sqlspec/migrations/loaders.py +402 -0
- sqlspec/migrations/runner.py +49 -51
- sqlspec/migrations/tracker.py +31 -44
- sqlspec/migrations/utils.py +64 -24
- sqlspec/protocols.py +7 -183
- sqlspec/storage/__init__.py +1 -1
- sqlspec/storage/backends/base.py +37 -40
- sqlspec/storage/backends/fsspec.py +136 -112
- sqlspec/storage/backends/obstore.py +138 -160
- sqlspec/storage/capabilities.py +5 -4
- sqlspec/storage/registry.py +57 -106
- sqlspec/typing.py +136 -115
- sqlspec/utils/__init__.py +2 -3
- sqlspec/utils/correlation.py +0 -3
- sqlspec/utils/deprecation.py +6 -6
- sqlspec/utils/fixtures.py +6 -6
- sqlspec/utils/logging.py +0 -2
- sqlspec/utils/module_loader.py +7 -12
- sqlspec/utils/singleton.py +0 -1
- sqlspec/utils/sync_tools.py +16 -37
- sqlspec/utils/text.py +12 -51
- sqlspec/utils/type_guards.py +443 -232
- {sqlspec-0.14.0.dist-info → sqlspec-0.15.0.dist-info}/METADATA +7 -2
- sqlspec-0.15.0.dist-info/RECORD +134 -0
- sqlspec-0.15.0.dist-info/entry_points.txt +2 -0
- sqlspec/driver/connection.py +0 -207
- sqlspec/driver/mixins/_cache.py +0 -114
- sqlspec/driver/mixins/_csv_writer.py +0 -91
- sqlspec/driver/mixins/_pipeline.py +0 -508
- sqlspec/driver/mixins/_query_tools.py +0 -796
- sqlspec/driver/mixins/_result_utils.py +0 -138
- sqlspec/driver/mixins/_storage.py +0 -912
- sqlspec/driver/mixins/_type_coercion.py +0 -128
- sqlspec/driver/parameters.py +0 -138
- sqlspec/statement/__init__.py +0 -21
- sqlspec/statement/builder/_merge.py +0 -95
- sqlspec/statement/cache.py +0 -50
- sqlspec/statement/filters.py +0 -625
- sqlspec/statement/parameters.py +0 -996
- sqlspec/statement/pipelines/__init__.py +0 -210
- sqlspec/statement/pipelines/analyzers/__init__.py +0 -9
- sqlspec/statement/pipelines/analyzers/_analyzer.py +0 -646
- sqlspec/statement/pipelines/context.py +0 -115
- sqlspec/statement/pipelines/transformers/__init__.py +0 -7
- sqlspec/statement/pipelines/transformers/_expression_simplifier.py +0 -88
- sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +0 -1247
- sqlspec/statement/pipelines/transformers/_remove_comments_and_hints.py +0 -76
- sqlspec/statement/pipelines/validators/__init__.py +0 -23
- sqlspec/statement/pipelines/validators/_dml_safety.py +0 -290
- sqlspec/statement/pipelines/validators/_parameter_style.py +0 -370
- sqlspec/statement/pipelines/validators/_performance.py +0 -714
- sqlspec/statement/pipelines/validators/_security.py +0 -967
- sqlspec/statement/result.py +0 -435
- sqlspec/statement/sql.py +0 -1774
- sqlspec/utils/cached_property.py +0 -25
- sqlspec/utils/statement_hashing.py +0 -203
- sqlspec-0.14.0.dist-info/RECORD +0 -143
- sqlspec-0.14.0.dist-info/entry_points.txt +0 -2
- /sqlspec/{statement/builder → builder}/mixins/_delete_operations.py +0 -0
- {sqlspec-0.14.0.dist-info → sqlspec-0.15.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.14.0.dist-info → sqlspec-0.15.0.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.14.0.dist-info → sqlspec-0.15.0.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, ParameterStyleTransformationState
|
|
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 conversion state."""
|
|
101
|
-
|
|
102
|
-
parameter_conversion: "Optional[ParameterStyleTransformationState]" = None
|
|
103
|
-
"""Single source of truth for parameter style conversion 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_conversion: 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_conversion:
|
|
78
|
-
optimizations.append("equality_conversion")
|
|
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)
|