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.
- {sqlspec-0.14.0 → sqlspec-0.14.1}/PKG-INFO +1 -1
- {sqlspec-0.14.0 → sqlspec-0.14.1}/pyproject.toml +3 -3
- sqlspec-0.14.1/sqlspec/__main__.py +12 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/adbc/config.py +12 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/adbc/driver.py +14 -0
- sqlspec-0.14.1/sqlspec/adapters/adbc/transformers.py +108 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/parameters.py +14 -54
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/context.py +2 -8
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/sql.py +4 -4
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_data_types.py +0 -3
- sqlspec-0.14.1/tests/integration/test_adapters/test_adbc/test_null_params.py +121 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_postgres_driver.py +0 -5
- sqlspec-0.14.1/tests/unit/test_adapters/test_adbc/test_transformers.py +147 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/uv.lock +1 -1
- {sqlspec-0.14.0 → sqlspec-0.14.1}/.gitignore +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/.pre-commit-config.yaml +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/CONTRIBUTING.rst +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/LICENSE +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/Makefile +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/NOTICE +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/README.md +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/__metadata__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/_serialization.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/_sql.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/_typing.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/adbc/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/aiosqlite/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/aiosqlite/config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/aiosqlite/driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/asyncmy/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/asyncmy/config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/asyncmy/driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/asyncpg/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/asyncpg/config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/asyncpg/driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/bigquery/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/bigquery/config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/bigquery/driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/duckdb/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/duckdb/config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/duckdb/driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/oracledb/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/oracledb/config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/oracledb/driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/psqlpy/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/psqlpy/config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/psqlpy/driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/psycopg/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/psycopg/config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/psycopg/driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/sqlite/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/sqlite/config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/adapters/sqlite/driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/base.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/cli.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/_async.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/_common.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/_sync.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/connection.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_cache.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_csv_writer.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_pipeline.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_query_tools.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_result_utils.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_sql_translator.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_storage.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/mixins/_type_coercion.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/driver/parameters.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/exceptions.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/aiosql/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/aiosql/adapter.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/litestar/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/litestar/_utils.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/litestar/cli.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/litestar/config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/litestar/handlers.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/litestar/plugin.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/extensions/litestar/providers.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/loader.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/migrations/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/migrations/base.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/migrations/commands.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/migrations/runner.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/migrations/tracker.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/migrations/utils.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/protocols.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/py.typed +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_base.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_column.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_ddl.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_ddl_utils.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_delete.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_insert.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_merge.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_parsing_utils.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_select.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/_update.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_cte_and_set_ops.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_delete_operations.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_insert_operations.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_join_operations.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_merge_operations.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_order_limit_operations.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_pivot_operations.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_select_operations.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_update_operations.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/builder/mixins/_where_clause.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/cache.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/filters.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/analyzers/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/analyzers/_analyzer.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/transformers/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/transformers/_expression_simplifier.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/transformers/_remove_comments_and_hints.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/validators/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/validators/_dml_safety.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/validators/_parameter_style.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/validators/_performance.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/pipelines/validators/_security.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/result.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/statement/splitter.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/storage/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/storage/backends/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/storage/backends/base.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/storage/backends/fsspec.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/storage/backends/obstore.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/storage/capabilities.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/storage/registry.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/typing.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/cached_property.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/correlation.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/deprecation.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/fixtures.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/logging.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/module_loader.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/serializers.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/singleton.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/statement_hashing.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/sync_tools.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/text.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/sqlspec/utils/type_guards.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/conftest.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/ddls-mysql-collection.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/ddls-postgres-collection.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/example_usage.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/init.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-config.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-data_types.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-database_details.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-engines.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-hostname.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-plugins.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-process_list.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-resource-groups.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-schema_objects.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-table_details.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/collection-users.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/mysql/init.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/oracle.ddl.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-applications.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-aws_extension_dependency.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-aws_oracle_exists.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-bg_writer_stats.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-calculated_metrics.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-data_types.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-database_details.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-extensions.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-index_details.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-pglogical-details.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-privileges.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-replication_slots.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-replication_stats.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-schema_details.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-schema_objects.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-settings.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-source_details.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/collection-table_details.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/extended-collection-all-databases.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/postgres/init.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/readiness-check.sql +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/fixtures/sql_utils.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/conftest.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_arrow_functionality.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_bigquery_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_connection.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_duckdb_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_execute_many.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_execute_script.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_parameter_styles.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_returning.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_sqlite_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_aiosqlite/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_aiosqlite/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncmy/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncmy/test_config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncpg/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncpg/conftest.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncpg/test_arrow_functionality.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncpg/test_connection.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncpg/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncpg/test_execute_many.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_asyncpg/test_parameter_styles.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_bigquery/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_bigquery/conftest.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_bigquery/test_arrow_functionality.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_bigquery/test_connection.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_bigquery/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_duckdb/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_duckdb/test_arrow_functionality.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_duckdb/test_connection.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_duckdb/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_duckdb/test_execute_many.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_duckdb/test_mixed_parameter_styles.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_duckdb/test_parameter_styles.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_oracledb/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_oracledb/test_connection.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_oracledb/test_driver_async.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_oracledb/test_driver_sync.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psqlpy/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psqlpy/test_arrow_functionality.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psqlpy/test_connection.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psqlpy/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psycopg/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psycopg/conftest.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psycopg/test_async_copy.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psycopg/test_connection.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psycopg/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psycopg/test_execute_many.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_psycopg/test_parameter_styles.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_sqlite/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_sqlite/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_sqlite/test_query_mixin.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_dialect_propagation.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_driver_mixins/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_extensions/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_extensions/test_aiosql/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_extensions/test_litestar/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_sql_file_loader.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_storage/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_storage/test_driver_storage_integration.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_storage/test_end_to_end_workflows.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_storage/test_storage_mixins.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/statement/test_cache.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_adbc/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_adbc/test_config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_adbc/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_aiosqlite/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_aiosqlite/test_config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_aiosqlite/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_asyncmy/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_asyncmy/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_asyncpg/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_asyncpg/test_config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_asyncpg/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_bigquery/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_bigquery/test_config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_bigquery/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_cache_mixin.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_duckdb/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_duckdb/test_config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_duckdb/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_oracledb/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_oracledb/test_config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_oracledb/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_psqlpy/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_psqlpy/test_config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_psqlpy/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_psycopg/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_psycopg/test_config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_psycopg/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_sqlite/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_sqlite/test_config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_adapters/test_sqlite/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_base.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_config_dialect.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_driver.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_driver_mixins/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_driver_mixins/test_query_mixin.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_exceptions.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_extensions/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_extensions/test_aiosql/test_adapter.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_loader.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_base.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_base.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_builder_mixins.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_column.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_delete.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_dynamic_columns.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_insert.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_merge.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_select.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_builder/test_update.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_config.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_filters.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_mixins.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_oracle_numeric_parameters.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_parameter_normalization.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_parameter_preservation.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_parameters.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_analyzer.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_analyzer_subquery_detection.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_expression_simplifier.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_literal_parameterizer_duplication.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_transformers_literal_parameterizer.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_transformers_literal_parameterizer_cte.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_transformers_remove_comments.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_validators_dml_safety.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_validators_parameter_style.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_validators_performance.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_pipelines/test_validators_security.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_result.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_splitter.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_sql.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_sql_as_many.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_sql_translator_mixin.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_sqlfactory.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_storage.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_transformers/test_expression_simplifier_parameter_tracking.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_statement/test_typed_parameter.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_storage/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_storage/test_backends/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_storage/test_backends/test_fsspec_backend.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_storage/test_backends/test_obstore_backend.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_storage/test_base.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_storage/test_registry.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_typing.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_utils/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_utils/test_deprecation.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_utils/test_fixtures.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_utils/test_module_loader.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_utils/test_singleton.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_utils/test_sync_tools.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/test_utils/test_text.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tests/unit/utils/test_ast_hashing.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tools/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tools/build_docs.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tools/pypi_readme.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tools/sphinx_ext/__init__.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tools/sphinx_ext/changelog.py +0 -0
- {sqlspec-0.14.0 → sqlspec-0.14.1}/tools/sphinx_ext/missing_references.py +0 -0
|
@@ -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.
|
|
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.
|
|
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.
|
|
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
|
|
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
|
-
"
|
|
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
|
|
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:
|
|
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:
|
|
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
|
|
347
|
+
return ParameterStyle.QMARK
|
|
361
348
|
|
|
362
|
-
return ParameterStyle.NONE
|
|
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
|
-
):
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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)
|
|
757
|
+
return dict(kwargs)
|
|
779
758
|
|
|
780
759
|
if args is not None:
|
|
781
|
-
return list(args)
|
|
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,
|
|
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[
|
|
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
|
|
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[
|
|
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
|
|
689
|
+
from sqlspec.statement.parameters import ParameterStyleConversionState
|
|
690
690
|
|
|
691
|
-
self._parameter_conversion_state =
|
|
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,
|
{sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_data_types.py
RENAMED
|
@@ -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
|
{sqlspec-0.14.0 → sqlspec-0.14.1}/tests/integration/test_adapters/test_adbc/test_postgres_driver.py
RENAMED
|
@@ -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
|