sqlspec 0.14.0__tar.gz → 0.14.1__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 (364) hide show
  1. {sqlspec-0.14.0 → sqlspec-0.14.1}/PKG-INFO +1 -1
  2. {sqlspec-0.14.0 → sqlspec-0.14.1}/pyproject.toml +3 -3
  3. sqlspec-0.14.1/sqlspec/__main__.py +12 -0
  4. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/adbc/config.py +12 -0
  5. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/adbc/driver.py +14 -0
  6. sqlspec-0.14.1/sqlspec/adapters/adbc/transformers.py +108 -0
  7. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/parameters.py +14 -54
  8. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/context.py +2 -8
  9. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/sql.py +4 -4
  10. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_data_types.py +0 -3
  11. sqlspec-0.14.1/tests/integration/test_adapters/test_adbc/test_null_params.py +121 -0
  12. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_postgres_driver.py +0 -5
  13. sqlspec-0.14.1/tests/unit/test_adapters/test_adbc/test_transformers.py +147 -0
  14. {sqlspec-0.14.0 → sqlspec-0.14.1}/uv.lock +1 -1
  15. {sqlspec-0.14.0 → sqlspec-0.14.1}/.gitignore +0 -0
  16. {sqlspec-0.14.0 → sqlspec-0.14.1}/.pre-commit-config.yaml +0 -0
  17. {sqlspec-0.14.0 → sqlspec-0.14.1}/CONTRIBUTING.rst +0 -0
  18. {sqlspec-0.14.0 → sqlspec-0.14.1}/LICENSE +0 -0
  19. {sqlspec-0.14.0 → sqlspec-0.14.1}/Makefile +0 -0
  20. {sqlspec-0.14.0 → sqlspec-0.14.1}/NOTICE +0 -0
  21. {sqlspec-0.14.0 → sqlspec-0.14.1}/README.md +0 -0
  22. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/__init__.py +0 -0
  23. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/__metadata__.py +0 -0
  24. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/_serialization.py +0 -0
  25. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/_sql.py +0 -0
  26. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/_typing.py +0 -0
  27. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/__init__.py +0 -0
  28. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/adbc/__init__.py +0 -0
  29. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/aiosqlite/__init__.py +0 -0
  30. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/aiosqlite/config.py +0 -0
  31. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/aiosqlite/driver.py +0 -0
  32. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/asyncmy/__init__.py +0 -0
  33. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/asyncmy/config.py +0 -0
  34. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/asyncmy/driver.py +0 -0
  35. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/asyncpg/__init__.py +0 -0
  36. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/asyncpg/config.py +0 -0
  37. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/asyncpg/driver.py +0 -0
  38. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/bigquery/__init__.py +0 -0
  39. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/bigquery/config.py +0 -0
  40. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/bigquery/driver.py +0 -0
  41. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/duckdb/__init__.py +0 -0
  42. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/duckdb/config.py +0 -0
  43. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/duckdb/driver.py +0 -0
  44. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/oracledb/__init__.py +0 -0
  45. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/oracledb/config.py +0 -0
  46. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/oracledb/driver.py +0 -0
  47. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/psqlpy/__init__.py +0 -0
  48. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/psqlpy/config.py +0 -0
  49. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/psqlpy/driver.py +0 -0
  50. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/psycopg/__init__.py +0 -0
  51. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/psycopg/config.py +0 -0
  52. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/psycopg/driver.py +0 -0
  53. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/sqlite/__init__.py +0 -0
  54. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/sqlite/config.py +0 -0
  55. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/sqlite/driver.py +0 -0
  56. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/base.py +0 -0
  57. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/cli.py +0 -0
  58. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/config.py +0 -0
  59. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/__init__.py +0 -0
  60. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/_async.py +0 -0
  61. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/_common.py +0 -0
  62. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/_sync.py +0 -0
  63. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/connection.py +0 -0
  64. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/__init__.py +0 -0
  65. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_cache.py +0 -0
  66. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_csv_writer.py +0 -0
  67. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_pipeline.py +0 -0
  68. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_query_tools.py +0 -0
  69. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_result_utils.py +0 -0
  70. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_sql_translator.py +0 -0
  71. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_storage.py +0 -0
  72. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_type_coercion.py +0 -0
  73. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/parameters.py +0 -0
  74. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/exceptions.py +0 -0
  75. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/__init__.py +0 -0
  76. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/aiosql/__init__.py +0 -0
  77. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/aiosql/adapter.py +0 -0
  78. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/litestar/__init__.py +0 -0
  79. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/litestar/_utils.py +0 -0
  80. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/litestar/cli.py +0 -0
  81. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/litestar/config.py +0 -0
  82. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/litestar/handlers.py +0 -0
  83. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/litestar/plugin.py +0 -0
  84. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/litestar/providers.py +0 -0
  85. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/loader.py +0 -0
  86. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/migrations/__init__.py +0 -0
  87. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/migrations/base.py +0 -0
  88. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/migrations/commands.py +0 -0
  89. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/migrations/runner.py +0 -0
  90. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/migrations/tracker.py +0 -0
  91. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/migrations/utils.py +0 -0
  92. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/protocols.py +0 -0
  93. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/py.typed +0 -0
  94. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/__init__.py +0 -0
  95. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/__init__.py +0 -0
  96. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_base.py +0 -0
  97. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_column.py +0 -0
  98. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_ddl.py +0 -0
  99. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_ddl_utils.py +0 -0
  100. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_delete.py +0 -0
  101. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_insert.py +0 -0
  102. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_merge.py +0 -0
  103. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_parsing_utils.py +0 -0
  104. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_select.py +0 -0
  105. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_update.py +0 -0
  106. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/__init__.py +0 -0
  107. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_cte_and_set_ops.py +0 -0
  108. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_delete_operations.py +0 -0
  109. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_insert_operations.py +0 -0
  110. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_join_operations.py +0 -0
  111. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_merge_operations.py +0 -0
  112. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_order_limit_operations.py +0 -0
  113. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_pivot_operations.py +0 -0
  114. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_select_operations.py +0 -0
  115. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_update_operations.py +0 -0
  116. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_where_clause.py +0 -0
  117. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/cache.py +0 -0
  118. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/filters.py +0 -0
  119. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/__init__.py +0 -0
  120. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/analyzers/__init__.py +0 -0
  121. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/analyzers/_analyzer.py +0 -0
  122. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/transformers/__init__.py +0 -0
  123. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/transformers/_expression_simplifier.py +0 -0
  124. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +0 -0
  125. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/transformers/_remove_comments_and_hints.py +0 -0
  126. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/validators/__init__.py +0 -0
  127. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/validators/_dml_safety.py +0 -0
  128. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/validators/_parameter_style.py +0 -0
  129. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/validators/_performance.py +0 -0
  130. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/validators/_security.py +0 -0
  131. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/result.py +0 -0
  132. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/splitter.py +0 -0
  133. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/storage/__init__.py +0 -0
  134. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/storage/backends/__init__.py +0 -0
  135. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/storage/backends/base.py +0 -0
  136. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/storage/backends/fsspec.py +0 -0
  137. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/storage/backends/obstore.py +0 -0
  138. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/storage/capabilities.py +0 -0
  139. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/storage/registry.py +0 -0
  140. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/typing.py +0 -0
  141. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/__init__.py +0 -0
  142. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/cached_property.py +0 -0
  143. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/correlation.py +0 -0
  144. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/deprecation.py +0 -0
  145. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/fixtures.py +0 -0
  146. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/logging.py +0 -0
  147. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/module_loader.py +0 -0
  148. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/serializers.py +0 -0
  149. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/singleton.py +0 -0
  150. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/statement_hashing.py +0 -0
  151. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/sync_tools.py +0 -0
  152. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/text.py +0 -0
  153. {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/type_guards.py +0 -0
  154. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/__init__.py +0 -0
  155. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/conftest.py +0 -0
  156. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/__init__.py +0 -0
  157. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/ddls-mysql-collection.sql +0 -0
  158. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/ddls-postgres-collection.sql +0 -0
  159. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/example_usage.py +0 -0
  160. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/init.sql +0 -0
  161. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-config.sql +0 -0
  162. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-data_types.sql +0 -0
  163. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-database_details.sql +0 -0
  164. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-engines.sql +0 -0
  165. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-hostname.sql +0 -0
  166. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-plugins.sql +0 -0
  167. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-process_list.sql +0 -0
  168. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-resource-groups.sql +0 -0
  169. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-schema_objects.sql +0 -0
  170. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-table_details.sql +0 -0
  171. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-users.sql +0 -0
  172. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/init.sql +0 -0
  173. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/oracle.ddl.sql +0 -0
  174. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-applications.sql +0 -0
  175. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-aws_extension_dependency.sql +0 -0
  176. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-aws_oracle_exists.sql +0 -0
  177. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-bg_writer_stats.sql +0 -0
  178. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-calculated_metrics.sql +0 -0
  179. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-data_types.sql +0 -0
  180. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-database_details.sql +0 -0
  181. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-extensions.sql +0 -0
  182. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-index_details.sql +0 -0
  183. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-pglogical-details.sql +0 -0
  184. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-privileges.sql +0 -0
  185. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-replication_slots.sql +0 -0
  186. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-replication_stats.sql +0 -0
  187. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-schema_details.sql +0 -0
  188. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-schema_objects.sql +0 -0
  189. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-settings.sql +0 -0
  190. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-source_details.sql +0 -0
  191. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-table_details.sql +0 -0
  192. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/extended-collection-all-databases.sql +0 -0
  193. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/init.sql +0 -0
  194. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/readiness-check.sql +0 -0
  195. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/sql_utils.py +0 -0
  196. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/__init__.py +0 -0
  197. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/__init__.py +0 -0
  198. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/__init__.py +0 -0
  199. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/conftest.py +0 -0
  200. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_arrow_functionality.py +0 -0
  201. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_bigquery_driver.py +0 -0
  202. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_connection.py +0 -0
  203. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_driver.py +0 -0
  204. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_duckdb_driver.py +0 -0
  205. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_execute_many.py +0 -0
  206. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_execute_script.py +0 -0
  207. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_parameter_styles.py +0 -0
  208. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_returning.py +0 -0
  209. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_sqlite_driver.py +0 -0
  210. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_aiosqlite/__init__.py +0 -0
  211. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_aiosqlite/test_driver.py +0 -0
  212. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncmy/__init__.py +0 -0
  213. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncmy/test_config.py +0 -0
  214. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncpg/__init__.py +0 -0
  215. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncpg/conftest.py +0 -0
  216. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncpg/test_arrow_functionality.py +0 -0
  217. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncpg/test_connection.py +0 -0
  218. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncpg/test_driver.py +0 -0
  219. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncpg/test_execute_many.py +0 -0
  220. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncpg/test_parameter_styles.py +0 -0
  221. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_bigquery/__init__.py +0 -0
  222. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_bigquery/conftest.py +0 -0
  223. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_bigquery/test_arrow_functionality.py +0 -0
  224. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_bigquery/test_connection.py +0 -0
  225. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_bigquery/test_driver.py +0 -0
  226. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_duckdb/__init__.py +0 -0
  227. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_duckdb/test_arrow_functionality.py +0 -0
  228. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_duckdb/test_connection.py +0 -0
  229. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_duckdb/test_driver.py +0 -0
  230. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_duckdb/test_execute_many.py +0 -0
  231. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_duckdb/test_mixed_parameter_styles.py +0 -0
  232. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_duckdb/test_parameter_styles.py +0 -0
  233. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_oracledb/__init__.py +0 -0
  234. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_oracledb/test_connection.py +0 -0
  235. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_oracledb/test_driver_async.py +0 -0
  236. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_oracledb/test_driver_sync.py +0 -0
  237. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psqlpy/__init__.py +0 -0
  238. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psqlpy/test_arrow_functionality.py +0 -0
  239. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psqlpy/test_connection.py +0 -0
  240. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psqlpy/test_driver.py +0 -0
  241. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psycopg/__init__.py +0 -0
  242. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psycopg/conftest.py +0 -0
  243. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psycopg/test_async_copy.py +0 -0
  244. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psycopg/test_connection.py +0 -0
  245. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psycopg/test_driver.py +0 -0
  246. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psycopg/test_execute_many.py +0 -0
  247. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psycopg/test_parameter_styles.py +0 -0
  248. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_sqlite/__init__.py +0 -0
  249. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_sqlite/test_driver.py +0 -0
  250. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_sqlite/test_query_mixin.py +0 -0
  251. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_dialect_propagation.py +0 -0
  252. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_driver_mixins/__init__.py +0 -0
  253. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_extensions/__init__.py +0 -0
  254. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_extensions/test_aiosql/__init__.py +0 -0
  255. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_extensions/test_litestar/__init__.py +0 -0
  256. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_sql_file_loader.py +0 -0
  257. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_storage/__init__.py +0 -0
  258. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_storage/test_driver_storage_integration.py +0 -0
  259. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_storage/test_end_to_end_workflows.py +0 -0
  260. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_storage/test_storage_mixins.py +0 -0
  261. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/__init__.py +0 -0
  262. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/statement/test_cache.py +0 -0
  263. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/__init__.py +0 -0
  264. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_adbc/__init__.py +0 -0
  265. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_adbc/test_config.py +0 -0
  266. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_adbc/test_driver.py +0 -0
  267. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_aiosqlite/__init__.py +0 -0
  268. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_aiosqlite/test_config.py +0 -0
  269. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_aiosqlite/test_driver.py +0 -0
  270. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_asyncmy/__init__.py +0 -0
  271. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_asyncmy/test_driver.py +0 -0
  272. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_asyncpg/__init__.py +0 -0
  273. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_asyncpg/test_config.py +0 -0
  274. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_asyncpg/test_driver.py +0 -0
  275. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_bigquery/__init__.py +0 -0
  276. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_bigquery/test_config.py +0 -0
  277. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_bigquery/test_driver.py +0 -0
  278. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_cache_mixin.py +0 -0
  279. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_duckdb/__init__.py +0 -0
  280. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_duckdb/test_config.py +0 -0
  281. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_duckdb/test_driver.py +0 -0
  282. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_oracledb/__init__.py +0 -0
  283. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_oracledb/test_config.py +0 -0
  284. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_oracledb/test_driver.py +0 -0
  285. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_psqlpy/__init__.py +0 -0
  286. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_psqlpy/test_config.py +0 -0
  287. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_psqlpy/test_driver.py +0 -0
  288. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_psycopg/__init__.py +0 -0
  289. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_psycopg/test_config.py +0 -0
  290. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_psycopg/test_driver.py +0 -0
  291. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_sqlite/__init__.py +0 -0
  292. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_sqlite/test_config.py +0 -0
  293. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_sqlite/test_driver.py +0 -0
  294. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_base.py +0 -0
  295. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_config.py +0 -0
  296. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_config_dialect.py +0 -0
  297. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_driver.py +0 -0
  298. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_driver_mixins/__init__.py +0 -0
  299. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_driver_mixins/test_query_mixin.py +0 -0
  300. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_exceptions.py +0 -0
  301. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_extensions/__init__.py +0 -0
  302. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_extensions/test_aiosql/test_adapter.py +0 -0
  303. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_loader.py +0 -0
  304. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/__init__.py +0 -0
  305. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_base.py +0 -0
  306. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/__init__.py +0 -0
  307. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_base.py +0 -0
  308. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_builder_mixins.py +0 -0
  309. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_column.py +0 -0
  310. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_delete.py +0 -0
  311. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_dynamic_columns.py +0 -0
  312. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_insert.py +0 -0
  313. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_merge.py +0 -0
  314. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_select.py +0 -0
  315. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_update.py +0 -0
  316. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_config.py +0 -0
  317. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_filters.py +0 -0
  318. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_mixins.py +0 -0
  319. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_oracle_numeric_parameters.py +0 -0
  320. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_parameter_normalization.py +0 -0
  321. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_parameter_preservation.py +0 -0
  322. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_parameters.py +0 -0
  323. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/__init__.py +0 -0
  324. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_analyzer.py +0 -0
  325. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_analyzer_subquery_detection.py +0 -0
  326. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_expression_simplifier.py +0 -0
  327. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_literal_parameterizer_duplication.py +0 -0
  328. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_transformers_literal_parameterizer.py +0 -0
  329. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_transformers_literal_parameterizer_cte.py +0 -0
  330. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_transformers_remove_comments.py +0 -0
  331. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_validators_dml_safety.py +0 -0
  332. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_validators_parameter_style.py +0 -0
  333. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_validators_performance.py +0 -0
  334. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_validators_security.py +0 -0
  335. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_result.py +0 -0
  336. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_splitter.py +0 -0
  337. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_sql.py +0 -0
  338. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_sql_as_many.py +0 -0
  339. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_sql_translator_mixin.py +0 -0
  340. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_sqlfactory.py +0 -0
  341. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_storage.py +0 -0
  342. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_transformers/test_expression_simplifier_parameter_tracking.py +0 -0
  343. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_typed_parameter.py +0 -0
  344. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_storage/__init__.py +0 -0
  345. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_storage/test_backends/__init__.py +0 -0
  346. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_storage/test_backends/test_fsspec_backend.py +0 -0
  347. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_storage/test_backends/test_obstore_backend.py +0 -0
  348. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_storage/test_base.py +0 -0
  349. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_storage/test_registry.py +0 -0
  350. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_typing.py +0 -0
  351. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_utils/__init__.py +0 -0
  352. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_utils/test_deprecation.py +0 -0
  353. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_utils/test_fixtures.py +0 -0
  354. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_utils/test_module_loader.py +0 -0
  355. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_utils/test_singleton.py +0 -0
  356. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_utils/test_sync_tools.py +0 -0
  357. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_utils/test_text.py +0 -0
  358. {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/utils/test_ast_hashing.py +0 -0
  359. {sqlspec-0.14.0 → sqlspec-0.14.1}/tools/__init__.py +0 -0
  360. {sqlspec-0.14.0 → sqlspec-0.14.1}/tools/build_docs.py +0 -0
  361. {sqlspec-0.14.0 → sqlspec-0.14.1}/tools/pypi_readme.py +0 -0
  362. {sqlspec-0.14.0 → sqlspec-0.14.1}/tools/sphinx_ext/__init__.py +0 -0
  363. {sqlspec-0.14.0 → sqlspec-0.14.1}/tools/sphinx_ext/changelog.py +0 -0
  364. {sqlspec-0.14.0 → sqlspec-0.14.1}/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.14.0
3
+ Version: 0.14.1
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/
@@ -7,7 +7,7 @@ maintainers = [{ name = "Litestar Developers", email = "hello@litestar.dev" }]
7
7
  name = "sqlspec"
8
8
  readme = "README.md"
9
9
  requires-python = ">=3.9, <4.0"
10
- version = "0.14.0"
10
+ version = "0.14.1"
11
11
 
12
12
  [project.urls]
13
13
  Discord = "https://discord.gg/litestar"
@@ -109,7 +109,7 @@ test = [
109
109
  ]
110
110
 
111
111
  [project.scripts]
112
- sqlspec = "sqlspec.cli:run_cli"
112
+ sqlspec = "sqlspec.__main__:run_cli"
113
113
 
114
114
  [build-system]
115
115
  build-backend = "hatchling.build"
@@ -131,7 +131,7 @@ packages = ["sqlspec"]
131
131
  allow_dirty = true
132
132
  commit = false
133
133
  commit_args = "--no-verify"
134
- current_version = "0.14.0"
134
+ current_version = "0.14.1"
135
135
  ignore_missing_files = false
136
136
  ignore_missing_version = false
137
137
  message = "chore(release): bump to v{new_version}"
@@ -0,0 +1,12 @@
1
+ from sqlspec.cli import add_migration_commands as build_cli_interface
2
+
3
+ __all__ = ("run_cli",)
4
+
5
+
6
+ def run_cli() -> None: # pragma: no cover
7
+ """SQLSpec CLI"""
8
+ build_cli_interface()()
9
+
10
+
11
+ if __name__ == "__main__": # pragma: no cover
12
+ run_cli()
@@ -6,6 +6,7 @@ from dataclasses import replace
6
6
  from typing import TYPE_CHECKING, Any, Callable, ClassVar, Optional
7
7
 
8
8
  from sqlspec.adapters.adbc.driver import AdbcConnection, AdbcDriver
9
+ from sqlspec.adapters.adbc.transformers import AdbcPostgresTransformer
9
10
  from sqlspec.config import NoPoolSyncConfig
10
11
  from sqlspec.exceptions import ImproperConfigurationError
11
12
  from sqlspec.statement.sql import SQLConfig
@@ -434,6 +435,17 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
434
435
  default_parameter_style=preferred_style,
435
436
  )
436
437
 
438
+ # Add ADBC PostgreSQL transformer if needed
439
+ if self._get_dialect() == "postgres":
440
+ # Get the default transformers from the pipeline
441
+ pipeline = statement_config.get_statement_pipeline()
442
+ existing_transformers = list(pipeline.transformers)
443
+
444
+ # Append our transformer to the existing ones
445
+ existing_transformers.append(AdbcPostgresTransformer())
446
+
447
+ statement_config = replace(statement_config, transformers=existing_transformers)
448
+
437
449
  driver = self.driver_type(connection=connection, config=statement_config)
438
450
  yield driver
439
451
 
@@ -220,6 +220,9 @@ class AdbcDriver(
220
220
 
221
221
  with self._get_cursor(txn_conn) as cursor:
222
222
  try:
223
+ # ADBC PostgreSQL has issues with NULL parameters in some cases
224
+ # The transformer handles all-NULL cases, but mixed NULL/non-NULL
225
+ # can still cause "Can't map Arrow type 'na' to Postgres type" errors
223
226
  cursor.execute(sql, cursor_params or [])
224
227
  except Exception as e:
225
228
  # Rollback transaction on error for PostgreSQL to avoid
@@ -265,6 +268,17 @@ class AdbcDriver(
265
268
  # Normalize parameter list using consolidated utility
266
269
  converted_param_list = convert_parameter_sequence(param_list)
267
270
 
271
+ # Handle empty parameter list case for PostgreSQL
272
+ if not converted_param_list and self.dialect == "postgres":
273
+ # Return empty result without executing
274
+ return SQLResult(
275
+ statement=SQL(sql, _dialect=self.dialect),
276
+ data=[],
277
+ rows_affected=0,
278
+ operation_type="EXECUTE",
279
+ metadata={"status_message": "OK"},
280
+ )
281
+
268
282
  with self._get_cursor(txn_conn) as cursor:
269
283
  try:
270
284
  cursor.executemany(sql, converted_param_list or [])
@@ -0,0 +1,108 @@
1
+ """ADBC-specific AST transformers for handling driver limitations."""
2
+
3
+ from typing import Optional
4
+
5
+ from sqlglot import exp
6
+
7
+ from sqlspec.protocols import ProcessorProtocol
8
+ from sqlspec.statement.pipelines.context import SQLProcessingContext
9
+
10
+ __all__ = ("AdbcPostgresTransformer",)
11
+
12
+
13
+ class AdbcPostgresTransformer(ProcessorProtocol):
14
+ """Transformer to handle ADBC PostgreSQL driver limitations.
15
+
16
+ This transformer addresses specific issues with the ADBC PostgreSQL driver:
17
+ 1. Empty parameter lists in executemany() causing "no parameter $1" errors
18
+ 2. NULL parameters causing "Can't map Arrow type 'na' to Postgres type" errors
19
+
20
+ The transformer works at the AST level to properly handle these edge cases.
21
+ """
22
+
23
+ def __init__(self) -> None:
24
+ self.has_placeholders = False
25
+ self.all_params_null = False
26
+ self.is_empty_params = False
27
+ self.has_null_params = False
28
+ self.null_param_indices: list[int] = []
29
+
30
+ def process(self, expression: Optional[exp.Expression], context: SQLProcessingContext) -> Optional[exp.Expression]:
31
+ """Process the SQL expression to handle ADBC limitations."""
32
+ if not expression:
33
+ return expression
34
+
35
+ # Check if we have an empty parameter list for executemany
36
+ # Look at the merged_parameters in the context
37
+ params = context.merged_parameters
38
+
39
+ # For execute_many, check if we have an empty list
40
+ if isinstance(params, list) and len(params) == 0:
41
+ self.is_empty_params = True
42
+
43
+ # Check for NULL parameters
44
+ if params:
45
+ if isinstance(params, (list, tuple)):
46
+ # Track which parameters are NULL
47
+ self.null_param_indices = [i for i, p in enumerate(params) if p is None]
48
+ self.has_null_params = len(self.null_param_indices) > 0
49
+ self.all_params_null = len(self.null_param_indices) == len(params)
50
+
51
+ # For ADBC PostgreSQL, we need to replace NULL parameters with literals
52
+ # and remove them from the parameter list
53
+ if self.has_null_params:
54
+ # Create new parameter list without NULLs
55
+ new_params = [p for p in params if p is not None]
56
+ context.merged_parameters = new_params
57
+
58
+ elif isinstance(params, dict):
59
+ # For dict parameters, track which ones are NULL
60
+ null_keys = [k for k, v in params.items() if v is None]
61
+ self.has_null_params = len(null_keys) > 0
62
+ self.all_params_null = len(null_keys) == len(params)
63
+
64
+ if self.has_null_params:
65
+ # Remove NULL parameters from dict
66
+ context.merged_parameters = {k: v for k, v in params.items() if v is not None}
67
+
68
+ # Transform the AST if needed
69
+ if self.is_empty_params:
70
+ # For empty parameters, we should skip transformation and let the driver handle it
71
+ # The driver already has logic to return empty result for empty params
72
+ return expression
73
+
74
+ if self.has_null_params:
75
+ # Transform placeholders to NULL literals where needed
76
+ self._parameter_index = 0 # Track current parameter position
77
+ return expression.transform(self._transform_node)
78
+
79
+ return expression
80
+
81
+ def _transform_node(self, node: exp.Expression) -> exp.Expression:
82
+ """Transform individual AST nodes."""
83
+ # Handle parameter nodes (e.g., $1, $2, etc. in PostgreSQL)
84
+ if isinstance(node, exp.Parameter):
85
+ # Access the parameter value directly from the AST node
86
+ # The 'this' attribute contains a Literal node, whose 'this' contains the actual value
87
+ if node.this and isinstance(node.this, exp.Literal):
88
+ try:
89
+ param_index = int(node.this.this) - 1 # Convert to 0-based index
90
+ # Check if this parameter should be NULL
91
+ if param_index in self.null_param_indices:
92
+ return exp.Null()
93
+ # Renumber the parameter based on how many NULLs came before it
94
+ nulls_before = sum(1 for idx in self.null_param_indices if idx < param_index)
95
+ new_index = param_index - nulls_before + 1 # Convert back to 1-based
96
+ return exp.Parameter(this=exp.Literal.number(new_index))
97
+ except (ValueError, IndexError):
98
+ pass
99
+
100
+ # Handle placeholder nodes for other dialects
101
+ elif isinstance(node, exp.Placeholder):
102
+ # For placeholders, we need to track position
103
+ if self._parameter_index in self.null_param_indices:
104
+ self._parameter_index += 1
105
+ return exp.Null()
106
+ self._parameter_index += 1
107
+
108
+ return node
@@ -10,16 +10,14 @@ import re
10
10
  from collections.abc import Mapping, Sequence
11
11
  from dataclasses import dataclass, field
12
12
  from enum import Enum
13
- from typing import TYPE_CHECKING, Any, Final, Optional, Union
13
+ from typing import Any, Final, Optional, Union
14
14
 
15
+ from sqlglot import exp
15
16
  from typing_extensions import TypedDict
16
17
 
17
18
  from sqlspec.exceptions import ExtraParameterError, MissingParameterError, ParameterStyleMismatchError
18
19
  from sqlspec.typing import SQLParameterType
19
20
 
20
- if TYPE_CHECKING:
21
- from sqlglot import exp
22
-
23
21
  # Constants
24
22
  MAX_32BIT_INT: Final[int] = 2147483647
25
23
 
@@ -28,7 +26,7 @@ __all__ = (
28
26
  "ParameterConverter",
29
27
  "ParameterInfo",
30
28
  "ParameterStyle",
31
- "ParameterStyleTransformationState",
29
+ "ParameterStyleConversionState",
32
30
  "ParameterValidator",
33
31
  "SQLParameterType",
34
32
  "TypedParameter",
@@ -169,7 +167,7 @@ class ParameterStyleInfo(TypedDict, total=False):
169
167
 
170
168
 
171
169
  @dataclass
172
- class ParameterStyleTransformationState:
170
+ class ParameterStyleConversionState:
173
171
  """Encapsulates all information about parameter style transformation.
174
172
 
175
173
  This class provides a single source of truth for parameter style conversions,
@@ -213,7 +211,7 @@ class ConvertedParameters:
213
211
  merged_parameters: "SQLParameterType"
214
212
  """Parameters after merging from various sources."""
215
213
 
216
- conversion_state: ParameterStyleTransformationState
214
+ conversion_state: ParameterStyleConversionState
217
215
  """Complete conversion state for tracking conversions."""
218
216
 
219
217
 
@@ -314,17 +312,13 @@ class ParameterValidator:
314
312
  """
315
313
  if not parameters_info:
316
314
  return ParameterStyle.NONE
317
-
318
- # Note: This logic prioritizes pyformat if present, then named, then positional.
319
315
  is_pyformat_named = any(p.style == ParameterStyle.NAMED_PYFORMAT for p in parameters_info)
320
316
  is_pyformat_positional = any(p.style == ParameterStyle.POSITIONAL_PYFORMAT for p in parameters_info)
321
317
 
322
318
  if is_pyformat_named:
323
319
  return ParameterStyle.NAMED_PYFORMAT
324
- if is_pyformat_positional: # If only PYFORMAT_POSITIONAL and not PYFORMAT_NAMED
320
+ if is_pyformat_positional:
325
321
  return ParameterStyle.POSITIONAL_PYFORMAT
326
-
327
- # Simplified logic if not pyformat, checks for any named or any positional
328
322
  has_named = any(
329
323
  p.style
330
324
  in {
@@ -336,13 +330,7 @@ class ParameterValidator:
336
330
  for p in parameters_info
337
331
  )
338
332
  has_positional = any(p.style in {ParameterStyle.QMARK, ParameterStyle.NUMERIC} for p in parameters_info)
339
-
340
- # If mixed named and positional (non-pyformat), prefer named as dominant.
341
- # The choice of NAMED_COLON here is somewhat arbitrary if multiple named styles are mixed.
342
333
  if has_named:
343
- # Could refine to return the style of the first named param encountered, or most frequent.
344
- # For simplicity, returning a general named style like NAMED_COLON is often sufficient.
345
- # Or, more accurately, find the first named style:
346
334
  for p_style in (
347
335
  ParameterStyle.NAMED_COLON,
348
336
  ParameterStyle.POSITIONAL_COLON,
@@ -354,12 +342,11 @@ class ParameterValidator:
354
342
  return ParameterStyle.NAMED_COLON
355
343
 
356
344
  if has_positional:
357
- # Similarly, could choose QMARK or NUMERIC based on presence.
358
345
  if any(p.style == ParameterStyle.NUMERIC for p in parameters_info):
359
346
  return ParameterStyle.NUMERIC
360
- return ParameterStyle.QMARK # Default positional
347
+ return ParameterStyle.QMARK
361
348
 
362
- return ParameterStyle.NONE # Should not be reached if parameters_info is not empty
349
+ return ParameterStyle.NONE
363
350
 
364
351
  @staticmethod
365
352
  def determine_parameter_input_type(parameters_info: "list[ParameterInfo]") -> "Optional[type]":
@@ -384,9 +371,8 @@ class ParameterValidator:
384
371
  if any(
385
372
  p.name is not None and p.style not in {ParameterStyle.POSITIONAL_COLON, ParameterStyle.NUMERIC}
386
373
  for p in parameters_info
387
- ): # True for NAMED styles and PYFORMAT_NAMED
374
+ ):
388
375
  return dict
389
- # All parameters must have p.name is None or be positional styles (POSITIONAL_COLON, NUMERIC)
390
376
  if all(
391
377
  p.name is None or p.style in {ParameterStyle.POSITIONAL_COLON, ParameterStyle.NUMERIC}
392
378
  for p in parameters_info
@@ -400,9 +386,7 @@ class ParameterValidator:
400
386
  "Ambiguous parameter structure for determining input type. "
401
387
  "Query might contain a mix of named and unnamed styles not typically supported together."
402
388
  )
403
- # Defaulting to dict if any named param is found, as that's the more common requirement for mixed scenarios.
404
- # However, strict validation should ideally prevent such mixed styles from being valid.
405
- return dict # Or raise an error for unsupported mixed styles.
389
+ return dict
406
390
 
407
391
  def validate_parameters(
408
392
  self,
@@ -421,12 +405,7 @@ class ParameterValidator:
421
405
  ParameterStyleMismatchError: When style doesn't match
422
406
  """
423
407
  expected_input_type = self.determine_parameter_input_type(parameters_info)
424
-
425
- # Allow creating SQL statements with placeholders but no parameters
426
- # This enables patterns like SQL("SELECT * FROM users WHERE id = ?").as_many([...])
427
- # Validation will happen later when parameters are actually provided
428
408
  if provided_params is None and parameters_info:
429
- # Don't raise an error, just return - validation will happen later
430
409
  return
431
410
 
432
411
  if (
@@ -707,7 +686,7 @@ class ParameterConverter:
707
686
  self.validator.validate_parameters(parameters_info, merged_params, sql)
708
687
  if needs_conversion:
709
688
  transformed_sql, placeholder_map = self._transform_sql_for_parsing(sql, parameters_info)
710
- conversion_state = ParameterStyleTransformationState(
689
+ conversion_state = ParameterStyleConversionState(
711
690
  was_transformed=True,
712
691
  original_styles=list({p.style for p in parameters_info}),
713
692
  transformation_style=ParameterStyle.NAMED_COLON,
@@ -716,7 +695,7 @@ class ParameterConverter:
716
695
  )
717
696
  else:
718
697
  transformed_sql = sql
719
- conversion_state = ParameterStyleTransformationState(
698
+ conversion_state = ParameterStyleConversionState(
720
699
  was_transformed=False,
721
700
  original_styles=list({p.style for p in parameters_info}),
722
701
  original_param_info=parameters_info,
@@ -775,10 +754,10 @@ class ParameterConverter:
775
754
  return parameters
776
755
 
777
756
  if kwargs is not None:
778
- return dict(kwargs) # Make a copy
757
+ return dict(kwargs)
779
758
 
780
759
  if args is not None:
781
- return list(args) # Convert tuple of args to list for consistency and mutability if needed later
760
+ return list(args)
782
761
 
783
762
  return None
784
763
 
@@ -809,53 +788,34 @@ class ParameterConverter:
809
788
 
810
789
  def infer_type_from_value(value: Any) -> tuple[str, "exp.DataType"]:
811
790
  """Infer SQL type hint and SQLGlot DataType from Python value."""
812
- # Import here to avoid issues
813
- from sqlglot import exp
814
791
 
815
792
  # None/NULL
816
793
  if value is None:
817
794
  return "null", exp.DataType.build("NULL")
818
-
819
- # Boolean
820
795
  if isinstance(value, bool):
821
796
  return "boolean", exp.DataType.build("BOOLEAN")
822
-
823
- # Integer types
824
797
  if isinstance(value, int) and not isinstance(value, bool):
825
798
  if abs(value) > MAX_32BIT_INT:
826
799
  return "bigint", exp.DataType.build("BIGINT")
827
800
  return "integer", exp.DataType.build("INT")
828
-
829
- # Float/Decimal
830
801
  if isinstance(value, float):
831
802
  return "float", exp.DataType.build("FLOAT")
832
803
  if isinstance(value, Decimal):
833
804
  return "decimal", exp.DataType.build("DECIMAL")
834
-
835
- # Date/Time types
836
805
  if isinstance(value, datetime):
837
806
  return "timestamp", exp.DataType.build("TIMESTAMP")
838
807
  if isinstance(value, date):
839
808
  return "date", exp.DataType.build("DATE")
840
809
  if isinstance(value, time):
841
810
  return "time", exp.DataType.build("TIME")
842
-
843
- # JSON/Dict
844
811
  if isinstance(value, dict):
845
812
  return "json", exp.DataType.build("JSON")
846
-
847
- # Array/List
848
813
  if isinstance(value, (list, tuple)):
849
814
  return "array", exp.DataType.build("ARRAY")
850
-
851
815
  if isinstance(value, str):
852
816
  return "string", exp.DataType.build("VARCHAR")
853
-
854
- # Bytes
855
817
  if isinstance(value, bytes):
856
818
  return "binary", exp.DataType.build("BINARY")
857
-
858
- # Default fallback
859
819
  return "string", exp.DataType.build("VARCHAR")
860
820
 
861
821
  def wrap_value(value: Any, semantic_name: Optional[str] = None) -> Any:
@@ -8,7 +8,7 @@ from sqlspec.exceptions import RiskLevel
8
8
  if TYPE_CHECKING:
9
9
  from sqlglot.dialects.dialect import DialectType
10
10
 
11
- from sqlspec.statement.parameters import ParameterInfo, ParameterStyleTransformationState
11
+ from sqlspec.statement.parameters import ParameterInfo, ParameterStyleConversionState
12
12
  from sqlspec.statement.sql import SQLConfig
13
13
  from sqlspec.typing import SQLParameterType
14
14
 
@@ -66,12 +66,6 @@ class SQLProcessingContext:
66
66
  # Current state
67
67
  current_expression: Optional[exp.Expression] = None
68
68
  """The SQL expression, potentially modified by transformers."""
69
-
70
- # Parameters
71
- initial_parameters: "Optional[SQLParameterType]" = None
72
- """The initial parameters as provided to the SQL object (before merging with kwargs)."""
73
- initial_kwargs: "Optional[dict[str, Any]]" = None
74
- """The initial keyword arguments as provided to the SQL object."""
75
69
  merged_parameters: "SQLParameterType" = field(default_factory=list)
76
70
  """Parameters after merging initial_parameters and initial_kwargs."""
77
71
  parameter_info: "list[ParameterInfo]" = field(default_factory=list)
@@ -99,7 +93,7 @@ class SQLProcessingContext:
99
93
  extra_info: dict[str, Any] = field(default_factory=dict)
100
94
  """Extra information from parameter processing, including conversion state."""
101
95
 
102
- parameter_conversion: "Optional[ParameterStyleTransformationState]" = None
96
+ parameter_conversion: "Optional[ParameterStyleConversionState]" = None
103
97
  """Single source of truth for parameter style conversion tracking."""
104
98
 
105
99
  @property
@@ -37,7 +37,7 @@ from sqlspec.utils.type_guards import (
37
37
  if TYPE_CHECKING:
38
38
  from sqlglot.dialects.dialect import DialectType
39
39
 
40
- from sqlspec.statement.parameters import ParameterStyleTransformationState
40
+ from sqlspec.statement.parameters import ParameterStyleConversionState
41
41
 
42
42
  __all__ = ("SQL", "SQLConfig", "Statement")
43
43
 
@@ -242,7 +242,7 @@ class SQL:
242
242
  self._original_parameters: Any = None
243
243
  self._original_sql: str = ""
244
244
  self._placeholder_mapping: dict[str, Union[str, int]] = {}
245
- self._parameter_conversion_state: Optional[ParameterStyleTransformationState] = None
245
+ self._parameter_conversion_state: Optional[ParameterStyleConversionState] = None
246
246
  self._is_many: bool = False
247
247
  self._is_script: bool = False
248
248
 
@@ -686,9 +686,9 @@ class SQL:
686
686
  self._placeholder_mapping = placeholder_mapping
687
687
 
688
688
  # Create conversion state
689
- from sqlspec.statement.parameters import ParameterStyleTransformationState
689
+ from sqlspec.statement.parameters import ParameterStyleConversionState
690
690
 
691
- self._parameter_conversion_state = ParameterStyleTransformationState(
691
+ self._parameter_conversion_state = ParameterStyleConversionState(
692
692
  was_transformed=True,
693
693
  original_styles=list({p.style for p in param_info}),
694
694
  transformation_style=ParameterStyle.NAMED_COLON,
@@ -173,9 +173,6 @@ def test_postgresql_date_time_types(adbc_postgresql_types_session: AdbcDriver) -
173
173
 
174
174
  @pytest.mark.xdist_group("postgres")
175
175
  @xfail_if_driver_missing
176
- @pytest.mark.xfail(
177
- reason="ADBC PostgreSQL driver has issues with null parameter handling - Known limitation: https://github.com/apache/arrow-adbc/issues/81"
178
- )
179
176
  def test_postgresql_null_values(adbc_postgresql_types_session: AdbcDriver) -> None:
180
177
  """Test NULL value handling with PostgreSQL.
181
178
 
@@ -0,0 +1,121 @@
1
+ """Test NULL parameter handling for ADBC drivers."""
2
+
3
+ from collections.abc import Generator
4
+
5
+ import pytest
6
+ from pytest_databases.docker.postgres import PostgresService
7
+
8
+ from sqlspec.adapters.adbc import AdbcConfig, AdbcDriver
9
+ from sqlspec.statement.sql import SQLConfig
10
+
11
+ # Import the decorator
12
+ from tests.integration.test_adapters.test_adbc.conftest import xfail_if_driver_missing
13
+
14
+
15
+ @pytest.fixture
16
+ def adbc_postgresql_null_session(postgres_service: PostgresService) -> Generator[AdbcDriver, None, None]:
17
+ """Create an ADBC PostgreSQL session for NULL parameter testing."""
18
+ config = AdbcConfig(
19
+ uri=f"postgres://{postgres_service.user}:{postgres_service.password}@{postgres_service.host}:{postgres_service.port}/{postgres_service.database}",
20
+ driver_name="adbc_driver_postgresql",
21
+ statement_config=SQLConfig(),
22
+ )
23
+
24
+ with config.provide_session() as session:
25
+ # Create test table
26
+ session.execute_script("""
27
+ CREATE TABLE IF NOT EXISTS test_null_params (
28
+ id SERIAL PRIMARY KEY,
29
+ col1 TEXT,
30
+ col2 TEXT,
31
+ col3 TEXT
32
+ )
33
+ """)
34
+ yield session
35
+ # Cleanup
36
+ session.execute_script("DROP TABLE IF EXISTS test_null_params")
37
+
38
+
39
+ @pytest.mark.xdist_group("postgres")
40
+ @xfail_if_driver_missing
41
+ def test_postgresql_single_null_parameter(adbc_postgresql_null_session: AdbcDriver) -> None:
42
+ """Test executing with a single NULL parameter."""
43
+ result = adbc_postgresql_null_session.execute("INSERT INTO test_null_params (col1) VALUES ($1)", None)
44
+ assert result.rows_affected in (-1, 1)
45
+
46
+ # Verify data
47
+ result = adbc_postgresql_null_session.execute("SELECT * FROM test_null_params")
48
+ assert len(result.data) == 1
49
+ assert result.data[0]["col1"] is None
50
+
51
+
52
+ @pytest.mark.xdist_group("postgres")
53
+ @xfail_if_driver_missing
54
+ def test_postgresql_all_null_parameters(adbc_postgresql_null_session: AdbcDriver) -> None:
55
+ """Test executing with all NULL parameters."""
56
+ result = adbc_postgresql_null_session.execute(
57
+ "INSERT INTO test_null_params (col1, col2, col3) VALUES ($1, $2, $3)", None, None, None
58
+ )
59
+ assert result.rows_affected in (-1, 1)
60
+
61
+ # Verify data
62
+ result = adbc_postgresql_null_session.execute("SELECT * FROM test_null_params")
63
+ assert len(result.data) == 1
64
+ assert result.data[0]["col1"] is None
65
+ assert result.data[0]["col2"] is None
66
+ assert result.data[0]["col3"] is None
67
+
68
+
69
+ @pytest.mark.xdist_group("postgres")
70
+ @xfail_if_driver_missing
71
+ def test_postgresql_mixed_null_parameters(adbc_postgresql_null_session: AdbcDriver) -> None:
72
+ """Test executing with mixed NULL and non-NULL parameters."""
73
+ result = adbc_postgresql_null_session.execute(
74
+ "INSERT INTO test_null_params (col1, col2, col3) VALUES ($1, $2, $3)", "value1", None, "value3"
75
+ )
76
+ assert result.rows_affected in (-1, 1)
77
+
78
+ # Verify data
79
+ result = adbc_postgresql_null_session.execute("SELECT * FROM test_null_params")
80
+ assert len(result.data) == 1
81
+ assert result.data[0]["col1"] == "value1"
82
+ assert result.data[0]["col2"] is None
83
+ assert result.data[0]["col3"] == "value3"
84
+
85
+
86
+ @pytest.mark.xdist_group("postgres")
87
+ @xfail_if_driver_missing
88
+ def test_postgresql_execute_many_with_nulls(adbc_postgresql_null_session: AdbcDriver) -> None:
89
+ """Test execute_many with NULL parameters."""
90
+ parameters = [
91
+ ("row1", None, None),
92
+ (None, "row2", None),
93
+ (None, None, "row3"),
94
+ (None, None, None), # All NULL row
95
+ ]
96
+
97
+ result = adbc_postgresql_null_session.execute_many(
98
+ "INSERT INTO test_null_params (col1, col2, col3) VALUES ($1, $2, $3)", parameters
99
+ )
100
+ assert result.rows_affected in (-1, 4, 1)
101
+
102
+ # Verify data
103
+ result = adbc_postgresql_null_session.execute("SELECT * FROM test_null_params ORDER BY id")
104
+ assert len(result.data) == 4
105
+
106
+ # Check each row
107
+ assert result.data[0]["col1"] == "row1"
108
+ assert result.data[0]["col2"] is None
109
+ assert result.data[0]["col3"] is None
110
+
111
+ assert result.data[1]["col1"] is None
112
+ assert result.data[1]["col2"] == "row2"
113
+ assert result.data[1]["col3"] is None
114
+
115
+ assert result.data[2]["col1"] is None
116
+ assert result.data[2]["col2"] is None
117
+ assert result.data[2]["col3"] == "row3"
118
+
119
+ assert result.data[3]["col1"] is None
120
+ assert result.data[3]["col2"] is None
121
+ assert result.data[3]["col3"] is None
@@ -224,9 +224,6 @@ def test_multiple_parameters(adbc_postgresql_session: AdbcDriver) -> None:
224
224
 
225
225
 
226
226
  @pytest.mark.xdist_group("postgres")
227
- @pytest.mark.xfail(
228
- reason="ADBC PostgreSQL driver has issues with null parameter handling - Known limitation: https://github.com/apache/arrow-adbc/issues/81"
229
- )
230
227
  def test_null_parameters(adbc_postgresql_session: AdbcDriver) -> None:
231
228
  """Test handling of NULL parameters.
232
229
 
@@ -265,7 +262,6 @@ def test_null_parameters(adbc_postgresql_session: AdbcDriver) -> None:
265
262
 
266
263
 
267
264
  @pytest.mark.xdist_group("postgres")
268
- @pytest.mark.xfail(reason="ADBC PostgreSQL driver has issues with Arrow type mapping in executemany - Known limitation")
269
265
  def test_execute_many(adbc_postgresql_session: AdbcDriver) -> None:
270
266
  """Test execute_many functionality with ADBC PostgreSQL.
271
267
 
@@ -701,7 +697,6 @@ def test_date_time_types(adbc_postgresql_session: AdbcDriver) -> None:
701
697
 
702
698
 
703
699
  @pytest.mark.xdist_group("postgres")
704
- @pytest.mark.xfail(reason="ADBC PostgreSQL driver has issues with null parameter handling")
705
700
  def test_null_values(adbc_postgresql_session: AdbcDriver) -> None:
706
701
  """Test NULL value handling."""
707
702
  # Ensure test_table exists after any prior errors