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