velocity-python 0.1.43__tar.gz → 0.1.45__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.
- {velocity_python-0.1.43/src/velocity_python.egg-info → velocity_python-0.1.45}/PKG-INFO +1 -1
- {velocity_python-0.1.43 → velocity_python-0.1.45}/pyproject.toml +1 -1
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/__init__.py +1 -1
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/core/table.py +75 -11
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/tablehelper.py +11 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_tablehelper.py +23 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45/src/velocity_python.egg-info}/PKG-INFO +1 -1
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_table_alter.py +48 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/LICENSE +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/README.md +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/setup.cfg +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/amplify.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/amplify_build.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/assets/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/assets/backfill.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/assets/indexing.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/assets/references.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/assets/service.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/assets/usage_index.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/dirty_pipeline.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/base_handler.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/context.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/context_factory.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/exceptions.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/lambda_handler.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/mixins/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/mixins/data_service.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/mixins/web_handler.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/perf.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/response.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/sqs_handler.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/s3.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/ssm_config.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/tests/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/tests/test_base_handler_error_response.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/tests/test_lambda_handler_json_serialization.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/tests/test_response.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/core/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/core/async_support.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/core/column.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/core/database.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/core/decorators.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/core/engine.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/core/result.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/core/row.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/core/sequence.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/core/transaction.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/core/view.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/exceptions.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/migrations.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/base/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/base/initializer.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/base/operators.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/base/sql.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/base/types.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/mysql/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/mysql/operators.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/mysql/reserved.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/mysql/sql.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/mysql/types.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/postgres/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/postgres/operators.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/postgres/reserved.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/postgres/sql.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/postgres/types.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlite/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlite/operators.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlite/reserved.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlite/sql.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlite/types.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlserver/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlserver/operators.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlserver/reserved.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlserver/sql.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlserver/types.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/common_db_test.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/common.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_column.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_connections.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_database.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_engine.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_general_usage.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_imports.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_result.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_row.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_row_comprehensive.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_schema_locking.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_schema_locking_unit.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_sequence.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_sql_comprehensive.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_table.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_table_comprehensive.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_transaction.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/sql/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/sql/common.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/sql/test_postgres_select_advanced.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/sql/test_postgres_select_variances.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_cursor_rowcount_fix.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_db_utils.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_postgres.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_postgres_unchanged.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_process_error_robustness.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_result_caching.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_result_sql_aware.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_row_get_missing_column.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_schema_locking_initializers.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_schema_locking_simple.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_sql_builder.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_view_helper.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/utils.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/logging.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/conv/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/conv/iconv.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/conv/oconv.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/db.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/export.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/format.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/mail.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/merge.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/pdf.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/tests/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/tests/test_db.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/tests/test_fix.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/tests/test_format.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/tests/test_iconv.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/tests/test_merge.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/tests/test_oconv.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/tests/test_original_error.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/tests/test_timer.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/timer.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/tools.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/payment/__init__.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/payment/authorizenet_adapter.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/payment/authorizenet_mirror.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/payment/base_adapter.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/payment/braintree_adapter.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/payment/braintree_mirror.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/payment/charge_rules.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/payment/stripe_adapter.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/payment/stripe_mirror.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity_python.egg-info/SOURCES.txt +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity_python.egg-info/dependency_links.txt +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity_python.egg-info/entry_points.txt +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity_python.egg-info/requires.txt +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity_python.egg-info/top_level.txt +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_amplify_build.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_asset_indexing.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_asset_references.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_assets_service.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_async_support.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_batch_operations.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_concurrency_safety.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_connection_pool.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_connection_resilience.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_context_job_descriptions.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_decorators.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_dirty_pipeline_fast_path.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_email_processing.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_iconv_money_to_cents.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_lambda_handler.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_lambda_handler_auth.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_mixins_import.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_n_plus_one.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_observability.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_payment_authorizenet_adapter.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_payment_braintree_adapter.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_payment_braintree_mirror.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_payment_profile_sorting.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_payment_stripe_adapter.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_pdf.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_prepared_statements.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_psycopg3_upgrade.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_query_cache.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_row_batch_update.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_row_cache_staleness.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_row_dirty_tracking.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_schema_migrations.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_security_hardening.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_server_cursor.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_spreadsheet_functions.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_sqs_per_record_transactions.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_sys_modified_count_postgres_demo.py +0 -0
- {velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_where_clause_validation.py +0 -0
|
@@ -234,6 +234,63 @@ def _normalize_index_expression(expression):
|
|
|
234
234
|
return normalized.strip().lower()
|
|
235
235
|
|
|
236
236
|
|
|
237
|
+
def _split_top_level_boolean_terms(expression):
|
|
238
|
+
parts = []
|
|
239
|
+
operators = []
|
|
240
|
+
start = 0
|
|
241
|
+
depth = 0
|
|
242
|
+
position = 0
|
|
243
|
+
while position < len(expression):
|
|
244
|
+
char = expression[position]
|
|
245
|
+
if char == "(":
|
|
246
|
+
depth += 1
|
|
247
|
+
position += 1
|
|
248
|
+
continue
|
|
249
|
+
if char == ")":
|
|
250
|
+
depth = max(0, depth - 1)
|
|
251
|
+
position += 1
|
|
252
|
+
continue
|
|
253
|
+
if depth == 0:
|
|
254
|
+
lowered = expression[position:].lower()
|
|
255
|
+
for operator in (" and ", " or "):
|
|
256
|
+
if lowered.startswith(operator):
|
|
257
|
+
parts.append(expression[start:position].strip())
|
|
258
|
+
operators.append(operator.strip())
|
|
259
|
+
position += len(operator)
|
|
260
|
+
start = position
|
|
261
|
+
break
|
|
262
|
+
else:
|
|
263
|
+
position += 1
|
|
264
|
+
continue
|
|
265
|
+
position += 1
|
|
266
|
+
|
|
267
|
+
if operators:
|
|
268
|
+
parts.append(expression[start:].strip())
|
|
269
|
+
|
|
270
|
+
return parts, operators
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def _normalize_index_where_clause(expression):
|
|
274
|
+
normalized = _normalize_index_expression(expression)
|
|
275
|
+
parts, operators = _split_top_level_boolean_terms(normalized)
|
|
276
|
+
if not operators:
|
|
277
|
+
return normalized
|
|
278
|
+
|
|
279
|
+
simplified_parts = []
|
|
280
|
+
for part in parts:
|
|
281
|
+
stripped = _strip_redundant_outer_parens(part)
|
|
282
|
+
nested_parts, nested_operators = _split_top_level_boolean_terms(stripped)
|
|
283
|
+
if nested_operators:
|
|
284
|
+
simplified_parts.append(part)
|
|
285
|
+
else:
|
|
286
|
+
simplified_parts.append(stripped)
|
|
287
|
+
|
|
288
|
+
combined = [simplified_parts[0]]
|
|
289
|
+
for operator, part in zip(operators, simplified_parts[1:]):
|
|
290
|
+
combined.extend([operator, part])
|
|
291
|
+
return " ".join(combined).strip()
|
|
292
|
+
|
|
293
|
+
|
|
237
294
|
def _parse_index_signature(index_sql):
|
|
238
295
|
normalized_sql = " ".join(str(index_sql or "").split())
|
|
239
296
|
upper_sql = normalized_sql.upper()
|
|
@@ -257,7 +314,7 @@ def _parse_index_signature(index_sql):
|
|
|
257
314
|
where_clause = None
|
|
258
315
|
where_pos = upper_sql.find(" WHERE ", closing_index)
|
|
259
316
|
if where_pos != -1:
|
|
260
|
-
where_clause =
|
|
317
|
+
where_clause = _normalize_index_where_clause(normalized_sql[where_pos + 7 :])
|
|
261
318
|
|
|
262
319
|
return {
|
|
263
320
|
"name": index_name,
|
|
@@ -686,16 +743,23 @@ class Table:
|
|
|
686
743
|
return signatures
|
|
687
744
|
|
|
688
745
|
def _desired_index_signature(self, spec):
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
746
|
+
columns = []
|
|
747
|
+
for column_name in spec["columns"]:
|
|
748
|
+
normalized_column = _normalize_identifier(column_name)
|
|
749
|
+
if spec.get("lower"):
|
|
750
|
+
normalized_column = f"lower({normalized_column})"
|
|
751
|
+
columns.append(normalized_column)
|
|
752
|
+
|
|
753
|
+
return {
|
|
754
|
+
"name": _normalize_identifier(spec.get("name")) if spec.get("name") else None,
|
|
755
|
+
"unique": bool(spec.get("unique")),
|
|
756
|
+
"columns": tuple(columns),
|
|
757
|
+
"where": (
|
|
758
|
+
_normalize_index_where_clause(spec.get("where"))
|
|
759
|
+
if spec.get("where")
|
|
760
|
+
else None
|
|
761
|
+
),
|
|
762
|
+
}
|
|
699
763
|
|
|
700
764
|
def _existing_foreign_key_signatures(self):
|
|
701
765
|
sql, vals = self.sql.foreign_key_info(table=self.name, column=None)
|
|
@@ -196,6 +196,17 @@ class TableHelper:
|
|
|
196
196
|
|
|
197
197
|
alias = self.get_table_alias("current_table")
|
|
198
198
|
if not self.has_pointer(column):
|
|
199
|
+
raw_expression = self.remove_operator(key).strip()
|
|
200
|
+
if column.upper() in self.reserved and re.search(
|
|
201
|
+
r"(?i)\bcase\s+when\b|\bexists\s*\(|\bselect\b|\bfrom\b|\bwhere\b",
|
|
202
|
+
raw_expression,
|
|
203
|
+
):
|
|
204
|
+
if options.get("bypass_on_error"):
|
|
205
|
+
return key
|
|
206
|
+
raise ValueError(
|
|
207
|
+
f"Could not safely resolve complex SQL expression: {key}"
|
|
208
|
+
)
|
|
209
|
+
|
|
199
210
|
# Standard column - no pointer syntax
|
|
200
211
|
if (
|
|
201
212
|
options.get("alias_table")
|
|
@@ -198,6 +198,29 @@ class TestTableHelper(unittest.TestCase):
|
|
|
198
198
|
f"Failed for '{input_expr}': expected '{expected}', got '{result}'",
|
|
199
199
|
)
|
|
200
200
|
|
|
201
|
+
def test_resolve_references_preserves_complex_case_exists_expression(self):
|
|
202
|
+
"""Complex CASE/EXISTS expressions should remain raw when not safely rewritable."""
|
|
203
|
+
original_reserved = TableHelper.reserved
|
|
204
|
+
TableHelper.reserved = ["CASE", "WHEN", "THEN", "ELSE", "END", "EXISTS"]
|
|
205
|
+
try:
|
|
206
|
+
expr = """coalesce(sum(case when exists (
|
|
207
|
+
select 1
|
|
208
|
+
from donor_users du
|
|
209
|
+
where lower(du.email_address) = lower(swipegive_settings.email_address)
|
|
210
|
+
and lower(coalesce(nullif(du.plaid_status, ''), 'ready')) not in ('error', 'purged')
|
|
211
|
+
) then 1 else 0 end), 0) as active"""
|
|
212
|
+
result = self.helper.resolve_references(
|
|
213
|
+
expr,
|
|
214
|
+
options={
|
|
215
|
+
"alias_column": True,
|
|
216
|
+
"alias_table": True,
|
|
217
|
+
"bypass_on_error": True,
|
|
218
|
+
},
|
|
219
|
+
)
|
|
220
|
+
self.assertEqual(result, expr)
|
|
221
|
+
finally:
|
|
222
|
+
TableHelper.reserved = original_reserved
|
|
223
|
+
|
|
201
224
|
def test_extract_column_name_cast_expressions(self):
|
|
202
225
|
"""Test extracting column names from CAST expressions"""
|
|
203
226
|
test_cases = [
|
|
@@ -558,6 +558,54 @@ class TableAlterTests(unittest.TestCase):
|
|
|
558
558
|
_parse_index_signature(desired),
|
|
559
559
|
)
|
|
560
560
|
|
|
561
|
+
def test_parse_index_signature_ignores_redundant_boolean_term_parentheses(self):
|
|
562
|
+
existing = (
|
|
563
|
+
"CREATE INDEX idx_pending_transactions_scheduled_capture_at "
|
|
564
|
+
"ON public.pending_transactions USING btree (scheduled_capture_at) "
|
|
565
|
+
"WHERE ((status = 'authorized'::text) AND (captured_at IS NULL) AND "
|
|
566
|
+
"(canceled_at IS NULL))"
|
|
567
|
+
)
|
|
568
|
+
desired = (
|
|
569
|
+
"CREATE INDEX idx_pending_transactions_scheduled_capture_at "
|
|
570
|
+
"ON pending_transactions (scheduled_capture_at) "
|
|
571
|
+
"WHERE status = 'authorized' AND captured_at IS NULL AND canceled_at IS NULL"
|
|
572
|
+
)
|
|
573
|
+
|
|
574
|
+
self.assertEqual(
|
|
575
|
+
_parse_index_signature(existing),
|
|
576
|
+
_parse_index_signature(desired),
|
|
577
|
+
)
|
|
578
|
+
|
|
579
|
+
def test_desired_index_signature_allows_system_columns_not_in_declared_spec(self):
|
|
580
|
+
table = FakeTable(
|
|
581
|
+
PostgresSQL,
|
|
582
|
+
{
|
|
583
|
+
"product_sys_id": {"type": "BIGINT", "nullable": False},
|
|
584
|
+
},
|
|
585
|
+
)
|
|
586
|
+
|
|
587
|
+
signature = Table._desired_index_signature(
|
|
588
|
+
table,
|
|
589
|
+
{
|
|
590
|
+
"name": "idx_inventory_ledger_product_sys_id_sys_id",
|
|
591
|
+
"columns": ["product_sys_id", "sys_id"],
|
|
592
|
+
"unique": False,
|
|
593
|
+
"direction": None,
|
|
594
|
+
"where": None,
|
|
595
|
+
"lower": None,
|
|
596
|
+
},
|
|
597
|
+
)
|
|
598
|
+
|
|
599
|
+
self.assertEqual(
|
|
600
|
+
signature,
|
|
601
|
+
{
|
|
602
|
+
"name": "idx_inventory_ledger_product_sys_id_sys_id",
|
|
603
|
+
"unique": False,
|
|
604
|
+
"columns": ("product_sys_id", "sys_id"),
|
|
605
|
+
"where": None,
|
|
606
|
+
},
|
|
607
|
+
)
|
|
608
|
+
|
|
561
609
|
|
|
562
610
|
if __name__ == "__main__":
|
|
563
611
|
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/context_factory.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/lambda_handler.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/mixins/__init__.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/mixins/data_service.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/aws/handlers/mixins/web_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/base/initializer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/mysql/operators.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/postgres/__init__.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/postgres/operators.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/postgres/reserved.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlite/__init__.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlite/operators.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlite/reserved.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlserver/__init__.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlserver/operators.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlserver/reserved.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/servers/sqlserver/types.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_column.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_connections.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_database.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_engine.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_imports.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_result.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_row.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_sequence.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_table.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/postgres/test_transaction.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_cursor_rowcount_fix.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_postgres_unchanged.py
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_result_caching.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/db/tests/test_result_sql_aware.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/misc/tests/test_original_error.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/payment/authorizenet_adapter.py
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity/payment/authorizenet_mirror.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity_python.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity_python.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/src/velocity_python.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_payment_authorizenet_adapter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{velocity_python-0.1.43 → velocity_python-0.1.45}/tests/test_sys_modified_count_postgres_demo.py
RENAMED
|
File without changes
|
|
File without changes
|