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.
@@ -71,7 +71,17 @@ class StatementResult(ABC, Iterable[Any]):
71
71
  metadata: Additional metadata about the operation.
72
72
  """
73
73
 
74
- __slots__ = ("data", "execution_time", "last_inserted_id", "metadata", "rows_affected", "statement")
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.statement.operation_type
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
- if sql_obj.is_processed:
482
- self._processed_state = sql_obj.get_processed_state()
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
- if self._processed_state is Empty:
615
+ state = self._processed_state
616
+ if state is Empty:
615
617
  return "COMMAND"
616
- return self._processed_state.operation_type
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
- if self._processed_state is not Empty:
630
- return self._processed_state.parsed_expression
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
- return self._processed_state is not Empty
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
- if self._processed_state is not Empty:
675
- return self._processed_state.parsed_expression
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
- if self._processed_state is Empty:
696
+ state = self._processed_state
697
+ if state is Empty:
692
698
  return []
693
- return self._processed_state.validation_errors.copy()
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
- if self._processed_state is Empty:
704
+ state = self._processed_state
705
+ if state is Empty:
699
706
  return False
700
- return bool(self._processed_state.validation_errors)
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
- if self._processed_state is Empty:
715
+ state = self._processed_state
716
+ if state is Empty:
709
717
  self.compile()
710
- if self._processed_state is Empty:
718
+ state = self._processed_state
719
+ if state is Empty:
711
720
  return False
712
721
 
713
- profile = self._processed_state.operation_profile
722
+ profile = state.operation_profile
714
723
  if profile.returns_rows:
715
724
  return True
716
725
 
717
- op_type = self._processed_state.operation_type
726
+ op_type = state.operation_type
718
727
  if op_type in RETURNS_ROWS_OPERATIONS:
719
728
  return True
720
729
 
721
- if self._processed_state.parsed_expression:
722
- expr = self._processed_state.parsed_expression
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
- if self._processed_state is Empty:
743
+ state = self._processed_state
744
+ if state is Empty:
735
745
  return False
736
746
 
737
- profile = self._processed_state.operation_profile
747
+ profile = state.operation_profile
738
748
  if profile.modifies_rows:
739
749
  return True
740
750
 
741
- op_type = self._processed_state.operation_type
751
+ op_type = state.operation_type
742
752
  if op_type in MODIFYING_OPERATIONS:
743
753
  return True
744
754
 
745
- if self._processed_state.parsed_expression:
746
- return isinstance(self._processed_state.parsed_expression, (exp.Insert, exp.Update, exp.Delete, exp.Merge))
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
- if self._processed_state is not Empty:
757
- if self._compiled_from_cache:
758
- state = self._processed_state
759
- if state.execution_parameters is None:
760
- self._processed_state = Empty
761
- self._compiled_from_cache = False
762
- else:
763
- can_reuse = (
764
- not self._statement_config.parameter_config.needs_static_script_compilation
765
- and self._can_reuse_cached_state(state)
766
- )
767
- if can_reuse:
768
- return self._rebind_cached_parameters(state)
769
- self._processed_state = Empty
770
- self._compiled_from_cache = False
771
- else:
772
- return self._processed_state.compiled_sql, self._processed_state.execution_parameters
773
- if self._processed_state is Empty:
774
- try:
775
- config = self._statement_config
776
- raw_sql = self._materialized_raw_sql()
777
- params = self._named_parameters or self._positional_parameters
778
- is_many = self._is_many
779
- param_fingerprint = structural_fingerprint(params, is_many=is_many)
780
- pipeline_fingerprint: Any | None = (
781
- None if config.parameter_config.needs_static_script_compilation else param_fingerprint
782
- )
783
- compiled_result = pipeline.compile_with_pipeline(
784
- config,
785
- raw_sql,
786
- params,
787
- is_many=is_many,
788
- expression=self._raw_expression,
789
- param_fingerprint=pipeline_fingerprint,
790
- )
791
-
792
- self._processed_state = self._build_processed_state(
793
- compiled_sql=compiled_result.compiled_sql,
794
- execution_parameters=compiled_result.execution_parameters,
795
- parsed_expression=compiled_result.expression,
796
- operation_type=compiled_result.operation_type,
797
- input_named_parameters=compiled_result.input_named_parameters,
798
- applied_wrap_types=compiled_result.applied_wrap_types,
799
- filter_hash=hash_filters(self._filters),
800
- parameter_fingerprint=param_fingerprint,
801
- parameter_casts=compiled_result.parameter_casts,
802
- parameter_profile=compiled_result.parameter_profile,
803
- operation_profile=compiled_result.operation_profile,
804
- validation_errors=[],
805
- is_many=self._is_many,
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
- new_sql._compiled_from_cache = self._processed_state is not Empty
921
- new_sql._processed_state = self._processed_state if self._processed_state is not Empty else Empty
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
- if (
1032
- self._processed_state is not Empty
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 self._processed_state is not Empty and self._processed_state.parsed_expression is not None:
1044
- return self._processed_state.parsed_expression.copy()
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
- self._processed_state is not Empty
1536
- and self._processed_state.parsed_expression is not None
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 = self._processed_state.parsed_expression.copy()
1543
+ expression = state.parsed_expression.copy()
1541
1544
  else:
1542
1545
  try:
1543
1546
  expression = sqlglot.parse_one(converted_sql, dialect=builder_dialect)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlspec
3
- Version: 0.54.2
3
+ Version: 0.54.3
4
4
  Summary: SQL Experiments in Python
5
5
  Project-URL: Discord, https://discord.gg/litestar
6
6
  Project-URL: Issue, https://github.com/litestar-org/sqlspec/issues/
@@ -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=0J2qEWoir0A-UAhPA2D7N28Bq3VtnadX7vcczPgjnf0,73894
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=btbZSN9zRTuS_K1U0n8qAxOMO0WN-FoCMpGKucXIYt8,43403
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.2.dist-info/METADATA,sha256=OeQ-2bPEid9sVk10SObevpHvq1Tnf0p1yK-xDWV7Eis,9320
529
- sqlspec-0.54.2.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
530
- sqlspec-0.54.2.dist-info/entry_points.txt,sha256=T_1g2gTpkUsl6YC-KSCoNS5r7CPG2kn6wyp1WyMvpqU,404
531
- sqlspec-0.54.2.dist-info/licenses/LICENSE,sha256=MdujfZ6l5HuLz4mElxlu049itenOR3gnhN1_Nd3nVcM,1078
532
- sqlspec-0.54.2.dist-info/RECORD,,
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,,