sqlspec 0.15.0__tar.gz → 0.16.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 (299) hide show
  1. {sqlspec-0.15.0 → sqlspec-0.16.0}/PKG-INFO +1 -1
  2. {sqlspec-0.15.0 → sqlspec-0.16.0}/pyproject.toml +1 -1
  3. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/_sql.py +252 -29
  4. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/_insert.py +12 -1
  5. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/_parsing_utils.py +5 -1
  6. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/mixins/_insert_operations.py +12 -2
  7. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/mixins/_merge_operations.py +16 -4
  8. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/mixins/_select_operations.py +4 -2
  9. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/mixins/_update_operations.py +12 -2
  10. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/mixins/_where_clause.py +163 -63
  11. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/core/filters.py +12 -10
  12. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/core/statement.py +17 -2
  13. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/driver/mixins/_result_tools.py +12 -16
  14. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/extensions/litestar/cli.py +1 -1
  15. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/extensions/litestar/plugin.py +2 -2
  16. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/utils/sync_tools.py +1 -1
  17. sqlspec-0.16.0/tests/unit/test_builder/__init__.py +1 -0
  18. sqlspec-0.16.0/tests/unit/test_builder/test_parameter_naming.py +392 -0
  19. sqlspec-0.16.0/tests/unit/test_builder_parameter_naming.py +222 -0
  20. sqlspec-0.16.0/tests/unit/test_core/test_filters.py +257 -0
  21. sqlspec-0.16.0/tests/unit/test_sql_factory.py +462 -0
  22. {sqlspec-0.15.0 → sqlspec-0.16.0}/uv.lock +76 -72
  23. {sqlspec-0.15.0 → sqlspec-0.16.0}/.gitignore +0 -0
  24. {sqlspec-0.15.0 → sqlspec-0.16.0}/.pre-commit-config.yaml +0 -0
  25. {sqlspec-0.15.0 → sqlspec-0.16.0}/CONTRIBUTING.rst +0 -0
  26. {sqlspec-0.15.0 → sqlspec-0.16.0}/LICENSE +0 -0
  27. {sqlspec-0.15.0 → sqlspec-0.16.0}/Makefile +0 -0
  28. {sqlspec-0.15.0 → sqlspec-0.16.0}/NOTICE +0 -0
  29. {sqlspec-0.15.0 → sqlspec-0.16.0}/README.md +0 -0
  30. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/__init__.py +0 -0
  31. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/__main__.py +0 -0
  32. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/__metadata__.py +0 -0
  33. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/_serialization.py +0 -0
  34. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/_typing.py +0 -0
  35. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/__init__.py +0 -0
  36. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/adbc/__init__.py +0 -0
  37. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/adbc/_types.py +0 -0
  38. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/adbc/config.py +0 -0
  39. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/adbc/driver.py +0 -0
  40. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/aiosqlite/__init__.py +0 -0
  41. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/aiosqlite/_types.py +0 -0
  42. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/aiosqlite/config.py +0 -0
  43. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/aiosqlite/driver.py +0 -0
  44. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/asyncmy/__init__.py +0 -0
  45. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/asyncmy/_types.py +0 -0
  46. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/asyncmy/config.py +0 -0
  47. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/asyncmy/driver.py +0 -0
  48. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/asyncpg/__init__.py +0 -0
  49. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/asyncpg/_types.py +0 -0
  50. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/asyncpg/config.py +0 -0
  51. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/asyncpg/driver.py +0 -0
  52. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/bigquery/__init__.py +0 -0
  53. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/bigquery/_types.py +0 -0
  54. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/bigquery/config.py +0 -0
  55. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/bigquery/driver.py +0 -0
  56. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/duckdb/__init__.py +0 -0
  57. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/duckdb/_types.py +0 -0
  58. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/duckdb/config.py +0 -0
  59. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/duckdb/driver.py +0 -0
  60. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/oracledb/__init__.py +0 -0
  61. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/oracledb/_types.py +0 -0
  62. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/oracledb/config.py +0 -0
  63. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/oracledb/driver.py +0 -0
  64. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/psqlpy/__init__.py +0 -0
  65. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/psqlpy/_types.py +0 -0
  66. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/psqlpy/config.py +0 -0
  67. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/psqlpy/driver.py +0 -0
  68. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/psycopg/__init__.py +0 -0
  69. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/psycopg/_types.py +0 -0
  70. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/psycopg/config.py +0 -0
  71. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/psycopg/driver.py +0 -0
  72. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/sqlite/__init__.py +0 -0
  73. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/sqlite/_types.py +0 -0
  74. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/sqlite/config.py +0 -0
  75. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/adapters/sqlite/driver.py +0 -0
  76. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/base.py +0 -0
  77. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/__init__.py +0 -0
  78. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/_base.py +0 -0
  79. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/_column.py +0 -0
  80. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/_ddl.py +0 -0
  81. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/_ddl_utils.py +0 -0
  82. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/_delete.py +0 -0
  83. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/_merge.py +0 -0
  84. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/_select.py +0 -0
  85. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/_update.py +0 -0
  86. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/mixins/__init__.py +0 -0
  87. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/mixins/_cte_and_set_ops.py +0 -0
  88. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/mixins/_delete_operations.py +0 -0
  89. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/mixins/_join_operations.py +0 -0
  90. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/mixins/_order_limit_operations.py +0 -0
  91. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/builder/mixins/_pivot_operations.py +0 -0
  92. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/cli.py +0 -0
  93. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/config.py +0 -0
  94. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/core/__init__.py +0 -0
  95. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/core/cache.py +0 -0
  96. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/core/compiler.py +0 -0
  97. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/core/hashing.py +0 -0
  98. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/core/parameters.py +0 -0
  99. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/core/result.py +0 -0
  100. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/core/splitter.py +0 -0
  101. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/driver/__init__.py +0 -0
  102. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/driver/_async.py +0 -0
  103. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/driver/_common.py +0 -0
  104. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/driver/_sync.py +0 -0
  105. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/driver/mixins/__init__.py +0 -0
  106. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/driver/mixins/_sql_translator.py +0 -0
  107. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/exceptions.py +0 -0
  108. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/extensions/__init__.py +0 -0
  109. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/extensions/aiosql/__init__.py +0 -0
  110. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/extensions/aiosql/adapter.py +0 -0
  111. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/extensions/litestar/__init__.py +0 -0
  112. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/extensions/litestar/_utils.py +0 -0
  113. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/extensions/litestar/config.py +0 -0
  114. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/extensions/litestar/handlers.py +0 -0
  115. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/extensions/litestar/providers.py +0 -0
  116. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/loader.py +0 -0
  117. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/migrations/__init__.py +0 -0
  118. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/migrations/base.py +0 -0
  119. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/migrations/commands.py +0 -0
  120. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/migrations/loaders.py +0 -0
  121. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/migrations/runner.py +0 -0
  122. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/migrations/tracker.py +0 -0
  123. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/migrations/utils.py +0 -0
  124. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/protocols.py +0 -0
  125. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/py.typed +0 -0
  126. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/storage/__init__.py +0 -0
  127. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/storage/backends/__init__.py +0 -0
  128. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/storage/backends/base.py +0 -0
  129. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/storage/backends/fsspec.py +0 -0
  130. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/storage/backends/obstore.py +0 -0
  131. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/storage/capabilities.py +0 -0
  132. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/storage/registry.py +0 -0
  133. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/typing.py +0 -0
  134. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/utils/__init__.py +0 -0
  135. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/utils/correlation.py +0 -0
  136. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/utils/deprecation.py +0 -0
  137. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/utils/fixtures.py +0 -0
  138. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/utils/logging.py +0 -0
  139. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/utils/module_loader.py +0 -0
  140. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/utils/serializers.py +0 -0
  141. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/utils/singleton.py +0 -0
  142. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/utils/text.py +0 -0
  143. {sqlspec-0.15.0 → sqlspec-0.16.0}/sqlspec/utils/type_guards.py +0 -0
  144. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/__init__.py +0 -0
  145. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/conftest.py +0 -0
  146. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/__init__.py +0 -0
  147. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/ddls-mysql-collection.sql +0 -0
  148. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/ddls-postgres-collection.sql +0 -0
  149. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/example_usage.py +0 -0
  150. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/init.sql +0 -0
  151. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/mysql/collection-config.sql +0 -0
  152. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/mysql/collection-data_types.sql +0 -0
  153. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/mysql/collection-database_details.sql +0 -0
  154. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/mysql/collection-engines.sql +0 -0
  155. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/mysql/collection-hostname.sql +0 -0
  156. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/mysql/collection-plugins.sql +0 -0
  157. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/mysql/collection-process_list.sql +0 -0
  158. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/mysql/collection-resource-groups.sql +0 -0
  159. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/mysql/collection-schema_objects.sql +0 -0
  160. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/mysql/collection-table_details.sql +0 -0
  161. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/mysql/collection-users.sql +0 -0
  162. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/mysql/init.sql +0 -0
  163. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/oracle.ddl.sql +0 -0
  164. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-applications.sql +0 -0
  165. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-aws_extension_dependency.sql +0 -0
  166. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-aws_oracle_exists.sql +0 -0
  167. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-bg_writer_stats.sql +0 -0
  168. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-calculated_metrics.sql +0 -0
  169. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-data_types.sql +0 -0
  170. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-database_details.sql +0 -0
  171. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-extensions.sql +0 -0
  172. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-index_details.sql +0 -0
  173. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-pglogical-details.sql +0 -0
  174. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-privileges.sql +0 -0
  175. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-replication_slots.sql +0 -0
  176. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-replication_stats.sql +0 -0
  177. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-schema_details.sql +0 -0
  178. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-schema_objects.sql +0 -0
  179. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-settings.sql +0 -0
  180. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-source_details.sql +0 -0
  181. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/collection-table_details.sql +0 -0
  182. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/extended-collection-all-databases.sql +0 -0
  183. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/postgres/init.sql +0 -0
  184. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/readiness-check.sql +0 -0
  185. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/fixtures/sql_utils.py +0 -0
  186. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/__init__.py +0 -0
  187. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/conftest.py +0 -0
  188. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/__init__.py +0 -0
  189. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_adbc/__init__.py +0 -0
  190. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_adbc/conftest.py +0 -0
  191. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_adbc/test_adbc_arrow_features.py +0 -0
  192. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_adbc/test_adbc_backends.py +0 -0
  193. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_adbc/test_adbc_connection.py +0 -0
  194. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_adbc/test_adbc_driver.py +0 -0
  195. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_adbc/test_adbc_edge_cases.py +0 -0
  196. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_adbc/test_adbc_results.py +0 -0
  197. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_aiosqlite/__init__.py +0 -0
  198. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_aiosqlite/conftest.py +0 -0
  199. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_aiosqlite/test_connection.py +0 -0
  200. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_aiosqlite/test_driver.py +0 -0
  201. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_aiosqlite/test_pooling.py +0 -0
  202. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_asyncmy/__init__.py +0 -0
  203. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_asyncmy/conftest.py +0 -0
  204. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_asyncmy/test_asyncmy_features.py +0 -0
  205. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_asyncmy/test_config.py +0 -0
  206. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_asyncmy/test_driver.py +0 -0
  207. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_asyncmy/test_parameter_styles.py +0 -0
  208. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_asyncpg/__init__.py +0 -0
  209. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_asyncpg/conftest.py +0 -0
  210. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_asyncpg/test_connection.py +0 -0
  211. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_asyncpg/test_driver.py +0 -0
  212. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_asyncpg/test_execute_many.py +0 -0
  213. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_asyncpg/test_parameter_styles.py +0 -0
  214. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_bigquery/__init__.py +0 -0
  215. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_bigquery/conftest.py +0 -0
  216. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_bigquery/test_bigquery_features.py +0 -0
  217. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_bigquery/test_config.py +0 -0
  218. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_bigquery/test_connection.py +0 -0
  219. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_bigquery/test_driver.py +0 -0
  220. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_bigquery/test_parameter_styles.py +0 -0
  221. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_duckdb/__init__.py +0 -0
  222. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_duckdb/test_connection.py +0 -0
  223. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_duckdb/test_driver.py +0 -0
  224. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_duckdb/test_execute_many.py +0 -0
  225. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_duckdb/test_mixed_parameter_styles.py +0 -0
  226. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_duckdb/test_parameter_styles.py +0 -0
  227. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_duckdb/test_pooling.py +0 -0
  228. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_duckdb/utils.py +0 -0
  229. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_oracledb/__init__.py +0 -0
  230. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_oracledb/conftest.py +0 -0
  231. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_oracledb/test_connection.py +0 -0
  232. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_oracledb/test_driver_async.py +0 -0
  233. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_oracledb/test_driver_sync.py +0 -0
  234. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_oracledb/test_execute_many.py +0 -0
  235. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_oracledb/test_oracle_features.py +0 -0
  236. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_oracledb/test_parameter_styles.py +0 -0
  237. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_psqlpy/__init__.py +0 -0
  238. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_psqlpy/conftest.py +0 -0
  239. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_psqlpy/test_connection.py +0 -0
  240. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_psqlpy/test_driver.py +0 -0
  241. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_psqlpy/test_parameter_styles.py +0 -0
  242. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_psqlpy/test_psqlpy_features.py +0 -0
  243. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_psycopg/__init__.py +0 -0
  244. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_psycopg/conftest.py +0 -0
  245. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_psycopg/test_async_copy.py +0 -0
  246. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_psycopg/test_connection.py +0 -0
  247. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_psycopg/test_driver.py +0 -0
  248. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_psycopg/test_execute_many.py +0 -0
  249. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_psycopg/test_parameter_styles.py +0 -0
  250. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_sqlite/__init__.py +0 -0
  251. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_sqlite/conftest.py +0 -0
  252. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_sqlite/test_driver.py +0 -0
  253. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_sqlite/test_parameter_styles.py +0 -0
  254. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_sqlite/test_pooling.py +0 -0
  255. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_adapters/test_sqlite/test_query_mixin.py +0 -0
  256. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_loader/__init__.py +0 -0
  257. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_loader/test_file_system_loading.py +0 -0
  258. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_migrations/__init__.py +0 -0
  259. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/integration/test_migrations/test_migration_execution.py +0 -0
  260. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/conftest.py +0 -0
  261. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_adapters/__init__.py +0 -0
  262. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_adapters/conftest.py +0 -0
  263. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_adapters/test_adapter_implementations.py +0 -0
  264. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_adapters/test_async_adapters.py +0 -0
  265. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_adapters/test_sync_adapters.py +0 -0
  266. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_base/__init__.py +0 -0
  267. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_base/test_sqlspec_class.py +0 -0
  268. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_core/test_cache.py +0 -0
  269. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_core/test_compiler.py +0 -0
  270. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_core/test_hashing.py +0 -0
  271. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_core/test_parameters.py +0 -0
  272. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_core/test_result.py +0 -0
  273. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_core/test_statement.py +0 -0
  274. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_loader/__init__.py +0 -0
  275. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_loader/test_cache_integration.py +0 -0
  276. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_loader/test_loading_patterns.py +0 -0
  277. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_loader/test_sql_file_loader.py +0 -0
  278. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_migrations/__init__.py +0 -0
  279. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_migrations/test_migration.py +0 -0
  280. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_migrations/test_migration_execution.py +0 -0
  281. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_migrations/test_migration_runner.py +0 -0
  282. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_utils/__init__.py +0 -0
  283. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_utils/test_correlation.py +0 -0
  284. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_utils/test_deprecation.py +0 -0
  285. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_utils/test_fixtures.py +0 -0
  286. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_utils/test_logging.py +0 -0
  287. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_utils/test_module_loader.py +0 -0
  288. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_utils/test_serializers.py +0 -0
  289. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_utils/test_singleton.py +0 -0
  290. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_utils/test_sync_tools.py +0 -0
  291. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_utils/test_text.py +0 -0
  292. {sqlspec-0.15.0 → sqlspec-0.16.0}/tests/unit/test_utils/test_type_guards.py +0 -0
  293. {sqlspec-0.15.0 → sqlspec-0.16.0}/tools/__init__.py +0 -0
  294. {sqlspec-0.15.0 → sqlspec-0.16.0}/tools/build_docs.py +0 -0
  295. {sqlspec-0.15.0 → sqlspec-0.16.0}/tools/local-infra.sh +0 -0
  296. {sqlspec-0.15.0 → sqlspec-0.16.0}/tools/pypi_readme.py +0 -0
  297. {sqlspec-0.15.0 → sqlspec-0.16.0}/tools/sphinx_ext/__init__.py +0 -0
  298. {sqlspec-0.15.0 → sqlspec-0.16.0}/tools/sphinx_ext/changelog.py +0 -0
  299. {sqlspec-0.15.0 → sqlspec-0.16.0}/tools/sphinx_ext/missing_references.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlspec
