sqlspec 0.23.0__tar.gz → 0.24.0__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.

Potentially problematic release.


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

Files changed (334) hide show
  1. {sqlspec-0.23.0 → sqlspec-0.24.0}/.pre-commit-config.yaml +1 -1
  2. {sqlspec-0.23.0 → sqlspec-0.24.0}/PKG-INFO +1 -1
  3. {sqlspec-0.23.0 → sqlspec-0.24.0}/pyproject.toml +1 -1
  4. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/_base.py +68 -21
  5. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/_ddl.py +14 -13
  6. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/_insert.py +8 -16
  7. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/_parsing_utils.py +16 -18
  8. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/_update.py +1 -1
  9. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/mixins/_cte_and_set_ops.py +20 -1
  10. sqlspec-0.24.0/sqlspec/builder/mixins/_where_clause.py +1316 -0
  11. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/utils/type_guards.py +31 -0
  12. sqlspec-0.24.0/tests/unit/test_cte_parameter_collisions.py +237 -0
  13. sqlspec-0.24.0/tests/unit/test_where_or_operations.py +545 -0
  14. {sqlspec-0.23.0 → sqlspec-0.24.0}/uv.lock +32 -32
  15. sqlspec-0.23.0/sqlspec/builder/mixins/_where_clause.py +0 -697
  16. {sqlspec-0.23.0 → sqlspec-0.24.0}/.gitignore +0 -0
  17. {sqlspec-0.23.0 → sqlspec-0.24.0}/CONTRIBUTING.rst +0 -0
  18. {sqlspec-0.23.0 → sqlspec-0.24.0}/LICENSE +0 -0
  19. {sqlspec-0.23.0 → sqlspec-0.24.0}/Makefile +0 -0
  20. {sqlspec-0.23.0 → sqlspec-0.24.0}/NOTICE +0 -0
  21. {sqlspec-0.23.0 → sqlspec-0.24.0}/README.md +0 -0
  22. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/__init__.py +0 -0
  23. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/__main__.py +0 -0
  24. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/__metadata__.py +0 -0
  25. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/_serialization.py +0 -0
  26. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/_sql.py +0 -0
  27. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/_typing.py +0 -0
  28. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/__init__.py +0 -0
  29. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/adbc/__init__.py +0 -0
  30. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/adbc/_types.py +0 -0
  31. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/adbc/config.py +0 -0
  32. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/adbc/driver.py +0 -0
  33. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/aiosqlite/__init__.py +0 -0
  34. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/aiosqlite/_types.py +0 -0
  35. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/aiosqlite/config.py +0 -0
  36. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/aiosqlite/driver.py +0 -0
  37. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/aiosqlite/pool.py +0 -0
  38. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/asyncmy/__init__.py +0 -0
  39. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/asyncmy/_types.py +0 -0
  40. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/asyncmy/config.py +0 -0
  41. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/asyncmy/driver.py +0 -0
  42. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/asyncpg/__init__.py +0 -0
  43. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/asyncpg/_types.py +0 -0
  44. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/asyncpg/config.py +0 -0
  45. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/asyncpg/driver.py +0 -0
  46. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/bigquery/__init__.py +0 -0
  47. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/bigquery/_types.py +0 -0
  48. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/bigquery/config.py +0 -0
  49. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/bigquery/driver.py +0 -0
  50. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/duckdb/__init__.py +0 -0
  51. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/duckdb/_types.py +0 -0
  52. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/duckdb/config.py +0 -0
  53. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/duckdb/driver.py +0 -0
  54. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/duckdb/pool.py +0 -0
  55. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/oracledb/__init__.py +0 -0
  56. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/oracledb/_types.py +0 -0
  57. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/oracledb/config.py +0 -0
  58. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/oracledb/driver.py +0 -0
  59. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/oracledb/migrations.py +0 -0
  60. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/psqlpy/__init__.py +0 -0
  61. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/psqlpy/_types.py +0 -0
  62. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/psqlpy/config.py +0 -0
  63. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/psqlpy/driver.py +0 -0
  64. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/psycopg/__init__.py +0 -0
  65. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/psycopg/_types.py +0 -0
  66. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/psycopg/config.py +0 -0
  67. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/psycopg/driver.py +0 -0
  68. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/sqlite/__init__.py +0 -0
  69. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/sqlite/_types.py +0 -0
  70. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/sqlite/config.py +0 -0
  71. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/sqlite/driver.py +0 -0
  72. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/adapters/sqlite/pool.py +0 -0
  73. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/base.py +0 -0
  74. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/__init__.py +0 -0
  75. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/_column.py +0 -0
  76. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/_delete.py +0 -0
  77. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/_expression_wrappers.py +0 -0
  78. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/_merge.py +0 -0
  79. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/_select.py +0 -0
  80. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/mixins/__init__.py +0 -0
  81. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/mixins/_delete_operations.py +0 -0
  82. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/mixins/_insert_operations.py +0 -0
  83. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/mixins/_join_operations.py +0 -0
  84. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/mixins/_merge_operations.py +0 -0
  85. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/mixins/_order_limit_operations.py +0 -0
  86. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/mixins/_pivot_operations.py +0 -0
  87. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/mixins/_select_operations.py +0 -0
  88. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/builder/mixins/_update_operations.py +0 -0
  89. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/cli.py +0 -0
  90. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/config.py +0 -0
  91. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/core/__init__.py +0 -0
  92. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/core/cache.py +0 -0
  93. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/core/compiler.py +0 -0
  94. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/core/filters.py +0 -0
  95. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/core/hashing.py +0 -0
  96. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/core/parameters.py +0 -0
  97. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/core/result.py +0 -0
  98. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/core/splitter.py +0 -0
  99. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/core/statement.py +0 -0
  100. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/driver/__init__.py +0 -0
  101. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/driver/_async.py +0 -0
  102. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/driver/_common.py +0 -0
  103. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/driver/_sync.py +0 -0
  104. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/driver/mixins/__init__.py +0 -0
  105. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/driver/mixins/_result_tools.py +0 -0
  106. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/driver/mixins/_sql_translator.py +0 -0
  107. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/exceptions.py +0 -0
  108. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/extensions/__init__.py +0 -0
  109. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/extensions/aiosql/__init__.py +0 -0
  110. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/extensions/aiosql/adapter.py +0 -0
  111. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/extensions/litestar/__init__.py +0 -0
  112. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/extensions/litestar/_utils.py +0 -0
  113. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/extensions/litestar/cli.py +0 -0
  114. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/extensions/litestar/config.py +0 -0
  115. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/extensions/litestar/handlers.py +0 -0
  116. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/extensions/litestar/plugin.py +0 -0
  117. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/extensions/litestar/providers.py +0 -0
  118. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/loader.py +0 -0
  119. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/migrations/__init__.py +0 -0
  120. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/migrations/base.py +0 -0
  121. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/migrations/commands.py +0 -0
  122. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/migrations/loaders.py +0 -0
  123. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/migrations/runner.py +0 -0
  124. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/migrations/tracker.py +0 -0
  125. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/migrations/utils.py +0 -0
  126. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/protocols.py +0 -0
  127. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/py.typed +0 -0
  128. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/storage/__init__.py +0 -0
  129. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/storage/backends/__init__.py +0 -0
  130. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/storage/backends/base.py +0 -0
  131. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/storage/backends/fsspec.py +0 -0
  132. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/storage/backends/local.py +0 -0
  133. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/storage/backends/obstore.py +0 -0
  134. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/storage/registry.py +0 -0
  135. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/typing.py +0 -0
  136. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/utils/__init__.py +0 -0
  137. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/utils/correlation.py +0 -0
  138. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/utils/data_transformation.py +0 -0
  139. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/utils/deprecation.py +0 -0
  140. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/utils/fixtures.py +0 -0
  141. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/utils/logging.py +0 -0
  142. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/utils/module_loader.py +0 -0
  143. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/utils/serializers.py +0 -0
  144. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/utils/singleton.py +0 -0
  145. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/utils/sync_tools.py +0 -0
  146. {sqlspec-0.23.0 → sqlspec-0.24.0}/sqlspec/utils/text.py +0 -0
  147. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/__init__.py +0 -0
  148. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/conftest.py +0 -0
  149. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/__init__.py +0 -0
  150. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/asset_maintenance.sql +0 -0
  151. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/ddls-mysql-collection.sql +0 -0
  152. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/ddls-postgres-collection.sql +0 -0
  153. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/example_usage.py +0 -0
  154. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/init.sql +0 -0
  155. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/mysql/collection-config.sql +0 -0
  156. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/mysql/collection-data_types.sql +0 -0
  157. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/mysql/collection-database_details.sql +0 -0
  158. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/mysql/collection-engines.sql +0 -0
  159. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/mysql/collection-hostname.sql +0 -0
  160. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/mysql/collection-plugins.sql +0 -0
  161. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/mysql/collection-process_list.sql +0 -0
  162. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/mysql/collection-resource-groups.sql +0 -0
  163. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/mysql/collection-schema_objects.sql +0 -0
  164. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/mysql/collection-table_details.sql +0 -0
  165. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/mysql/collection-users.sql +0 -0
  166. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/mysql/init.sql +0 -0
  167. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/oracle.ddl.sql +0 -0
  168. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-applications.sql +0 -0
  169. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-aws_extension_dependency.sql +0 -0
  170. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-aws_oracle_exists.sql +0 -0
  171. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-bg_writer_stats.sql +0 -0
  172. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-calculated_metrics.sql +0 -0
  173. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-data_types.sql +0 -0
  174. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-database_details.sql +0 -0
  175. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-extensions.sql +0 -0
  176. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-index_details.sql +0 -0
  177. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-pglogical-details.sql +0 -0
  178. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-privileges.sql +0 -0
  179. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-replication_slots.sql +0 -0
  180. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-replication_stats.sql +0 -0
  181. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-schema_details.sql +0 -0
  182. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-schema_objects.sql +0 -0
  183. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-settings.sql +0 -0
  184. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-source_details.sql +0 -0
  185. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/collection-table_details.sql +0 -0
  186. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/extended-collection-all-databases.sql +0 -0
  187. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/postgres/init.sql +0 -0
  188. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/readiness-check.sql +0 -0
  189. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/fixtures/sql_utils.py +0 -0
  190. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/__init__.py +0 -0
  191. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/conftest.py +0 -0
  192. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/__init__.py +0 -0
  193. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_adbc/__init__.py +0 -0
  194. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_adbc/conftest.py +0 -0
  195. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_adbc/test_adbc_arrow_features.py +0 -0
  196. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_adbc/test_adbc_backends.py +0 -0
  197. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_adbc/test_adbc_connection.py +0 -0
  198. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_adbc/test_adbc_driver.py +0 -0
  199. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_adbc/test_adbc_edge_cases.py +0 -0
  200. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_adbc/test_adbc_results.py +0 -0
  201. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_adbc/test_migrations.py +0 -0
  202. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_adbc/test_parameter_styles.py +0 -0
  203. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_aiosqlite/__init__.py +0 -0
  204. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_aiosqlite/conftest.py +0 -0
  205. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_aiosqlite/test_connection.py +0 -0
  206. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_aiosqlite/test_driver.py +0 -0
  207. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_aiosqlite/test_migrations.py +0 -0
  208. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_aiosqlite/test_parameter_styles.py +0 -0
  209. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_aiosqlite/test_pooling.py +0 -0
  210. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_asyncmy/__init__.py +0 -0
  211. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_asyncmy/conftest.py +0 -0
  212. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_asyncmy/test_asyncmy_features.py +0 -0
  213. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_asyncmy/test_config.py +0 -0
  214. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_asyncmy/test_driver.py +0 -0
  215. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_asyncmy/test_migrations.py +0 -0
  216. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_asyncmy/test_parameter_styles.py +0 -0
  217. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_asyncpg/__init__.py +0 -0
  218. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_asyncpg/conftest.py +0 -0
  219. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_asyncpg/test_connection.py +0 -0
  220. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_asyncpg/test_driver.py +0 -0
  221. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_asyncpg/test_execute_many.py +0 -0
  222. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_asyncpg/test_migrations.py +0 -0
  223. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_asyncpg/test_parameter_styles.py +0 -0
  224. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_bigquery/__init__.py +0 -0
  225. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_bigquery/conftest.py +0 -0
  226. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_bigquery/test_bigquery_features.py +0 -0
  227. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_bigquery/test_config.py +0 -0
  228. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_bigquery/test_connection.py +0 -0
  229. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_bigquery/test_driver.py +0 -0
  230. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_duckdb/__init__.py +0 -0
  231. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_duckdb/test_connection.py +0 -0
  232. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_duckdb/test_driver.py +0 -0
  233. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_duckdb/test_execute_many.py +0 -0
  234. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_duckdb/test_migrations.py +0 -0
  235. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_duckdb/test_mixed_parameter_styles.py +0 -0
  236. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_duckdb/test_parameter_styles.py +0 -0
  237. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_duckdb/test_pooling.py +0 -0
  238. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_duckdb/utils.py +0 -0
  239. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_oracledb/__init__.py +0 -0
  240. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_oracledb/conftest.py +0 -0
  241. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_oracledb/test_connection.py +0 -0
  242. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_oracledb/test_driver_async.py +0 -0
  243. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_oracledb/test_driver_sync.py +0 -0
  244. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_oracledb/test_execute_many.py +0 -0
  245. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_oracledb/test_migrations.py +0 -0
  246. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_oracledb/test_oracle_features.py +0 -0
  247. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_oracledb/test_parameter_styles.py +0 -0
  248. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_psqlpy/__init__.py +0 -0
  249. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_psqlpy/conftest.py +0 -0
  250. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_psqlpy/test_connection.py +0 -0
  251. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_psqlpy/test_driver.py +0 -0
  252. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_psqlpy/test_migrations.py +0 -0
  253. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_psqlpy/test_parameter_styles.py +0 -0
  254. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_psqlpy/test_psqlpy_features.py +0 -0
  255. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_psycopg/__init__.py +0 -0
  256. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_psycopg/conftest.py +0 -0
  257. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_psycopg/test_async_copy.py +0 -0
  258. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_psycopg/test_connection.py +0 -0
  259. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_psycopg/test_driver.py +0 -0
  260. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_psycopg/test_execute_many.py +0 -0
  261. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_psycopg/test_migrations.py +0 -0
  262. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_psycopg/test_parameter_styles.py +0 -0
  263. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_sqlite/__init__.py +0 -0
  264. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_sqlite/conftest.py +0 -0
  265. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_sqlite/test_driver.py +0 -0
  266. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_sqlite/test_migrations.py +0 -0
  267. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_sqlite/test_parameter_styles.py +0 -0
  268. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_sqlite/test_pooling.py +0 -0
  269. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_adapters/test_sqlite/test_query_mixin.py +0 -0
  270. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_loader/__init__.py +0 -0
  271. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_loader/test_file_system_loading.py +0 -0
  272. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_migrations/__init__.py +0 -0
  273. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_storage/__init__.py +0 -0
  274. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/integration/test_storage/test_storage_integration.py +0 -0
  275. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/conftest.py +0 -0
  276. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_adapters/__init__.py +0 -0
  277. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_adapters/conftest.py +0 -0
  278. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_adapters/test_adapter_implementations.py +0 -0
  279. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_adapters/test_async_adapters.py +0 -0
  280. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_adapters/test_sync_adapters.py +0 -0
  281. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_base/__init__.py +0 -0
  282. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_base/test_sql_integration.py +0 -0
  283. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_base/test_sqlspec_class.py +0 -0
  284. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_builder/__init__.py +0 -0
  285. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_builder/test_insert_builder.py +0 -0
  286. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_builder/test_lateral_joins.py +0 -0
  287. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_builder/test_parameter_naming.py +0 -0
  288. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_builder_parameter_naming.py +0 -0
  289. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_core/test_cache.py +0 -0
  290. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_core/test_compiler.py +0 -0
  291. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_core/test_filters.py +0 -0
  292. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_core/test_hashing.py +0 -0
  293. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_core/test_parameters.py +0 -0
  294. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_core/test_result.py +0 -0
  295. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_core/test_statement.py +0 -0
  296. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_extensions/__init__.py +0 -0
  297. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_extensions/test_litestar/__init__.py +0 -0
  298. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_extensions/test_litestar/test_config.py +0 -0
  299. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_loader/__init__.py +0 -0
  300. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_loader/test_cache_integration.py +0 -0
  301. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_loader/test_fixtures_directory_loading.py +0 -0
  302. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_loader/test_loading_patterns.py +0 -0
  303. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_loader/test_sql_file_loader.py +0 -0
  304. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_migrations/__init__.py +0 -0
  305. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_migrations/test_migration.py +0 -0
  306. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_migrations/test_migration_commands.py +0 -0
  307. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_migrations/test_migration_execution.py +0 -0
  308. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_migrations/test_migration_runner.py +0 -0
  309. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_parsing_utils.py +0 -0
  310. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_sql_factory.py +0 -0
  311. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_storage/__init__.py +0 -0
  312. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_storage/test_fsspec_backend.py +0 -0
  313. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_storage/test_local_store.py +0 -0
  314. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_storage/test_obstore_backend.py +0 -0
  315. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_storage/test_storage_registry.py +0 -0
  316. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_utils/__init__.py +0 -0
  317. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_utils/test_correlation.py +0 -0
  318. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_utils/test_data_transformation.py +0 -0
  319. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_utils/test_deprecation.py +0 -0
  320. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_utils/test_fixtures.py +0 -0
  321. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_utils/test_logging.py +0 -0
  322. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_utils/test_module_loader.py +0 -0
  323. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_utils/test_serializers.py +0 -0
  324. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_utils/test_singleton.py +0 -0
  325. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_utils/test_sync_tools.py +0 -0
  326. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_utils/test_text.py +0 -0
  327. {sqlspec-0.23.0 → sqlspec-0.24.0}/tests/unit/test_utils/test_type_guards.py +0 -0
  328. {sqlspec-0.23.0 → sqlspec-0.24.0}/tools/__init__.py +0 -0
  329. {sqlspec-0.23.0 → sqlspec-0.24.0}/tools/build_docs.py +0 -0
  330. {sqlspec-0.23.0 → sqlspec-0.24.0}/tools/local-infra.sh +0 -0
  331. {sqlspec-0.23.0 → sqlspec-0.24.0}/tools/pypi_readme.py +0 -0
  332. {sqlspec-0.23.0 → sqlspec-0.24.0}/tools/sphinx_ext/__init__.py +0 -0
  333. {sqlspec-0.23.0 → sqlspec-0.24.0}/tools/sphinx_ext/changelog.py +0 -0
  334. {sqlspec-0.23.0 → sqlspec-0.24.0}/tools/sphinx_ext/missing_references.py +0 -0
@@ -17,7 +17,7 @@ repos:
17
17
  - id: mixed-line-ending
18
18
  - id: trailing-whitespace
19
19
  - repo: https://github.com/charliermarsh/ruff-pre-commit
20
- rev: "v0.12.11"
20
+ rev: "v0.12.12"
21
21
  hooks:
22
22
  - id: ruff
23
23
  args: ["--fix"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlspec
3
- Version: 0.23.0
3
+ Version: 0.24.0
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/
@@ -13,7 +13,7 @@ maintainers = [{ name = "Litestar Developers", email = "hello@litestar.dev" }]
13
13
  name = "sqlspec"
14
14
  readme = "README.md"
15
15
  requires-python = ">=3.9, <4.0"
16
- version = "0.23.0"
16
+ version = "0.24.0"
17
17
 
18
18
  [project.urls]
19
19
  Discord = "https://discord.gg/litestar"
@@ -19,7 +19,7 @@ from sqlspec.core.parameters import ParameterStyle, ParameterStyleConfig
19
19
  from sqlspec.core.statement import SQL, StatementConfig
20
20
  from sqlspec.exceptions import SQLBuilderError
21
21
  from sqlspec.utils.logging import get_logger
22
- from sqlspec.utils.type_guards import has_sql_method, has_with_method
22
+ from sqlspec.utils.type_guards import has_expression_and_parameters, has_sql_method, has_with_method
23
23
 
24
24
  if TYPE_CHECKING:
25
25
  from sqlspec.core.result import SQLResult
@@ -208,6 +208,43 @@ class QueryBuilder(ABC):
208
208
 
209
209
  return f"{base_name}_{uuid.uuid4().hex[:8]}"
210
210
 
211
+ def _merge_cte_parameters(self, cte_name: str, parameters: dict[str, Any]) -> dict[str, str]:
212
+ """Merge CTE parameters with unique naming to prevent collisions.
213
+
214
+ Args:
215
+ cte_name: The name of the CTE for parameter prefixing
216
+ parameters: The CTE's parameter dictionary
217
+
218
+ Returns:
219
+ Mapping of old parameter names to new unique names
220
+ """
221
+ param_mapping = {}
222
+ for old_name, value in parameters.items():
223
+ new_name = self._generate_unique_parameter_name(f"{cte_name}_{old_name}")
224
+ param_mapping[old_name] = new_name
225
+ self.add_parameter(value, name=new_name)
226
+ return param_mapping
227
+
228
+ def _update_placeholders_in_expression(
229
+ self, expression: exp.Expression, param_mapping: dict[str, str]
230
+ ) -> exp.Expression:
231
+ """Update parameter placeholders in expression to use new names.
232
+
233
+ Args:
234
+ expression: The SQLGlot expression to update
235
+ param_mapping: Mapping of old parameter names to new names
236
+
237
+ Returns:
238
+ Updated expression with new placeholder names
239
+ """
240
+
241
+ def placeholder_replacer(node: exp.Expression) -> exp.Expression:
242
+ if isinstance(node, exp.Placeholder) and str(node.this) in param_mapping:
243
+ return exp.Placeholder(this=param_mapping[str(node.this)])
244
+ return node
245
+
246
+ return expression.transform(placeholder_replacer, copy=False)
247
+
211
248
  def _generate_builder_cache_key(self, config: "Optional[StatementConfig]" = None) -> str:
212
249
  """Generate cache key based on builder state and configuration.
213
250
 
@@ -276,9 +313,12 @@ class QueryBuilder(ABC):
276
313
  msg = f"CTE query builder expression must be a Select, got {type(query._expression).__name__}."
277
314
  self._raise_sql_builder_error(msg)
278
315
  cte_select_expression = query._expression
279
- for p_name, p_value in query.parameters.items():
280
- unique_name = self._generate_unique_parameter_name(p_name)
281
- self.add_parameter(p_value, unique_name)
316
+ param_mapping = self._merge_cte_parameters(alias, query.parameters)
317
+ updated_expression = self._update_placeholders_in_expression(cte_select_expression, param_mapping)
318
+ if not isinstance(updated_expression, exp.Select):
319
+ msg = f"Updated CTE expression must be a Select, got {type(updated_expression).__name__}."
320
+ self._raise_sql_builder_error(msg)
321
+ cte_select_expression = updated_expression
282
322
 
283
323
  elif isinstance(query, str):
284
324
  try:
@@ -297,7 +337,6 @@ class QueryBuilder(ABC):
297
337
  else:
298
338
  msg = f"Invalid query type for CTE: {type(query).__name__}"
299
339
  self._raise_sql_builder_error(msg)
300
- return self
301
340
 
302
341
  self._with_ctes[alias] = exp.CTE(this=cte_select_expression, alias=exp.to_table(alias))
303
342
  return self
@@ -416,7 +455,7 @@ class QueryBuilder(ABC):
416
455
 
417
456
  if isinstance(safe_query.parameters, dict):
418
457
  kwargs = safe_query.parameters
419
- parameters: Optional[tuple] = None
458
+ parameters: Optional[tuple[Any, ...]] = None
420
459
  else:
421
460
  kwargs = None
422
461
  parameters = (
@@ -440,7 +479,7 @@ class QueryBuilder(ABC):
440
479
  config.dialect is not None
441
480
  and config.dialect != safe_query.dialect
442
481
  and self._expression is not None
443
- and hasattr(self._expression, "sql")
482
+ and has_sql_method(self._expression)
444
483
  ):
445
484
  try:
446
485
  sql_string = self._expression.sql(dialect=config.dialect, pretty=True)
@@ -459,26 +498,34 @@ class QueryBuilder(ABC):
459
498
  Returns:
460
499
  str: The SQL string for this query.
461
500
  """
462
- try:
463
- return self.build().sql
464
- except Exception:
465
- return super().__str__()
501
+ return self.build().sql
466
502
 
467
503
  @property
468
504
  def dialect_name(self) -> "Optional[str]":
469
505
  """Returns the name of the dialect, if set."""
470
506
  if isinstance(self.dialect, str):
471
507
  return self.dialect
472
- if self.dialect is not None:
473
- if isinstance(self.dialect, type) and issubclass(self.dialect, Dialect):
474
- return self.dialect.__name__.lower()
475
- if isinstance(self.dialect, Dialect):
476
- return type(self.dialect).__name__.lower()
477
- try:
478
- return self.dialect.__name__.lower()
479
- except AttributeError:
480
- pass
481
- return None
508
+ if self.dialect is None:
509
+ return None
510
+ if isinstance(self.dialect, type) and issubclass(self.dialect, Dialect):
511
+ return self.dialect.__name__.lower()
512
+ if isinstance(self.dialect, Dialect):
513
+ return type(self.dialect).__name__.lower()
514
+ return getattr(self.dialect, "__name__", str(self.dialect)).lower()
515
+
516
+ def _merge_sql_object_parameters(self, sql_obj: Any) -> None:
517
+ """Merge parameters from a SQL object into the builder.
518
+
519
+ Args:
520
+ sql_obj: Object with parameters attribute containing parameter mappings
521
+ """
522
+ if not has_expression_and_parameters(sql_obj):
523
+ return
524
+
525
+ sql_parameters = getattr(sql_obj, "parameters", {})
526
+ for param_name, param_value in sql_parameters.items():
527
+ unique_name = self._generate_unique_parameter_name(param_name)
528
+ self.add_parameter(param_value, name=unique_name)
482
529
 
483
530
  @property
484
531
  def parameters(self) -> dict[str, Any]:
@@ -12,6 +12,7 @@ from typing_extensions import Self
12
12
 
13
13
  from sqlspec.builder._base import QueryBuilder, SafeQuery
14
14
  from sqlspec.core.result import SQLResult
15
+ from sqlspec.utils.type_guards import has_sqlglot_expression, has_with_method
15
16
 
16
17
  if TYPE_CHECKING:
17
18
  from sqlspec.builder._column import ColumnExpression
@@ -436,8 +437,8 @@ class CreateTable(DDLBuilder):
436
437
  self._raise_sql_builder_error("Check constraint must have a condition")
437
438
 
438
439
  condition_str: str
439
- if hasattr(condition, "sqlglot_expression"):
440
- sqlglot_expr = getattr(condition, "sqlglot_expression", None)
440
+ if has_sqlglot_expression(condition):
441
+ sqlglot_expr = condition.sqlglot_expression
441
442
  condition_str = sqlglot_expr.sql(dialect=self.dialect) if sqlglot_expr else str(condition)
442
443
  else:
443
444
  condition_str = str(condition)
@@ -970,15 +971,15 @@ class CreateTableAsSelect(DDLBuilder):
970
971
 
971
972
  if isinstance(self._select_query, SQL):
972
973
  select_expr = self._select_query.expression
973
- select_parameters = getattr(self._select_query, "parameters", None)
974
+ select_parameters = self._select_query.parameters
974
975
  elif isinstance(self._select_query, Select):
975
- select_expr = getattr(self._select_query, "_expression", None)
976
- select_parameters = getattr(self._select_query, "_parameters", None)
976
+ select_expr = self._select_query._expression
977
+ select_parameters = self._select_query._parameters
977
978
 
978
- with_ctes = getattr(self._select_query, "_with_ctes", {})
979
+ with_ctes = self._select_query._with_ctes
979
980
  if with_ctes and select_expr and isinstance(select_expr, exp.Select):
980
981
  for alias, cte in with_ctes.items():
981
- if hasattr(select_expr, "with_"):
982
+ if has_with_method(select_expr):
982
983
  select_expr = select_expr.with_(cte.this, as_=alias, copy=False)
983
984
  elif isinstance(self._select_query, str):
984
985
  select_expr = exp.maybe_parse(self._select_query)
@@ -1097,10 +1098,10 @@ class CreateMaterializedView(DDLBuilder):
1097
1098
 
1098
1099
  if isinstance(self._select_query, SQL):
1099
1100
  select_expr = self._select_query.expression
1100
- select_parameters = getattr(self._select_query, "parameters", None)
1101
+ select_parameters = self._select_query.parameters
1101
1102
  elif isinstance(self._select_query, Select):
1102
- select_expr = getattr(self._select_query, "_expression", None)
1103
- select_parameters = getattr(self._select_query, "_parameters", None)
1103
+ select_expr = self._select_query._expression
1104
+ select_parameters = self._select_query._parameters
1104
1105
  elif isinstance(self._select_query, str):
1105
1106
  select_expr = exp.maybe_parse(self._select_query)
1106
1107
  select_parameters = None
@@ -1195,10 +1196,10 @@ class CreateView(DDLBuilder):
1195
1196
 
1196
1197
  if isinstance(self._select_query, SQL):
1197
1198
  select_expr = self._select_query.expression
1198
- select_parameters = getattr(self._select_query, "parameters", None)
1199
+ select_parameters = self._select_query.parameters
1199
1200
  elif isinstance(self._select_query, Select):
1200
- select_expr = getattr(self._select_query, "_expression", None)
1201
- select_parameters = getattr(self._select_query, "_parameters", None)
1201
+ select_expr = self._select_query._expression
1202
+ select_parameters = self._select_query._parameters
1202
1203
  elif isinstance(self._select_query, str):
1203
1204
  select_expr = exp.maybe_parse(self._select_query)
1204
1205
  select_parameters = None
@@ -13,6 +13,7 @@ from sqlspec.builder._base import QueryBuilder
13
13
  from sqlspec.builder.mixins import InsertFromSelectMixin, InsertIntoClauseMixin, InsertValuesMixin, ReturningClauseMixin
14
14
  from sqlspec.core.result import SQLResult
15
15
  from sqlspec.exceptions import SQLBuilderError
16
+ from sqlspec.utils.type_guards import has_expression_and_sql
16
17
 
17
18
  if TYPE_CHECKING:
18
19
  from collections.abc import Mapping, Sequence
@@ -124,12 +125,9 @@ class Insert(QueryBuilder, ReturningClauseMixin, InsertValuesMixin, InsertFromSe
124
125
  return self.values_from_dict(kwargs)
125
126
 
126
127
  if len(values) == 1:
127
- try:
128
- values_0 = values[0]
129
- if hasattr(values_0, "items"):
130
- return self.values_from_dict(values_0)
131
- except (AttributeError, TypeError):
132
- pass
128
+ values_0 = values[0]
129
+ if hasattr(values_0, "items") and hasattr(values_0, "keys"):
130
+ return self.values_from_dict(values_0)
133
131
 
134
132
  insert_expr = self._get_insert_expression()
135
133
 
@@ -141,24 +139,18 @@ class Insert(QueryBuilder, ReturningClauseMixin, InsertValuesMixin, InsertFromSe
141
139
  for i, value in enumerate(values):
142
140
  if isinstance(value, exp.Expression):
143
141
  value_placeholders.append(value)
144
- elif hasattr(value, "expression") and hasattr(value, "sql"):
142
+ elif has_expression_and_sql(value):
145
143
  # Handle SQL objects (from sql.raw with parameters)
146
144
  expression = getattr(value, "expression", None)
147
145
  if expression is not None and isinstance(expression, exp.Expression):
148
146
  # Merge parameters from SQL object into builder
149
- if hasattr(value, "parameters"):
150
- sql_parameters = getattr(value, "parameters", {})
151
- for param_name, param_value in sql_parameters.items():
152
- self.add_parameter(param_value, name=param_name)
147
+ self._merge_sql_object_parameters(value)
153
148
  value_placeholders.append(expression)
154
149
  else:
155
150
  # If expression is None, fall back to parsing the raw SQL
156
151
  sql_text = getattr(value, "sql", "")
157
152
  # Merge parameters even when parsing raw SQL
158
- if hasattr(value, "parameters"):
159
- sql_parameters = getattr(value, "parameters", {})
160
- for param_name, param_value in sql_parameters.items():
161
- self.add_parameter(param_value, name=param_name)
153
+ self._merge_sql_object_parameters(value)
162
154
  # Check if sql_text is callable (like Expression.sql method)
163
155
  if callable(sql_text):
164
156
  sql_text = str(value)
@@ -376,7 +368,7 @@ class ConflictBuilder:
376
368
  # Create SET expressions for the UPDATE
377
369
  set_expressions = []
378
370
  for col, val in kwargs.items():
379
- if hasattr(val, "expression") and hasattr(val, "sql"):
371
+ if has_expression_and_sql(val):
380
372
  # Handle SQL objects (from sql.raw with parameters)
381
373
  expression = getattr(val, "expression", None)
382
374
  if expression is not None and isinstance(expression, exp.Expression):
@@ -10,7 +10,12 @@ from typing import Any, Final, Optional, Union, cast
10
10
  from sqlglot import exp, maybe_parse, parse_one
11
11
 
12
12
  from sqlspec.core.parameters import ParameterStyle
13
- from sqlspec.utils.type_guards import has_expression_attr, has_parameter_builder
13
+ from sqlspec.utils.type_guards import (
14
+ has_expression_and_parameters,
15
+ has_expression_and_sql,
16
+ has_expression_attr,
17
+ has_parameter_builder,
18
+ )
14
19
 
15
20
 
16
21
  def parse_column_expression(
@@ -38,12 +43,12 @@ def parse_column_expression(
38
43
  return column_input
39
44
 
40
45
  # Handle SQL objects (from sql.raw with parameters)
41
- if hasattr(column_input, "expression") and hasattr(column_input, "sql"):
46
+ if has_expression_and_sql(column_input):
42
47
  # This is likely a SQL object
43
48
  expression = getattr(column_input, "expression", None)
44
49
  if expression is not None and isinstance(expression, exp.Expression):
45
50
  # Merge parameters from SQL object into builder if available
46
- if builder and hasattr(column_input, "parameters") and hasattr(builder, "add_parameter"):
51
+ if builder and has_expression_and_parameters(column_input) and hasattr(builder, "add_parameter"):
47
52
  sql_parameters = getattr(column_input, "parameters", {})
48
53
  for param_name, param_value in sql_parameters.items():
49
54
  builder.add_parameter(param_value, name=param_name)
@@ -51,19 +56,16 @@ def parse_column_expression(
51
56
  # If expression is None, fall back to parsing the raw SQL
52
57
  sql_text = getattr(column_input, "sql", "")
53
58
  # Merge parameters even when parsing raw SQL
54
- if builder and hasattr(column_input, "parameters") and hasattr(builder, "add_parameter"):
59
+ if builder and has_expression_and_parameters(column_input) and hasattr(builder, "add_parameter"):
55
60
  sql_parameters = getattr(column_input, "parameters", {})
56
61
  for param_name, param_value in sql_parameters.items():
57
62
  builder.add_parameter(param_value, name=param_name)
58
63
  return exp.maybe_parse(sql_text) or exp.column(str(sql_text))
59
64
 
60
65
  if has_expression_attr(column_input):
61
- try:
62
- attr_value = column_input._expression
63
- if isinstance(attr_value, exp.Expression):
64
- return attr_value
65
- except AttributeError:
66
- pass
66
+ attr_value = getattr(column_input, "_expression", None)
67
+ if isinstance(attr_value, exp.Expression):
68
+ return attr_value
67
69
 
68
70
  return exp.maybe_parse(column_input) or exp.column(str(column_input))
69
71
 
@@ -178,14 +180,10 @@ def parse_condition_expression(
178
180
  )
179
181
  condition_input = converted_condition
180
182
 
181
- try:
182
- return exp.condition(condition_input)
183
- except Exception:
184
- try:
185
- parsed = exp.maybe_parse(condition_input) # type: ignore[var-annotated]
186
- return parsed or exp.condition(condition_input)
187
- except Exception:
188
- return exp.condition(condition_input)
183
+ parsed: Optional[exp.Expression] = exp.maybe_parse(condition_input)
184
+ if parsed:
185
+ return parsed
186
+ return exp.condition(condition_input)
189
187
 
190
188
 
191
189
  __all__ = ("parse_column_expression", "parse_condition_expression", "parse_order_expression", "parse_table_expression")
@@ -176,7 +176,7 @@ class Update(
176
176
  msg = "No UPDATE expression to build or expression is of the wrong type."
177
177
  raise SQLBuilderError(msg)
178
178
 
179
- if getattr(self._expression, "this", None) is None:
179
+ if self._expression.this is None:
180
180
  msg = "No table specified for UPDATE statement."
181
181
  raise SQLBuilderError(msg)
182
182
 
@@ -31,6 +31,18 @@ class CommonTableExpressionMixin:
31
31
  msg = "Method must be provided by QueryBuilder subclass"
32
32
  raise NotImplementedError(msg)
33
33
 
34
+ def _generate_unique_parameter_name(self, base_name: str) -> str:
35
+ """Generate unique parameter name - provided by QueryBuilder."""
36
+ msg = "Method must be provided by QueryBuilder subclass"
37
+ raise NotImplementedError(msg)
38
+
39
+ def _update_placeholders_in_expression(
40
+ self, expression: exp.Expression, param_mapping: dict[str, str]
41
+ ) -> exp.Expression:
42
+ """Update parameter placeholders - provided by QueryBuilder."""
43
+ msg = "Method must be provided by QueryBuilder subclass"
44
+ raise NotImplementedError(msg)
45
+
34
46
  def with_(
35
47
  self, name: str, query: Union[Any, str], recursive: bool = False, columns: Optional[list[str]] = None
36
48
  ) -> Self:
@@ -69,8 +81,15 @@ class CommonTableExpressionMixin:
69
81
  parameters = built_query.parameters
70
82
  if parameters:
71
83
  if isinstance(parameters, dict):
84
+ param_mapping = {}
72
85
  for param_name, param_value in parameters.items():
73
- self.add_parameter(param_value, name=param_name)
86
+ unique_name = self._generate_unique_parameter_name(f"{name}_{param_name}")
87
+ param_mapping[param_name] = unique_name
88
+ self.add_parameter(param_value, name=unique_name)
89
+
90
+ # Update placeholders in the parsed expression
91
+ if cte_expr and param_mapping:
92
+ cte_expr = self._update_placeholders_in_expression(cte_expr, param_mapping)
74
93
  elif isinstance(parameters, (list, tuple)):
75
94
  for param_value in parameters:
76
95
  self.add_parameter(param_value)