sqlspec 0.54.2__py3-none-any.whl → 0.54.3__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.
- sqlspec/core/result/_base.py +13 -14
- sqlspec/core/statement.py +97 -94
- {sqlspec-0.54.2.dist-info → sqlspec-0.54.3.dist-info}/METADATA +1 -1
- {sqlspec-0.54.2.dist-info → sqlspec-0.54.3.dist-info}/RECORD +7 -7
- {sqlspec-0.54.2.dist-info → sqlspec-0.54.3.dist-info}/WHEEL +0 -0
- {sqlspec-0.54.2.dist-info → sqlspec-0.54.3.dist-info}/entry_points.txt +0 -0
- {sqlspec-0.54.2.dist-info → sqlspec-0.54.3.dist-info}/licenses/LICENSE +0 -0
sqlspec/core/result/_base.py
CHANGED
|
@@ -71,7 +71,17 @@ class StatementResult(ABC, Iterable[Any]):
|
|
|
71
71
|
metadata: Additional metadata about the operation.
|
|
72
72
|
"""
|
|
73
73
|
|
|
74
|
-
__slots__ = (
|
|
74
|
+
__slots__ = (
|
|
75
|
+
"_operation_type",
|
|
76
|
+
"data",
|
|
77
|
+
"execution_time",
|
|
78
|
+
"last_inserted_id",
|
|
79
|
+
"metadata",
|
|
80
|
+
"rows_affected",
|
|
81
|
+
"statement",
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
_operation_type: "OperationType"
|
|
75
85
|
|
|
76
86
|
def __init__(
|
|
77
87
|
self,
|
|
@@ -93,6 +103,7 @@ class StatementResult(ABC, Iterable[Any]):
|
|
|
93
103
|
metadata: Additional metadata about the operation.
|
|
94
104
|
"""
|
|
95
105
|
self.statement = statement
|
|
106
|
+
self._operation_type = statement.operation_type
|
|
96
107
|
self.data = data
|
|
97
108
|
self.rows_affected = rows_affected
|
|
98
109
|
self.last_inserted_id = last_inserted_id
|
|
@@ -147,7 +158,7 @@ class StatementResult(ABC, Iterable[Any]):
|
|
|
147
158
|
Returns:
|
|
148
159
|
The type of SQL operation that produced this result.
|
|
149
160
|
"""
|
|
150
|
-
return self.
|
|
161
|
+
return self._operation_type
|
|
151
162
|
|
|
152
163
|
|
|
153
164
|
@mypyc_attr(allow_interpreted_subclasses=False)
|
|
@@ -163,7 +174,6 @@ class SQLResult(StatementResult):
|
|
|
163
174
|
|
|
164
175
|
__slots__ = (
|
|
165
176
|
"_materialized_dicts",
|
|
166
|
-
"_operation_type",
|
|
167
177
|
"_row_format",
|
|
168
178
|
"_schema_row_cache",
|
|
169
179
|
"_schema_rows_cache",
|
|
@@ -180,8 +190,6 @@ class SQLResult(StatementResult):
|
|
|
180
190
|
"total_statements",
|
|
181
191
|
)
|
|
182
192
|
|
|
183
|
-
_operation_type: "OperationType"
|
|
184
|
-
|
|
185
193
|
def __init__(
|
|
186
194
|
self,
|
|
187
195
|
statement: "SQL",
|
|
@@ -260,15 +268,6 @@ class SQLResult(StatementResult):
|
|
|
260
268
|
if self.total_count is None:
|
|
261
269
|
self.total_count = len(data) if data is not None else 0
|
|
262
270
|
|
|
263
|
-
@property
|
|
264
|
-
def operation_type(self) -> "OperationType":
|
|
265
|
-
"""Get operation type for this result.
|
|
266
|
-
|
|
267
|
-
Returns:
|
|
268
|
-
The type of SQL operation that produced this result.
|
|
269
|
-
"""
|
|
270
|
-
return self._operation_type
|
|
271
|
-
|
|
272
271
|
def _get_rows(self) -> "list[dict[str, Any]]":
|
|
273
272
|
"""Get row data as list of dicts, materializing lazily from raw format.
|
|
274
273
|
|
sqlspec/core/statement.py
CHANGED
|
@@ -478,8 +478,9 @@ class SQL:
|
|
|
478
478
|
self._is_many = sql_obj.is_many
|
|
479
479
|
self._is_script = sql_obj.is_script
|
|
480
480
|
self._declared_parameters = sql_obj._declared_parameters
|
|
481
|
-
|
|
482
|
-
|
|
481
|
+
source_state = sql_obj.get_processed_state()
|
|
482
|
+
if source_state is not Empty:
|
|
483
|
+
self._processed_state = source_state
|
|
483
484
|
|
|
484
485
|
@staticmethod
|
|
485
486
|
def _should_auto_detect_many(parameters: tuple) -> bool:
|
|
@@ -611,9 +612,10 @@ class SQL:
|
|
|
611
612
|
@property
|
|
612
613
|
def operation_type(self) -> "OperationType":
|
|
613
614
|
"""SQL operation type."""
|
|
614
|
-
|
|
615
|
+
state = self._processed_state
|
|
616
|
+
if state is Empty:
|
|
615
617
|
return "COMMAND"
|
|
616
|
-
return
|
|
618
|
+
return state.operation_type
|
|
617
619
|
|
|
618
620
|
@property
|
|
619
621
|
def statement_config(self) -> "StatementConfig":
|
|
@@ -626,8 +628,9 @@ class SQL:
|
|
|
626
628
|
|
|
627
629
|
This intentionally mirrors statement_expression for compatibility.
|
|
628
630
|
"""
|
|
629
|
-
|
|
630
|
-
|
|
631
|
+
state = self._processed_state
|
|
632
|
+
if state is not Empty:
|
|
633
|
+
return state.parsed_expression
|
|
631
634
|
return self._raw_expression
|
|
632
635
|
|
|
633
636
|
@property
|
|
@@ -651,7 +654,8 @@ class SQL:
|
|
|
651
654
|
@property
|
|
652
655
|
def is_processed(self) -> bool:
|
|
653
656
|
"""Check if SQL has been processed (public API)."""
|
|
654
|
-
|
|
657
|
+
state = self._processed_state
|
|
658
|
+
return state is not Empty
|
|
655
659
|
|
|
656
660
|
def get_processed_state(self) -> Any:
|
|
657
661
|
"""Get processed state (public API)."""
|
|
@@ -671,8 +675,9 @@ class SQL:
|
|
|
671
675
|
Returns:
|
|
672
676
|
Parsed SQLGlot expression or None if not parsed
|
|
673
677
|
"""
|
|
674
|
-
|
|
675
|
-
|
|
678
|
+
state = self._processed_state
|
|
679
|
+
if state is not Empty:
|
|
680
|
+
return state.parsed_expression
|
|
676
681
|
return self._raw_expression
|
|
677
682
|
|
|
678
683
|
@property
|
|
@@ -688,16 +693,18 @@ class SQL:
|
|
|
688
693
|
@property
|
|
689
694
|
def validation_errors(self) -> "list[str]":
|
|
690
695
|
"""Validation errors."""
|
|
691
|
-
|
|
696
|
+
state = self._processed_state
|
|
697
|
+
if state is Empty:
|
|
692
698
|
return []
|
|
693
|
-
return
|
|
699
|
+
return state.validation_errors.copy()
|
|
694
700
|
|
|
695
701
|
@property
|
|
696
702
|
def has_errors(self) -> bool:
|
|
697
703
|
"""Check if there are validation errors."""
|
|
698
|
-
|
|
704
|
+
state = self._processed_state
|
|
705
|
+
if state is Empty:
|
|
699
706
|
return False
|
|
700
|
-
return bool(
|
|
707
|
+
return bool(state.validation_errors)
|
|
701
708
|
|
|
702
709
|
def returns_rows(self) -> bool:
|
|
703
710
|
"""Check if statement returns rows.
|
|
@@ -705,21 +712,23 @@ class SQL:
|
|
|
705
712
|
Returns:
|
|
706
713
|
True if the SQL statement returns result rows
|
|
707
714
|
"""
|
|
708
|
-
|
|
715
|
+
state = self._processed_state
|
|
716
|
+
if state is Empty:
|
|
709
717
|
self.compile()
|
|
710
|
-
|
|
718
|
+
state = self._processed_state
|
|
719
|
+
if state is Empty:
|
|
711
720
|
return False
|
|
712
721
|
|
|
713
|
-
profile =
|
|
722
|
+
profile = state.operation_profile
|
|
714
723
|
if profile.returns_rows:
|
|
715
724
|
return True
|
|
716
725
|
|
|
717
|
-
op_type =
|
|
726
|
+
op_type = state.operation_type
|
|
718
727
|
if op_type in RETURNS_ROWS_OPERATIONS:
|
|
719
728
|
return True
|
|
720
729
|
|
|
721
|
-
if
|
|
722
|
-
expr =
|
|
730
|
+
if state.parsed_expression:
|
|
731
|
+
expr = state.parsed_expression
|
|
723
732
|
if isinstance(expr, (exp.Insert, exp.Update, exp.Delete)) and expr.args.get("returning"):
|
|
724
733
|
return True
|
|
725
734
|
|
|
@@ -731,19 +740,20 @@ class SQL:
|
|
|
731
740
|
Returns:
|
|
732
741
|
True if the operation modifies data (INSERT/UPDATE/DELETE)
|
|
733
742
|
"""
|
|
734
|
-
|
|
743
|
+
state = self._processed_state
|
|
744
|
+
if state is Empty:
|
|
735
745
|
return False
|
|
736
746
|
|
|
737
|
-
profile =
|
|
747
|
+
profile = state.operation_profile
|
|
738
748
|
if profile.modifies_rows:
|
|
739
749
|
return True
|
|
740
750
|
|
|
741
|
-
op_type =
|
|
751
|
+
op_type = state.operation_type
|
|
742
752
|
if op_type in MODIFYING_OPERATIONS:
|
|
743
753
|
return True
|
|
744
754
|
|
|
745
|
-
if
|
|
746
|
-
return isinstance(
|
|
755
|
+
if state.parsed_expression:
|
|
756
|
+
return isinstance(state.parsed_expression, (exp.Insert, exp.Update, exp.Delete, exp.Merge))
|
|
747
757
|
|
|
748
758
|
return False
|
|
749
759
|
|
|
@@ -753,63 +763,57 @@ class SQL:
|
|
|
753
763
|
Returns:
|
|
754
764
|
Tuple of compiled SQL string and execution parameters
|
|
755
765
|
"""
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
except sqlspec.exceptions.SQLSpecError:
|
|
808
|
-
raise
|
|
809
|
-
except Exception as e:
|
|
810
|
-
self._processed_state = self._handle_compile_failure(e)
|
|
811
|
-
|
|
812
|
-
return self._processed_state.compiled_sql, self._processed_state.execution_parameters
|
|
766
|
+
state = self._processed_state
|
|
767
|
+
if state is not Empty:
|
|
768
|
+
if not self._compiled_from_cache:
|
|
769
|
+
return state.compiled_sql, state.execution_parameters
|
|
770
|
+
if state.execution_parameters is not None and (
|
|
771
|
+
not self._statement_config.parameter_config.needs_static_script_compilation
|
|
772
|
+
and self._can_reuse_cached_state(state)
|
|
773
|
+
):
|
|
774
|
+
return self._rebind_cached_parameters(state)
|
|
775
|
+
|
|
776
|
+
try:
|
|
777
|
+
config = self._statement_config
|
|
778
|
+
raw_sql = self._materialized_raw_sql()
|
|
779
|
+
params = self._named_parameters or self._positional_parameters
|
|
780
|
+
is_many = self._is_many
|
|
781
|
+
param_fingerprint = structural_fingerprint(params, is_many=is_many)
|
|
782
|
+
pipeline_fingerprint: Any | None = (
|
|
783
|
+
None if config.parameter_config.needs_static_script_compilation else param_fingerprint
|
|
784
|
+
)
|
|
785
|
+
compiled_result = pipeline.compile_with_pipeline(
|
|
786
|
+
config,
|
|
787
|
+
raw_sql,
|
|
788
|
+
params,
|
|
789
|
+
is_many=is_many,
|
|
790
|
+
expression=self._raw_expression,
|
|
791
|
+
param_fingerprint=pipeline_fingerprint,
|
|
792
|
+
)
|
|
793
|
+
|
|
794
|
+
new_state = self._build_processed_state(
|
|
795
|
+
compiled_sql=compiled_result.compiled_sql,
|
|
796
|
+
execution_parameters=compiled_result.execution_parameters,
|
|
797
|
+
parsed_expression=compiled_result.expression,
|
|
798
|
+
operation_type=compiled_result.operation_type,
|
|
799
|
+
input_named_parameters=compiled_result.input_named_parameters,
|
|
800
|
+
applied_wrap_types=compiled_result.applied_wrap_types,
|
|
801
|
+
filter_hash=hash_filters(self._filters),
|
|
802
|
+
parameter_fingerprint=param_fingerprint,
|
|
803
|
+
parameter_casts=compiled_result.parameter_casts,
|
|
804
|
+
parameter_profile=compiled_result.parameter_profile,
|
|
805
|
+
operation_profile=compiled_result.operation_profile,
|
|
806
|
+
validation_errors=[],
|
|
807
|
+
is_many=self._is_many,
|
|
808
|
+
)
|
|
809
|
+
except sqlspec.exceptions.SQLSpecError:
|
|
810
|
+
raise
|
|
811
|
+
except Exception as e:
|
|
812
|
+
new_state = self._handle_compile_failure(e)
|
|
813
|
+
|
|
814
|
+
self._processed_state = new_state
|
|
815
|
+
self._compiled_from_cache = False
|
|
816
|
+
return new_state.compiled_sql, new_state.execution_parameters
|
|
813
817
|
|
|
814
818
|
def _rebind_cached_parameters(self, state: "ProcessedState") -> "tuple[str, Any]":
|
|
815
819
|
params = self._named_parameters or self._positional_parameters
|
|
@@ -917,8 +921,10 @@ class SQL:
|
|
|
917
921
|
new_sql._pooled = True
|
|
918
922
|
|
|
919
923
|
# Reset mutable state
|
|
920
|
-
|
|
921
|
-
|
|
924
|
+
source_state = self._processed_state
|
|
925
|
+
is_processed = source_state is not Empty
|
|
926
|
+
new_sql._compiled_from_cache = is_processed
|
|
927
|
+
new_sql._processed_state = source_state if is_processed else Empty
|
|
922
928
|
new_sql._hash = None
|
|
923
929
|
new_sql._filters = self._filters.copy()
|
|
924
930
|
new_sql._named_parameters = {}
|
|
@@ -1028,20 +1034,16 @@ class SQL:
|
|
|
1028
1034
|
The SQLGlot expression for this statement
|
|
1029
1035
|
"""
|
|
1030
1036
|
# Preserve authoring-time parameter names when applying dynamic query modifiers.
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
and self._processed_state.input_named_parameters
|
|
1034
|
-
and self._raw_expression is None
|
|
1035
|
-
and self._raw_sql
|
|
1036
|
-
):
|
|
1037
|
+
state = self._processed_state
|
|
1038
|
+
if state is not Empty and state.input_named_parameters and self._raw_expression is None and self._raw_sql:
|
|
1037
1039
|
try:
|
|
1038
1040
|
parsed = sqlglot.parse_one(self._raw_sql, dialect=self._dialect)
|
|
1039
1041
|
if isinstance(parsed, exp.Expr):
|
|
1040
1042
|
return parsed
|
|
1041
1043
|
except ParseError:
|
|
1042
1044
|
pass
|
|
1043
|
-
if
|
|
1044
|
-
return
|
|
1045
|
+
if state is not Empty and state.parsed_expression is not None:
|
|
1046
|
+
return state.parsed_expression.copy()
|
|
1045
1047
|
# Then check statement_expression (from compilation)
|
|
1046
1048
|
if self.statement_expression is not None:
|
|
1047
1049
|
return self.statement_expression.copy()
|
|
@@ -1524,6 +1526,7 @@ class SQL:
|
|
|
1524
1526
|
converted_sql, converted_params = converter.convert_placeholder_style(
|
|
1525
1527
|
raw_sql_for_builder, raw_params, ParameterStyle.NAMED_COLON, is_many=False
|
|
1526
1528
|
)
|
|
1529
|
+
state = self._processed_state
|
|
1527
1530
|
|
|
1528
1531
|
if (
|
|
1529
1532
|
self._raw_expression is not None
|
|
@@ -1532,12 +1535,12 @@ class SQL:
|
|
|
1532
1535
|
):
|
|
1533
1536
|
expression = self._raw_expression.copy()
|
|
1534
1537
|
elif (
|
|
1535
|
-
|
|
1536
|
-
and
|
|
1538
|
+
state is not Empty
|
|
1539
|
+
and state.parsed_expression is not None
|
|
1537
1540
|
and converted_sql == raw_sql_for_builder
|
|
1538
1541
|
and builder_dialect == self._dialect
|
|
1539
1542
|
):
|
|
1540
|
-
expression =
|
|
1543
|
+
expression = state.parsed_expression.copy()
|
|
1541
1544
|
else:
|
|
1542
1545
|
try:
|
|
1543
1546
|
expression = sqlglot.parse_one(converted_sql, dialect=builder_dialect)
|
|
@@ -305,7 +305,7 @@ sqlspec/core/query_modifiers.py,sha256=JCfMtIvgjhVRCFy9kfoGyPnctWeWpx_3ntpym9QpP
|
|
|
305
305
|
sqlspec/core/splitter.py,sha256=sEJ2IpCg8TvgB8Km_NmlQ52gRYQpMWgwK4tOTEa6FtE,32047
|
|
306
306
|
sqlspec/core/sqlcommenter.py,sha256=TMEd13GG5uHvmNitjJuzRibLWQ5BODiDpcZZ1z72Dag,10015
|
|
307
307
|
sqlspec/core/stack.py,sha256=th1gDkmBuVRqnPgJHGCSgiL4IrG8LCEmH-DZ6xbsXC4,6328
|
|
308
|
-
sqlspec/core/statement.py,sha256=
|
|
308
|
+
sqlspec/core/statement.py,sha256=guUTNE2VGfa5dq7Z2gJBvefFp2fnsOSY9XLJF9y716Y,73314
|
|
309
309
|
sqlspec/core/type_converter.py,sha256=8Xh79g87y_1SWui1wsBEYLhXqjeHxD_VCCC1HZbAGao,3052
|
|
310
310
|
sqlspec/core/parameters/__init__.py,sha256=o9pNfE2KDCkMdqOhAGR-bmHE1QMUuGqcpoBd8QlAAJ8,2457
|
|
311
311
|
sqlspec/core/parameters/_alignment.py,sha256=xedu8EKPpORT-f8gqeN4oQgAQQ8euTJ_qqYz-0nu_6k,12275
|
|
@@ -317,7 +317,7 @@ sqlspec/core/parameters/_transformers.py,sha256=U74HDWRggXRDW4EyyramrRzZtZ0uBwED
|
|
|
317
317
|
sqlspec/core/parameters/_types.py,sha256=_ssqAiiv6sgkZNrgeDdOWbI4jFkQGt7-qemx5meZ6n4,24282
|
|
318
318
|
sqlspec/core/parameters/_validator.py,sha256=_u9fwmgmG8g5h1gnYtoaHT6QSOHfzr95YqdaZJBeKYw,5280
|
|
319
319
|
sqlspec/core/result/__init__.py,sha256=CCegsuyJuCUEEByb0Q1vAdc4b1Lkxf-weKuaoGM_kGg,558
|
|
320
|
-
sqlspec/core/result/_base.py,sha256=
|
|
320
|
+
sqlspec/core/result/_base.py,sha256=wrQsZ0MxHnhCmQH2y-xJ5HF6k6jPnlqWbxPivvBCQ-o,43263
|
|
321
321
|
sqlspec/data_dictionary/__init__.py,sha256=ltNkW4U6alTC1ZI6lD6vyZb42xHzgx3JmMEZ35rzsGQ,2519
|
|
322
322
|
sqlspec/data_dictionary/_loader.py,sha256=uEoL5C79apHok6TGzECWsSoOP0zFLeJAEa_XSDU6LbM,13852
|
|
323
323
|
sqlspec/data_dictionary/_registry.py,sha256=yjetmHLgr8QIV4F2aQrqJy4NJAeFfMqoxEnf_rUr6OE,2903
|
|
@@ -525,8 +525,8 @@ sqlspec/utils/serializers/__init__.py,sha256=HrIvaltPf5QfcmXopQvEgRCTzCqn47xZ5G9
|
|
|
525
525
|
sqlspec/utils/serializers/_json.py,sha256=QqHj5YpBkz3QZVne5SNFHp6-dhF1YsFuKxobX2AGm90,14285
|
|
526
526
|
sqlspec/utils/serializers/_numpy.py,sha256=C_V34NNqSpLtV1Z2DVv-SPrH_orUu3q2tS0cRAV1iYI,1767
|
|
527
527
|
sqlspec/utils/serializers/_schema.py,sha256=_QCUNgeC1BpdczMtD1JzQGo4RbgcTpWPPQWa7_w-i2M,11446
|
|
528
|
-
sqlspec-0.54.
|
|
529
|
-
sqlspec-0.54.
|
|
530
|
-
sqlspec-0.54.
|
|
531
|
-
sqlspec-0.54.
|
|
532
|
-
sqlspec-0.54.
|
|
528
|
+
sqlspec-0.54.3.dist-info/METADATA,sha256=5Pu1RkQrwZAXYUQ4pg-R21f0bmVF9VylTRk5YyF40UU,9320
|
|
529
|
+
sqlspec-0.54.3.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
|
|
530
|
+
sqlspec-0.54.3.dist-info/entry_points.txt,sha256=T_1g2gTpkUsl6YC-KSCoNS5r7CPG2kn6wyp1WyMvpqU,404
|
|
531
|
+
sqlspec-0.54.3.dist-info/licenses/LICENSE,sha256=MdujfZ6l5HuLz4mElxlu049itenOR3gnhN1_Nd3nVcM,1078
|
|
532
|
+
sqlspec-0.54.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|