3
- Version: 0.15.0
3
+ Version: 0.16.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.15.0"
16
+ version = "0.16.0"
17
17
 
18
18
  [project.urls]
19
19
  Discord = "https://discord.gg/litestar"
@@ -4,17 +4,65 @@ Provides both statement builders (select, insert, update, etc.) and column expre
4
4
  """
5
5
 
6
6
  import logging
7
- from typing import Any, Optional, Union
7
+ from typing import TYPE_CHECKING, Any, Optional, Union
8
8
 
9
9
  import sqlglot
10
10
  from sqlglot import exp
11
11
  from sqlglot.dialects.dialect import DialectType
12
12
  from sqlglot.errors import ParseError as SQLGlotParseError
13
13
 
14
- from sqlspec.builder import Column, Delete, Insert, Merge, Select, Truncate, Update
14
+ from sqlspec.builder import (
15
+ AlterTable,
16
+ Column,
17
+ CommentOn,
18
+ CreateIndex,
19
+ CreateMaterializedView,
20
+ CreateSchema,
21
+ CreateTable,
22
+ CreateTableAsSelect,
23
+ CreateView,
24
+ Delete,
25
+ DropIndex,
26
+ DropSchema,
27
+ DropTable,
28
+ DropView,
29
+ Insert,
30
+ Merge,
31
+ RenameTable,
32
+ Select,
33
+ Truncate,
34
+ Update,
35
+ )
15
36
  from sqlspec.exceptions import SQLBuilderError
16
37
 
17
- __all__ = ("Case", "Column", "Delete", "Insert", "Merge", "SQLFactory", "Select", "Truncate", "Update", "sql")
38
+ if TYPE_CHECKING:
39
+ from sqlspec.core.statement import SQL
40
+
41
+ __all__ = (
42
+ "AlterTable",
43
+ "Case",
44
+ "Column",
45
+ "CommentOn",
46
+ "CreateIndex",
47
+ "CreateMaterializedView",
48
+ "CreateSchema",
49
+ "CreateTable",
50
+ "CreateTableAsSelect",
51
+ "CreateView",
52
+ "Delete",
53
+ "DropIndex",
54
+ "DropSchema",
55
+ "DropTable",
56
+ "DropView",
57
+ "Insert",
58
+ "Merge",
59
+ "RenameTable",
60
+ "SQLFactory",
61
+ "Select",
62
+ "Truncate",
63
+ "Update",
64
+ "sql",
65
+ )
18
66
 
19
67
  logger = logging.getLogger("sqlspec")
20
68
 
@@ -212,6 +260,174 @@ class SQLFactory:
212
260
  return builder.into(table_or_sql)
213
261
  return builder
214
262
 
263
+ # ===================
264
+ # DDL Statement Builders
265
+ # ===================
266
+
267
+ def create_table(self, table_name: str, dialect: DialectType = None) -> "CreateTable":
268
+ """Create a CREATE TABLE builder.
269
+
270
+ Args:
271
+ table_name: Name of the table to create
272
+ dialect: Optional SQL dialect
273
+
274
+ Returns:
275
+ CreateTable builder instance
276
+ """
277
+ builder = CreateTable(table_name)
278
+ builder.dialect = dialect or self.dialect
279
+ return builder
280
+
281
+ def create_table_as_select(self, dialect: DialectType = None) -> "CreateTableAsSelect":
282
+ """Create a CREATE TABLE AS SELECT builder.
283
+
284
+ Args:
285
+ dialect: Optional SQL dialect
286
+
287
+ Returns:
288
+ CreateTableAsSelect builder instance
289
+ """
290
+ builder = CreateTableAsSelect()
291
+ builder.dialect = dialect or self.dialect
292
+ return builder
293
+
294
+ def create_view(self, dialect: DialectType = None) -> "CreateView":
295
+ """Create a CREATE VIEW builder.
296
+
297
+ Args:
298
+ dialect: Optional SQL dialect
299
+
300
+ Returns:
301
+ CreateView builder instance
302
+ """
303
+ builder = CreateView()
304
+ builder.dialect = dialect or self.dialect
305
+ return builder
306
+
307
+ def create_materialized_view(self, dialect: DialectType = None) -> "CreateMaterializedView":
308
+ """Create a CREATE MATERIALIZED VIEW builder.
309
+
310
+ Args:
311
+ dialect: Optional SQL dialect
312
+
313
+ Returns:
314
+ CreateMaterializedView builder instance
315
+ """
316
+ builder = CreateMaterializedView()
317
+ builder.dialect = dialect or self.dialect
318
+ return builder
319
+
320
+ def create_index(self, index_name: str, dialect: DialectType = None) -> "CreateIndex":
321
+ """Create a CREATE INDEX builder.
322
+
323
+ Args:
324
+ index_name: Name of the index to create
325
+ dialect: Optional SQL dialect
326
+
327
+ Returns:
328
+ CreateIndex builder instance
329
+ """
330
+ return CreateIndex(index_name, dialect=dialect or self.dialect)
331
+
332
+ def create_schema(self, dialect: DialectType = None) -> "CreateSchema":
333
+ """Create a CREATE SCHEMA builder.
334
+
335
+ Args:
336
+ dialect: Optional SQL dialect
337
+
338
+ Returns:
339
+ CreateSchema builder instance
340
+ """
341
+ builder = CreateSchema()
342
+ builder.dialect = dialect or self.dialect
343
+ return builder
344
+
345
+ def drop_table(self, table_name: str, dialect: DialectType = None) -> "DropTable":
346
+ """Create a DROP TABLE builder.
347
+
348
+ Args:
349
+ table_name: Name of the table to drop
350
+ dialect: Optional SQL dialect
351
+
352
+ Returns:
353
+ DropTable builder instance
354
+ """
355
+ return DropTable(table_name, dialect=dialect or self.dialect)
356
+
357
+ def drop_view(self, dialect: DialectType = None) -> "DropView":
358
+ """Create a DROP VIEW builder.
359
+
360
+ Args:
361
+ dialect: Optional SQL dialect
362
+
363
+ Returns:
364
+ DropView builder instance
365
+ """
366
+ return DropView(dialect=dialect or self.dialect)
367
+
368
+ def drop_index(self, index_name: str, dialect: DialectType = None) -> "DropIndex":
369
+ """Create a DROP INDEX builder.
370
+
371
+ Args:
372
+ index_name: Name of the index to drop
373
+ dialect: Optional SQL dialect
374
+
375
+ Returns:
376
+ DropIndex builder instance
377
+ """
378
+ return DropIndex(index_name, dialect=dialect or self.dialect)
379
+
380
+ def drop_schema(self, dialect: DialectType = None) -> "DropSchema":
381
+ """Create a DROP SCHEMA builder.
382
+
383
+ Args:
384
+ dialect: Optional SQL dialect
385
+
386
+ Returns:
387
+ DropSchema builder instance
388
+ """
389
+ return DropSchema(dialect=dialect or self.dialect)
390
+
391
+ def alter_table(self, table_name: str, dialect: DialectType = None) -> "AlterTable":
392
+ """Create an ALTER TABLE builder.
393
+
394
+ Args:
395
+ table_name: Name of the table to alter
396
+ dialect: Optional SQL dialect
397
+
398
+ Returns:
399
+ AlterTable builder instance
400
+ """
401
+ builder = AlterTable(table_name)
402
+ builder.dialect = dialect or self.dialect
403
+ return builder
404
+
405
+ def rename_table(self, dialect: DialectType = None) -> "RenameTable":
406
+ """Create a RENAME TABLE builder.
407
+
408
+ Args:
409
+ dialect: Optional SQL dialect
410
+
411
+ Returns:
412
+ RenameTable builder instance
413
+ """
414
+ builder = RenameTable()
415
+ builder.dialect = dialect or self.dialect
416
+ return builder
417
+
418
+ def comment_on(self, dialect: DialectType = None) -> "CommentOn":
419
+ """Create a COMMENT ON builder.
420
+
421
+ Args:
422
+ dialect: Optional SQL dialect
423
+
424
+ Returns:
425
+ CommentOn builder instance
426
+ """
427
+ builder = CommentOn()
428
+ builder.dialect = dialect or self.dialect
429
+ return builder
430
+
215
431
  # ===================
216
432
  # SQL Analysis Helpers
217
433
  # ===================
@@ -363,8 +579,8 @@ class SQLFactory:
363
579
  # ===================
364
580
 
365
581
  @staticmethod
366
- def raw(sql_fragment: str) -> exp.Expression:
367
- """Create a raw SQL expression from a string fragment.
582
+ def raw(sql_fragment: str, **parameters: Any) -> "Union[exp.Expression, SQL]":
583
+ """Create a raw SQL expression from a string fragment with optional parameters.
368
584
 
369
585
  This method makes it explicit that you are passing raw SQL that should
370
586
  be parsed and included directly in the query. Useful for complex expressions,
@@ -372,30 +588,30 @@ class SQLFactory:
372
588
 
373
589
  Args:
374
590
  sql_fragment: Raw SQL string to parse into an expression.
591
+ **parameters: Named parameters for parameter binding.
375
592
 
376
593
  Returns:
377
- SQLGlot expression from the parsed SQL fragment.
594
+ SQLGlot expression from the parsed SQL fragment (if no parameters).
595
+ SQL statement object (if parameters provided).
378
596
 
379
597
  Raises:
380
598
  SQLBuilderError: If the SQL fragment cannot be parsed.
381
599
 
382
600
  Example:
383
601
  ```python
384
- # Raw column expression with alias
385
- query = sql.select(
386
- sql.raw("user.id AS u_id"), "name"
387
- ).from_("users")
602
+ # Raw expression without parameters (current behavior)
603
+ expr = sql.raw("COALESCE(name, 'Unknown')")
388
604
 
389
- # Raw function call
390
- query = sql.select(
391
- sql.raw("COALESCE(name, 'Unknown')")
392
- ).from_("users")
605
+ # Raw SQL with named parameters (new functionality)
606
+ stmt = sql.raw(
607
+ "LOWER(name) LIKE LOWER(:pattern)", pattern=f"%{query}%"
608
+ )
393
609
 
394
- # Raw complex expression
395
- query = (
396
- sql.select("*")
397
- .from_("orders")
398
- .where(sql.raw("DATE(created_at) = CURRENT_DATE"))
610
+ # Raw complex expression with parameters
611
+ expr = sql.raw(
612
+ "price BETWEEN :min_price AND :max_price",
613
+ min_price=100,
614
+ max_price=500,
399
615
  )
400
616
 
401
617
  # Raw window function
@@ -407,16 +623,23 @@ class SQLFactory:
407
623
  ).from_("employees")
408
624
  ```
409
625
  """
410
- try:
411
- parsed: Optional[exp.Expression] = exp.maybe_parse(sql_fragment)
412
- if parsed is not None:
413
- return parsed
414
- if sql_fragment.strip().replace("_", "").replace(".", "").isalnum():
415
- return exp.to_identifier(sql_fragment)
416
- return exp.Literal.string(sql_fragment)
417
- except Exception as e:
418
- msg = f"Failed to parse raw SQL fragment '{sql_fragment}': {e}"
419
- raise SQLBuilderError(msg) from e
626
+ if not parameters:
627
+ # Original behavior - return pure expression
628
+ try:
629
+ parsed: Optional[exp.Expression] = exp.maybe_parse(sql_fragment)
630
+ if parsed is not None:
631
+ return parsed
632
+ if sql_fragment.strip().replace("_", "").replace(".", "").isalnum():
633
+ return exp.to_identifier(sql_fragment)
634
+ return exp.Literal.string(sql_fragment)
635
+ except Exception as e:
636
+ msg = f"Failed to parse raw SQL fragment '{sql_fragment}': {e}"
637
+ raise SQLBuilderError(msg) from e
638
+
639
+ # New behavior - return SQL statement with parameters
640
+ from sqlspec.core.statement import SQL
641
+
642
+ return SQL(sql_fragment, parameters)
420
643
 
421
644
  # ===================
422
645
  # Aggregate Functions
@@ -119,7 +119,18 @@ class Insert(QueryBuilder, ReturningClauseMixin, InsertValuesMixin, InsertFromSe
119
119
  msg = ERR_MSG_VALUES_COLUMNS_MISMATCH.format(values_len=len(values), columns_len=len(self._columns))
120
120
  raise SQLBuilderError(msg)
121
121
 
122
- param_names = [self._add_parameter(value) for value in values]
122
+ param_names = []
123
+ for i, value in enumerate(values):
124
+ # Try to use column name if available, otherwise use position-based name
125
+ if self._columns and i < len(self._columns):
126
+ column_name = (
127
+ str(self._columns[i]).split(".")[-1] if "." in str(self._columns[i]) else str(self._columns[i])
128
+ )
129
+ param_name = self._generate_unique_parameter_name(column_name)
130
+ else:
131
+ param_name = self._generate_unique_parameter_name(f"value_{i + 1}")
132
+ _, param_name = self.add_parameter(value, name=param_name)
133
+ param_names.append(param_name)
123
134
  value_placeholders = tuple(exp.var(name) for name in param_names)
124
135
 
125
136
  current_values_expression = insert_expr.args.get("expression")
@@ -109,7 +109,11 @@ def parse_condition_expression(
109
109
  if value is None:
110
110
  return exp.Is(this=column_expr, expression=exp.null())
111
111
  if builder and has_parameter_builder(builder):
112
- _, param_name = builder.add_parameter(value)
112
+ from sqlspec.builder.mixins._where_clause import _extract_column_name
113
+
114
+ column_name = _extract_column_name(column)
115
+ param_name = builder._generate_unique_parameter_name(column_name)
116
+ _, param_name = builder.add_parameter(value, name=param_name)
113
117
  return exp.EQ(this=column_expr, expression=exp.Placeholder(this=param_name))
114
118
  if isinstance(value, str):
115
119
  return exp.EQ(this=column_expr, expression=exp.convert(value))
@@ -78,11 +78,21 @@ class InsertValuesMixin:
78
78
  except AttributeError:
79
79
  pass
80
80
  row_exprs = []
81
- for v in values:
81
+ for i, v in enumerate(values):
82
82
  if isinstance(v, exp.Expression):
83
83
  row_exprs.append(v)
84
84
  else:
85
- _, param_name = self.add_parameter(v) # type: ignore[attr-defined]
85
+ # Try to use column name if available, otherwise use position-based name
86
+ try:
87
+ _columns = self._columns # type: ignore[attr-defined]
88
+ if _columns and i < len(_columns):
89
+ column_name = str(_columns[i]).split(".")[-1] if "." in str(_columns[i]) else str(_columns[i])
90
+ param_name = self._generate_unique_parameter_name(column_name) # type: ignore[attr-defined]
91
+ else:
92
+ param_name = self._generate_unique_parameter_name(f"value_{i + 1}") # type: ignore[attr-defined]
93
+ except AttributeError:
94
+ param_name = self._generate_unique_parameter_name(f"value_{i + 1}") # type: ignore[attr-defined]
95
+ _, param_name = self.add_parameter(v, name=param_name) # type: ignore[attr-defined]
86
96
  row_exprs.append(exp.var(param_name))
87
97
  values_expr = exp.Values(expressions=[row_exprs])
88
98
  self._expression.set("expression", values_expr)
@@ -172,7 +172,11 @@ class MergeMatchedClauseMixin:
172
172
  """
173
173
  update_expressions: list[exp.EQ] = []
174
174
  for col, val in set_values.items():
175
- param_name = self.add_parameter(val)[1] # type: ignore[attr-defined]
175
+ column_name = col if isinstance(col, str) else str(col)
176
+ if "." in column_name:
177
+ column_name = column_name.split(".")[-1]
178
+ param_name = self._generate_unique_parameter_name(column_name) # type: ignore[attr-defined]
179
+ param_name = self.add_parameter(val, name=param_name)[1] # type: ignore[attr-defined]
176
180
  update_expressions.append(exp.EQ(this=exp.column(col), expression=exp.var(param_name)))
177
181
 
178
182
  when_args: dict[str, Any] = {"matched": True, "then": exp.Update(expressions=update_expressions)}
@@ -270,8 +274,12 @@ class MergeNotMatchedClauseMixin:
270
274
  raise SQLBuilderError(msg)
271
275
 
272
276
  parameterized_values: list[exp.Expression] = []
273
- for val in values:
274
- param_name = self.add_parameter(val)[1] # type: ignore[attr-defined]
277
+ for i, val in enumerate(values):
278
+ column_name = columns[i] if isinstance(columns[i], str) else str(columns[i])
279
+ if "." in column_name:
280
+ column_name = column_name.split(".")[-1]
281
+ param_name = self._generate_unique_parameter_name(column_name) # type: ignore[attr-defined]
282
+ param_name = self.add_parameter(val, name=param_name)[1] # type: ignore[attr-defined]
275
283
  parameterized_values.append(exp.var(param_name))
276
284
 
277
285
  insert_args["this"] = exp.Tuple(expressions=[exp.column(c) for c in columns])
@@ -336,7 +344,11 @@ class MergeNotMatchedBySourceClauseMixin:
336
344
  """
337
345
  update_expressions: list[exp.EQ] = []
338
346
  for col, val in set_values.items():
339
- param_name = self.add_parameter(val)[1] # type: ignore[attr-defined]
347
+ column_name = col if isinstance(col, str) else str(col)
348
+ if "." in column_name:
349
+ column_name = column_name.split(".")[-1]
350
+ param_name = self._generate_unique_parameter_name(column_name) # type: ignore[attr-defined]
351
+ param_name = self.add_parameter(val, name=param_name)[1] # type: ignore[attr-defined]
340
352
  update_expressions.append(exp.EQ(this=exp.column(col), expression=exp.var(param_name)))
341
353
 
342
354
  when_args: dict[str, Any] = {
@@ -563,7 +563,8 @@ class CaseBuilder:
563
563
  CaseBuilder: The current builder instance for method chaining.
564
564
  """
565
565
  cond_expr = exp.condition(condition) if isinstance(condition, str) else condition
566
- param_name = self._parent.add_parameter(value)[1]
566
+ param_name = self._parent._generate_unique_parameter_name("case_when_value")
567
+ param_name = self._parent.add_parameter(value, name=param_name)[1]
567
568
  value_expr = exp.Placeholder(this=param_name)
568
569
 
569
570
  when_clause = exp.When(this=cond_expr, then=value_expr)
@@ -582,7 +583,8 @@ class CaseBuilder:
582
583
  Returns:
583
584
  CaseBuilder: The current builder instance for method chaining.
584
585
  """
585
- param_name = self._parent.add_parameter(value)[1]
586
+ param_name = self._parent._generate_unique_parameter_name("case_else_value")
587
+ param_name = self._parent.add_parameter(value, name=param_name)[1]
586
588
  value_expr = exp.Placeholder(this=param_name)
587
589
  self._case_expr.set("default", value_expr)
588
590
  return self
@@ -81,7 +81,12 @@ class UpdateSetClauseMixin:
81
81
  for p_name, p_value in val.parameters.items():
82
82
  self.add_parameter(p_value, name=p_name) # type: ignore[attr-defined]
83
83
  else:
84
- param_name = self.add_parameter(val)[1] # type: ignore[attr-defined]
84
+ column_name = col if isinstance(col, str) else str(col)
85
+ # Extract just the column part if table.column format
86
+ if "." in column_name:
87
+ column_name = column_name.split(".")[-1]
88
+ param_name = self._generate_unique_parameter_name(column_name) # type: ignore[attr-defined]
89
+ param_name = self.add_parameter(val, name=param_name)[1] # type: ignore[attr-defined]
85
90
  value_expr = exp.Placeholder(this=param_name)
86
91
  assignments.append(exp.EQ(this=col_expr, expression=value_expr))
87
92
  elif (len(args) == 1 and isinstance(args[0], Mapping)) or kwargs:
@@ -97,7 +102,12 @@ class UpdateSetClauseMixin:
97
102
  for p_name, p_value in val.parameters.items():
98
103
  self.add_parameter(p_value, name=p_name) # type: ignore[attr-defined]
99
104
  else:
100
- param_name = self.add_parameter(val)[1] # type: ignore[attr-defined]
105
+ # Extract column name for parameter naming
106
+ column_name = col if isinstance(col, str) else str(col)
107
+ if "." in column_name:
108
+ column_name = column_name.split(".")[-1]
109
+ param_name = self._generate_unique_parameter_name(column_name) # type: ignore[attr-defined]
110
+ param_name = self.add_parameter(val, name=param_name)[1] # type: ignore[attr-defined]
101
111
  value_expr = exp.Placeholder(this=param_name)
102
112
  assignments.append(exp.EQ(this=exp.column(col), expression=value_expr))
103
113
  else: