vgi-python 0.19.0__tar.gz → 0.20.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.
- {vgi_python-0.19.0 → vgi_python-0.20.0}/PKG-INFO +1 -1
- {vgi_python-0.19.0 → vgi_python-0.20.0}/pyproject.toml +1 -1
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_protocol_version.py +3 -3
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/landing/describe.expected.json +63 -1
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/aggregate/__init__.py +3 -0
- vgi_python-0.20.0/vgi/_test_fixtures/aggregate/same_name.py +139 -0
- vgi_python-0.20.0/vgi/_test_fixtures/table/same_name_cached.py +131 -0
- vgi_python-0.20.0/vgi/_test_fixtures/table_in_out_same_name.py +243 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/worker.py +29 -4
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/protocol.py +61 -1
- vgi_python-0.20.0/vgi/protocol_version.txt +1 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/worker.py +16 -4
- vgi_python-0.19.0/vgi/protocol_version.txt +0 -1
- {vgi_python-0.19.0 → vgi_python-0.20.0}/.gitattributes +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/.github/dependabot.yml +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/.github/styles/config/vocabularies/VGI/accept.txt +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/.github/workflows/ci.yml +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/.github/workflows/docs.yml +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/.github/workflows/integration.yml +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/.github/workflows/release.yml +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/.gitignore +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/.python-version +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/.vale.ini +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/CLAUDE.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/DOCS_ACCEPTANCE_CRITERIA.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/DOCS_REVIEW_RUBRIC.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/DOCS_USABILITY_TEST.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/LICENSE +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/README.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/SECURITY.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/ci/README.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/ci/preprocess-require.awk +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/ci/run-integration.sh +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/dist-vgi/.gitignore +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/aggregate-functions.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/api/arguments.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/api/auth.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/api/catalogs.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/api/client.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/api/exceptions.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/api/filters.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/api/functions.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/api/http.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/api/index.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/api/metadata.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/api/observability.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/api/storage.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/api/transactor.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/api/worker.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/argument-serialization.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/assets/apple-touch-icon.png +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/assets/favicon-16x16.png +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/assets/favicon-32x32.png +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/assets/favicon.ico +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/assets/kinds/aggregate.svg +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/assets/kinds/buffering.svg +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/assets/kinds/scalar.svg +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/assets/kinds/table-in-out.svg +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/assets/kinds/table.svg +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/assets/logo.png +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/assets/social-card.png +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/authentication.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/catalog-interface.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/cli.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/column-statistics.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/concepts/index.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/contributing-docs.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/filter-pushdown.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/generator-api.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/how-to/catalogs.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/how-to/function-patterns.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/how-to/http-auth.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/how-to/index.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/how-to/pushdown-and-statistics.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/how-to/state-storage.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/index.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/lifecycle.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/metadata.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/overrides/main.html +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/robots.txt +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/shared-storage.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/stylesheets/extra.css +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/tutorial/index.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/tutorial/scalar.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/tutorial/table.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/docs/vgi-logo.png +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/examples/calc_scalar_worker.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/examples/calc_worker.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/examples/filter_worker.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/examples/greeting_scalar_worker.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/examples/row_count_worker.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/examples/series_streaming_worker.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/examples/sum_worker.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/mkdocs.yml +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/packages/vgi-fixtures/LICENSE +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/packages/vgi-fixtures/README.md +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/packages/vgi-fixtures/docker/Dockerfile +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/packages/vgi-fixtures/docker/docker-entrypoint.sh +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/packages/vgi-fixtures/pyproject.toml +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/scripts/measure_startup.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/scripts/run_all_tests.sh +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/test-data/generate.sh +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/_http_fixtures.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/catalog/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/catalog/test_catalog_interface.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/catalog/test_client_catalog.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/catalog/test_column_statistics.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/catalog/test_declarative.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/catalog/test_example_worker_catalog.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/catalog/test_integration.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/catalog/test_required_filters.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/catalog/test_scan_branches.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/catalog/test_serialization.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/catalog/test_setting.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/catalog/test_storage.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/catalog/test_time_travel.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/catalog/test_writable_table.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/client/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/client/test_broken_pipe.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/client/test_cli.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/client/test_cli_catalog_functions.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/client/test_worker_debug.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/_stub.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/conftest.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_accumulate.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_aggregate.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_attach.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_bearer_auth.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_const_param_enforcement.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_container.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_copy_from.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_copy_to.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_directory_parity.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_function_inventory.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_github.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_http_client.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_http_external_location.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_http_upload_url.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_macro.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_overload.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_protocol_inventory.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_resumable_scan.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_scalar.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_scalar_attach_opaque_data.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_secret.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_settings.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_table.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_table_in_out.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_view.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conformance/test_writable.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/conftest.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/landing/_checker.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/landing/describe.schema.json +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/scalar/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/scalar/test_bernoulli_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/scalar/test_binary_packet_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/scalar/test_client.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/scalar/test_conditional_message_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/scalar/test_hash_seed_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/scalar/test_multiply_by_setting_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/scalar/test_multiply_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/scalar/test_random_bytes_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/scalar/test_return_secret_value_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table/generator/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table/generator/test_constant_columns_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table/generator/test_double_sequence_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table/generator/test_exception_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table/generator/test_filter_echo_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table/generator/test_logging_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table/generator/test_nested_sequence_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table/generator/test_partitioned_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table/generator/test_projected_data_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table/generator/test_sequence_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table/generator/test_settings_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table/generator/test_struct_settings_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table/generator/test_ten_thousand_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table_in_out/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table_in_out/generator/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table_in_out/generator/test_buffer_input_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table_in_out/generator/test_echo_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table_in_out/generator/test_exception_functions.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table_in_out/generator/test_filter_by_setting_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table_in_out/generator/test_repeat_inputs_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table_in_out/generator/test_substream_partial_sum_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table_in_out/generator/test_sum_all_columns_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table_in_out/test_blended_metadata.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/table_in_out/test_client.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_access_log_audit.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_aggregate_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_argument_spec.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_auth.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_bind_exceptions.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_bind_request_at_clause.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_bound_storage_conformance.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_cache_control.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_catalog_auth_binding.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_copy_from_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_copy_to_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_docstrings.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_documentation_examples.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_example_function_arg_types.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_examples_workers.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_exception_handling.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_exceptions.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_filter_pushdown.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_filter_pushdown_extension.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_function_storage.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_function_storage_azure_sql.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_function_storage_cf_do.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_function_storage_cf_do_integration.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_function_storage_conformance.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_generated_cpp_constants.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_generated_cpp_protocol_version.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_generated_cpp_request_builders.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_generated_cpp_schemas.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_generated_cpp_secret.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_generated_go_schemas.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_generated_protocol_version.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_generated_schemas_cross_lang.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_generated_ts_client.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_generated_ts_schemas.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_http_demo_storage.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_http_s3_offload_input.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_http_s3_offload_output.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_landing_conformance.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_metadata.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_mypy_consolidated.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_nest_tensor.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_otel.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_projection_enforcement.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_projection_repro.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_protocol_classes.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_resolved_secrets.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_schema_scoped_functions.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_schema_utils.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_serve.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_setting_secret_annotations.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_table_buffering_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_table_function_dynamic_to_string.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_tcp_transport.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_type_bounds.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_union_argument.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_worker.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_worker_cli.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/test_worker_page.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/transactor/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/tests/transactor/test_transactor.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/uv.lock +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_duckdb.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_storage_profile.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/accumulate/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/accumulate/worker.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/aggregate/_common.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/aggregate/basic.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/aggregate/dynamic.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/aggregate/generic.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/aggregate/listagg.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/aggregate/percentile.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/aggregate/secret_typed.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/aggregate/streaming.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/aggregate/varargs.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/aggregate/window.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/attach_options.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/bad_enum.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/bad_protocol.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/cancellable.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/catalog.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/companion.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/copy_from.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/copy_to.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/http_server.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/narrow_bind/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/narrow_bind/worker.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/nest_tensor.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/orchard_catalog.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/projection_repro/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/projection_repro/worker.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/scalar/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/scalar/_common.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/scalar/arithmetic.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/scalar/bench_ladder.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/scalar/binary.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/scalar/formatting.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/scalar/geo.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/scalar/null_handling.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/scalar/random_demo.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/scalar/same_name.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/scalar/settings_secrets.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/scalar/type_info.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/schema_reconcile/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/schema_reconcile/worker.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/simple_writable.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/_common.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/batch_index.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/batch_index_broken.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/cache.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/catalog_scans.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/filters.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/late_materialization.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/make_series.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/misc.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/order_modes.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/pairs.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/partition_columns.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/partition_columns_broken.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/profiling_example.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/required_filters.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/sequence.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/settings.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/transaction_storage.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/tt_pushdown.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/typed_probe.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table/versioned.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/table_in_out.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/twin_catalogs.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/versioned.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/versioned_tables.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/writable/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/writable/generic.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/writable/table.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/_test_fixtures/writable/worker.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/aggregate_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/argument_spec.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/arguments.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/attach_header.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/auth.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/cache_control.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/catalog/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/catalog/_descriptor_spec.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/catalog/attach_option.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/catalog/catalog_interface.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/catalog/descriptors.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/catalog/duckdb_statistics.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/catalog/secret_type.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/catalog/setting.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/catalog/storage.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/client/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/client/catalog_mixin.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/client/cli.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/client/cli_catalog.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/client/cli_schema.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/client/cli_table.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/client/cli_transaction.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/client/cli_utils.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/client/cli_view.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/client/client.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/codegen/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/codegen/_common.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/codegen/cpp_constants.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/codegen/cpp_protocol_version.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/codegen/cpp_request_builders.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/codegen/cpp_schemas.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/codegen/cpp_secret_protocol_version.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/codegen/cpp_secret_request_builders.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/codegen/cpp_secret_schemas.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/codegen/go_schemas.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/codegen/protocol_version.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/codegen/ts_client.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/codegen/ts_schemas.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/copy_from_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/copy_to_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/exceptions.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/function_storage.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/function_storage_azure_sql.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/function_storage_cf_do.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/http/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/http/demo_storage.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/http/describe_json.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/http/landing.html +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/http/landing_page.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/http/worker_page.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/invocation.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/logging_config.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/meta_worker.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/metadata.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/otel.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/py.typed +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/scalar_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/schema_utils.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/secret_protocol.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/secret_service.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/serve.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/table_buffering_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/table_filter_pushdown.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/table_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/table_in_out_function.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/transactor/__init__.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/transactor/_duckdb_compat.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/transactor/client.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/transactor/protocol.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/vgi/transactor/server.py +0 -0
- {vgi_python-0.19.0 → vgi_python-0.20.0}/wrangler.jsonc +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vgi-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.20.0
|
|
4
4
|
Summary: Vector Gateway Interface - Connect DuckDB to external programs via Apache Arrow
|
|
5
5
|
Project-URL: Homepage, https://query.farm
|
|
6
6
|
Project-URL: Repository, https://github.com/Query-farm/vgi-python
|
|
@@ -32,14 +32,14 @@ CLIENT_PROTOCOL_VERSION = VgiProtocol.protocol_version
|
|
|
32
32
|
|
|
33
33
|
def test_client_protocol_version_is_canonical() -> None:
|
|
34
34
|
"""Sanity-check the constants this test reasons about haven't drifted apart."""
|
|
35
|
-
assert CLIENT_PROTOCOL_VERSION == "1.
|
|
35
|
+
assert CLIENT_PROTOCOL_VERSION == "1.2.0"
|
|
36
36
|
# The fixture must be a genuine mismatch in the major/minor that the
|
|
37
37
|
# framework compares; a patch-only difference would (correctly) pass.
|
|
38
38
|
assert BAD_PROTOCOL_VERSION.split(".")[:2] != CLIENT_PROTOCOL_VERSION.split(".")[:2]
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
def test_mismatched_worker_protocol_version_raises() -> None:
|
|
42
|
-
"""A worker enforcing 99.0.0 must reject the 1.
|
|
42
|
+
"""A worker enforcing 99.0.0 must reject the 1.2.0 client at dispatch."""
|
|
43
43
|
with Client("vgi-fixture-bad-protocol-worker") as client, pytest.raises(ClientError) as exc_info:
|
|
44
44
|
list(
|
|
45
45
|
client.table_function(
|
|
@@ -54,5 +54,5 @@ def test_mismatched_worker_protocol_version_raises() -> None:
|
|
|
54
54
|
assert "protocol_version mismatch" in message
|
|
55
55
|
assert CLIENT_PROTOCOL_VERSION in message
|
|
56
56
|
assert BAD_PROTOCOL_VERSION in message
|
|
57
|
-
# Directional hint: the client (1.
|
|
57
|
+
# Directional hint: the client (1.2.0) is older than the worker (99.0.0).
|
|
58
58
|
assert "upgrade the VGI extension/client" in message
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
{
|
|
4
4
|
"attach_options": [],
|
|
5
5
|
"counts": {
|
|
6
|
-
"functions":
|
|
6
|
+
"functions": 217,
|
|
7
7
|
"schemas": 2,
|
|
8
8
|
"tables": 59,
|
|
9
9
|
"views": 3
|
|
@@ -16,6 +16,19 @@
|
|
|
16
16
|
{
|
|
17
17
|
"doc": "Example tables backed by functions",
|
|
18
18
|
"functions": [
|
|
19
|
+
{
|
|
20
|
+
"args": [
|
|
21
|
+
{
|
|
22
|
+
"desc": "Integer value to accumulate",
|
|
23
|
+
"name": "value",
|
|
24
|
+
"type": "int64"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"doc": "Schema-disambiguation probe; the data-schema aggregate",
|
|
28
|
+
"name": "test_same_name_agg",
|
|
29
|
+
"returns": "string",
|
|
30
|
+
"type": "aggregate"
|
|
31
|
+
},
|
|
19
32
|
{
|
|
20
33
|
"args": [
|
|
21
34
|
{
|
|
@@ -28,6 +41,24 @@
|
|
|
28
41
|
"name": "test_same_name_bind",
|
|
29
42
|
"returns": "string",
|
|
30
43
|
"type": "scalar"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"args": [],
|
|
47
|
+
"doc": "Schema-disambiguation probe; the data-schema cacheable producer",
|
|
48
|
+
"name": "test_same_name_cached",
|
|
49
|
+
"type": "table"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"args": [],
|
|
53
|
+
"doc": "Schema-disambiguation probe; the data-schema table-in-out",
|
|
54
|
+
"name": "test_same_name_transform",
|
|
55
|
+
"type": "table"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"args": [],
|
|
59
|
+
"doc": "Schema-disambiguation probe; the data-schema buffered function",
|
|
60
|
+
"name": "test_same_name_buffered",
|
|
61
|
+
"type": "table_in_out"
|
|
31
62
|
}
|
|
32
63
|
],
|
|
33
64
|
"name": "data",
|
|
@@ -371,6 +402,19 @@
|
|
|
371
402
|
"returns": "null",
|
|
372
403
|
"type": "aggregate"
|
|
373
404
|
},
|
|
405
|
+
{
|
|
406
|
+
"args": [
|
|
407
|
+
{
|
|
408
|
+
"desc": "Integer value to accumulate",
|
|
409
|
+
"name": "value",
|
|
410
|
+
"type": "int64"
|
|
411
|
+
}
|
|
412
|
+
],
|
|
413
|
+
"doc": "Schema-disambiguation probe; the main-schema aggregate",
|
|
414
|
+
"name": "test_same_name_agg",
|
|
415
|
+
"returns": "string",
|
|
416
|
+
"type": "aggregate"
|
|
417
|
+
},
|
|
374
418
|
{
|
|
375
419
|
"args": [
|
|
376
420
|
{
|
|
@@ -2884,6 +2928,18 @@
|
|
|
2884
2928
|
"name": "ten_thousand",
|
|
2885
2929
|
"type": "table"
|
|
2886
2930
|
},
|
|
2931
|
+
{
|
|
2932
|
+
"args": [],
|
|
2933
|
+
"doc": "Schema-disambiguation probe; the main-schema cacheable producer",
|
|
2934
|
+
"name": "test_same_name_cached",
|
|
2935
|
+
"type": "table"
|
|
2936
|
+
},
|
|
2937
|
+
{
|
|
2938
|
+
"args": [],
|
|
2939
|
+
"doc": "Schema-disambiguation probe; the main-schema table-in-out",
|
|
2940
|
+
"name": "test_same_name_transform",
|
|
2941
|
+
"type": "table"
|
|
2942
|
+
},
|
|
2887
2943
|
{
|
|
2888
2944
|
"args": [
|
|
2889
2945
|
{
|
|
@@ -3314,6 +3370,12 @@
|
|
|
3314
3370
|
"doc": "Distributed sum using the buffered (Sink+Combine+Source) model",
|
|
3315
3371
|
"name": "sum_all_columns_simple_distributed",
|
|
3316
3372
|
"type": "table_in_out"
|
|
3373
|
+
},
|
|
3374
|
+
{
|
|
3375
|
+
"args": [],
|
|
3376
|
+
"doc": "Schema-disambiguation probe; the main-schema buffered function",
|
|
3377
|
+
"name": "test_same_name_buffered",
|
|
3378
|
+
"type": "table_in_out"
|
|
3317
3379
|
}
|
|
3318
3380
|
],
|
|
3319
3381
|
"name": "main",
|
|
@@ -32,6 +32,7 @@ from vgi._test_fixtures.aggregate.dynamic import (
|
|
|
32
32
|
from vgi._test_fixtures.aggregate.generic import GenericSumFunction
|
|
33
33
|
from vgi._test_fixtures.aggregate.listagg import ListAggFunction
|
|
34
34
|
from vgi._test_fixtures.aggregate.percentile import PercentileFunction
|
|
35
|
+
from vgi._test_fixtures.aggregate.same_name import SameNameDataAgg, SameNameMainAgg
|
|
35
36
|
from vgi._test_fixtures.aggregate.secret_typed import SecretTypedSumFunction
|
|
36
37
|
from vgi._test_fixtures.aggregate.streaming import StreamingSumFunction
|
|
37
38
|
from vgi._test_fixtures.aggregate.varargs import SumAllFunction
|
|
@@ -45,6 +46,8 @@ from vgi._test_fixtures.aggregate.window import (
|
|
|
45
46
|
__all__ = [
|
|
46
47
|
"AvgFunction",
|
|
47
48
|
"CountFunction",
|
|
49
|
+
"SameNameDataAgg",
|
|
50
|
+
"SameNameMainAgg",
|
|
48
51
|
"DynamicAggregateFunction",
|
|
49
52
|
"DynamicMLAggregateFunction",
|
|
50
53
|
"GenericSumFunction",
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Copyright 2025, 2026 Query Farm LLC - https://query.farm
|
|
2
|
+
|
|
3
|
+
"""Same-name-in-two-schemas *aggregate* fixtures.
|
|
4
|
+
|
|
5
|
+
The third member of the schema-disambiguation family, after
|
|
6
|
+
:mod:`vgi._test_fixtures.scalar.same_name` (scalar) and
|
|
7
|
+
:mod:`vgi._test_fixtures.table_in_out_same_name` (table-in-out + buffering).
|
|
8
|
+
|
|
9
|
+
Aggregates are the widest surface of the three. Every aggregate RPC —
|
|
10
|
+
``aggregate_update`` / ``_combine`` / ``_finalize`` / ``_destructor``, the four
|
|
11
|
+
window calls, and the three streaming calls — resolves the function through the
|
|
12
|
+
worker's single ``_resolve_aggregate`` entry point, which had no schema to work
|
|
13
|
+
with: none of those request types carried one, not even ``AggregateBindRequest``.
|
|
14
|
+
So an aggregate name declared in two schemas resolved to whichever the by-name
|
|
15
|
+
lookup found first.
|
|
16
|
+
|
|
17
|
+
Both classes register under ``test_same_name_agg``, in the ``main`` and ``data``
|
|
18
|
+
schemas of the ``example`` catalog. Each returns a VARCHAR tagged with its own
|
|
19
|
+
schema *and* the aggregated value, so a mis-routed call reads as the wrong tag
|
|
20
|
+
rather than a plausible answer, and a call that mis-routes only partway (bind to
|
|
21
|
+
one implementation, update/finalize to another) still shows up — the tag is
|
|
22
|
+
stamped at ``finalize`` while the accumulation happens in ``update``.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
from dataclasses import dataclass
|
|
28
|
+
from typing import Annotated
|
|
29
|
+
|
|
30
|
+
import pyarrow as pa
|
|
31
|
+
from vgi_rpc import ArrowSerializableDataclass, ArrowType
|
|
32
|
+
|
|
33
|
+
from vgi.aggregate_function import AggregateFunction
|
|
34
|
+
from vgi.arguments import Param, Returns
|
|
35
|
+
from vgi.metadata import (
|
|
36
|
+
DistinctDependence,
|
|
37
|
+
FunctionExample,
|
|
38
|
+
NullHandling,
|
|
39
|
+
OrderDependence,
|
|
40
|
+
)
|
|
41
|
+
from vgi.table_function import ProcessParams
|
|
42
|
+
|
|
43
|
+
# Deliberately identical in both schemas — the collision is the point.
|
|
44
|
+
FUNCTION_NAME = "test_same_name_agg"
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass(kw_only=True)
|
|
48
|
+
class SameNameAggState(ArrowSerializableDataclass):
|
|
49
|
+
"""Running total for one group."""
|
|
50
|
+
|
|
51
|
+
total: Annotated[int, ArrowType(pa.int64())] = 0
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class _SameNameAgg(AggregateFunction[SameNameAggState]):
|
|
55
|
+
"""Shared body; each subclass supplies the schema it is declared in."""
|
|
56
|
+
|
|
57
|
+
#: Schema this implementation is registered into — the tag it stamps.
|
|
58
|
+
OWNING_SCHEMA: str = ""
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def initial_state(cls, params: ProcessParams[None]) -> SameNameAggState:
|
|
62
|
+
"""Start each group at zero."""
|
|
63
|
+
return SameNameAggState()
|
|
64
|
+
|
|
65
|
+
@classmethod
|
|
66
|
+
def update(
|
|
67
|
+
cls,
|
|
68
|
+
states: dict[int, SameNameAggState],
|
|
69
|
+
group_ids: pa.Int64Array,
|
|
70
|
+
value: Annotated[pa.Int64Array, Param(doc="Integer value to accumulate")],
|
|
71
|
+
) -> None:
|
|
72
|
+
"""Accumulate each row's value into its group."""
|
|
73
|
+
for gid, v in zip(group_ids.to_pylist(), value.to_pylist(), strict=True):
|
|
74
|
+
if v is None or gid is None:
|
|
75
|
+
continue
|
|
76
|
+
states[gid] = SameNameAggState(total=states[gid].total + v)
|
|
77
|
+
|
|
78
|
+
@classmethod
|
|
79
|
+
def combine(
|
|
80
|
+
cls,
|
|
81
|
+
source: SameNameAggState,
|
|
82
|
+
target: SameNameAggState,
|
|
83
|
+
params: ProcessParams[None],
|
|
84
|
+
) -> SameNameAggState:
|
|
85
|
+
"""Merge two partial states."""
|
|
86
|
+
return SameNameAggState(total=source.total + target.total)
|
|
87
|
+
|
|
88
|
+
@classmethod
|
|
89
|
+
def finalize(
|
|
90
|
+
cls,
|
|
91
|
+
group_ids: pa.Int64Array,
|
|
92
|
+
states: dict[int, SameNameAggState],
|
|
93
|
+
params: ProcessParams[None],
|
|
94
|
+
) -> Annotated[pa.RecordBatch, Returns(pa.string())]:
|
|
95
|
+
"""Tag each group's total with the owning schema."""
|
|
96
|
+
results = [f"{cls.OWNING_SCHEMA}:{states[gid.as_py()].total}" for gid in group_ids]
|
|
97
|
+
return pa.record_batch({"result": pa.array(results, type=pa.string())})
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class SameNameMainAgg(_SameNameAgg):
|
|
101
|
+
"""``test_same_name_agg`` as declared in the ``main`` schema."""
|
|
102
|
+
|
|
103
|
+
OWNING_SCHEMA = "main"
|
|
104
|
+
|
|
105
|
+
class Meta:
|
|
106
|
+
"""Function metadata."""
|
|
107
|
+
|
|
108
|
+
name = FUNCTION_NAME
|
|
109
|
+
description = "Schema-disambiguation probe; the main-schema aggregate"
|
|
110
|
+
null_handling = NullHandling.SPECIAL
|
|
111
|
+
order_dependent = OrderDependence.NOT_ORDER_DEPENDENT
|
|
112
|
+
distinct_dependent = DistinctDependence.NOT_DISTINCT_DEPENDENT
|
|
113
|
+
examples = [
|
|
114
|
+
FunctionExample(
|
|
115
|
+
sql="SELECT example.main.test_same_name_agg(n) FROM range(3) t(n)",
|
|
116
|
+
description="Returns 'main:3'",
|
|
117
|
+
),
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class SameNameDataAgg(_SameNameAgg):
|
|
122
|
+
"""``test_same_name_agg`` as declared in the ``data`` schema."""
|
|
123
|
+
|
|
124
|
+
OWNING_SCHEMA = "data"
|
|
125
|
+
|
|
126
|
+
class Meta:
|
|
127
|
+
"""Function metadata."""
|
|
128
|
+
|
|
129
|
+
name = FUNCTION_NAME
|
|
130
|
+
description = "Schema-disambiguation probe; the data-schema aggregate"
|
|
131
|
+
null_handling = NullHandling.SPECIAL
|
|
132
|
+
order_dependent = OrderDependence.NOT_ORDER_DEPENDENT
|
|
133
|
+
distinct_dependent = DistinctDependence.NOT_DISTINCT_DEPENDENT
|
|
134
|
+
examples = [
|
|
135
|
+
FunctionExample(
|
|
136
|
+
sql="SELECT example.data.test_same_name_agg(n) FROM range(3) t(n)",
|
|
137
|
+
description="Returns 'data:3'",
|
|
138
|
+
),
|
|
139
|
+
]
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Copyright 2025, 2026 Query Farm LLC - https://query.farm
|
|
2
|
+
|
|
3
|
+
"""Cacheable same-name-in-two-schemas producer fixtures.
|
|
4
|
+
|
|
5
|
+
The result-cache member of the schema-disambiguation family (see
|
|
6
|
+
``scalar/same_name.py``, ``table_in_out_same_name.py``, ``aggregate/same_name.py``).
|
|
7
|
+
Those probe *dispatch*; this one probes the *result cache*, a distinct layer.
|
|
8
|
+
|
|
9
|
+
``test_same_name_cached`` is a one-row producer table function that advertises
|
|
10
|
+
``vgi.cache.ttl`` and is registered in BOTH the ``main`` and ``data`` schemas of
|
|
11
|
+
the ``example`` catalog. Each schema's implementation emits a single row tagged
|
|
12
|
+
with its own schema name.
|
|
13
|
+
|
|
14
|
+
The result cache keyed on catalog + auth + function name with no schema
|
|
15
|
+
dimension, so the two implementations produced byte-identical cache keys and one
|
|
16
|
+
schema's memoized rows cross-served the other — the caching-layer twin of the
|
|
17
|
+
``(schema, name)`` dispatch bug. The tag makes a cross-serve visible:
|
|
18
|
+
``example.data.test_same_name_cached()`` would return a ``main`` row. With the
|
|
19
|
+
schema in the key, each schema gets its own entry (so ``vgi_result_cache()``
|
|
20
|
+
holds two rows for the one function name) and returns its own tag. Driven by
|
|
21
|
+
``cache/same_name_schemas.test``.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
from dataclasses import dataclass
|
|
27
|
+
from typing import ClassVar, cast
|
|
28
|
+
|
|
29
|
+
import pyarrow as pa
|
|
30
|
+
from vgi_rpc import ArrowSerializableDataclass
|
|
31
|
+
from vgi_rpc.rpc import OutputCollector
|
|
32
|
+
|
|
33
|
+
from vgi.cache_control import CacheControl
|
|
34
|
+
from vgi.metadata import FunctionExample
|
|
35
|
+
from vgi.protocol import VgiOutputCollector
|
|
36
|
+
from vgi.schema_utils import schema
|
|
37
|
+
from vgi.table_function import (
|
|
38
|
+
ProcessParams,
|
|
39
|
+
TableFunctionGenerator,
|
|
40
|
+
bind_fixed_schema,
|
|
41
|
+
init_single_worker,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
FUNCTION_NAME = "test_same_name_cached"
|
|
45
|
+
|
|
46
|
+
# Long enough that the TTL never lapses mid-test.
|
|
47
|
+
_TTL_SECONDS = 300
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@dataclass(slots=True, frozen=True)
|
|
51
|
+
class _CachedArgs:
|
|
52
|
+
"""Arguments for the cacheable same-name producer (none)."""
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@dataclass(kw_only=True)
|
|
56
|
+
class _CachedState(ArrowSerializableDataclass):
|
|
57
|
+
"""One-shot emit latch for the single output row."""
|
|
58
|
+
|
|
59
|
+
done: bool = False
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class _SameNameCached(TableFunctionGenerator[_CachedArgs, _CachedState]):
|
|
63
|
+
"""Shared body; each subclass supplies the schema it is declared in."""
|
|
64
|
+
|
|
65
|
+
#: Schema this implementation is declared in — the tag it stamps.
|
|
66
|
+
OWNING_SCHEMA: ClassVar[str] = ""
|
|
67
|
+
|
|
68
|
+
FunctionArguments = _CachedArgs
|
|
69
|
+
FIXED_SCHEMA: ClassVar[pa.Schema] = schema(tag=pa.string())
|
|
70
|
+
|
|
71
|
+
@classmethod
|
|
72
|
+
def initial_state(cls, params: ProcessParams[_CachedArgs]) -> _CachedState:
|
|
73
|
+
"""Fresh latch per (real, cache-missing) invocation."""
|
|
74
|
+
return _CachedState()
|
|
75
|
+
|
|
76
|
+
@classmethod
|
|
77
|
+
def process(
|
|
78
|
+
cls,
|
|
79
|
+
params: ProcessParams[_CachedArgs],
|
|
80
|
+
state: _CachedState,
|
|
81
|
+
out: OutputCollector,
|
|
82
|
+
) -> None:
|
|
83
|
+
"""Emit the single schema-tagged row once, advertising a cache TTL."""
|
|
84
|
+
if state.done:
|
|
85
|
+
out.finish()
|
|
86
|
+
return
|
|
87
|
+
batch = pa.RecordBatch.from_pydict({"tag": [cls.OWNING_SCHEMA]}, schema=params.output_schema)
|
|
88
|
+
cast(VgiOutputCollector, out).emit(batch, cache_control=CacheControl(ttl=_TTL_SECONDS))
|
|
89
|
+
state.done = True
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@init_single_worker
|
|
93
|
+
@bind_fixed_schema
|
|
94
|
+
class SameNameMainCached(_SameNameCached):
|
|
95
|
+
"""``test_same_name_cached`` as declared in the ``main`` schema."""
|
|
96
|
+
|
|
97
|
+
OWNING_SCHEMA = "main"
|
|
98
|
+
|
|
99
|
+
class Meta:
|
|
100
|
+
"""Function metadata."""
|
|
101
|
+
|
|
102
|
+
name = FUNCTION_NAME
|
|
103
|
+
description = "Schema-disambiguation probe; the main-schema cacheable producer"
|
|
104
|
+
categories = ["generator", "cache", "testing"]
|
|
105
|
+
examples = [
|
|
106
|
+
FunctionExample(
|
|
107
|
+
sql="SELECT * FROM example.main.test_same_name_cached()",
|
|
108
|
+
description="One cacheable row tagged 'main'",
|
|
109
|
+
),
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@init_single_worker
|
|
114
|
+
@bind_fixed_schema
|
|
115
|
+
class SameNameDataCached(_SameNameCached):
|
|
116
|
+
"""``test_same_name_cached`` as declared in the ``data`` schema."""
|
|
117
|
+
|
|
118
|
+
OWNING_SCHEMA = "data"
|
|
119
|
+
|
|
120
|
+
class Meta:
|
|
121
|
+
"""Function metadata."""
|
|
122
|
+
|
|
123
|
+
name = FUNCTION_NAME
|
|
124
|
+
description = "Schema-disambiguation probe; the data-schema cacheable producer"
|
|
125
|
+
categories = ["generator", "cache", "testing"]
|
|
126
|
+
examples = [
|
|
127
|
+
FunctionExample(
|
|
128
|
+
sql="SELECT * FROM example.data.test_same_name_cached()",
|
|
129
|
+
description="One cacheable row tagged 'data'",
|
|
130
|
+
),
|
|
131
|
+
]
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# Copyright 2025, 2026 Query Farm LLC - https://query.farm
|
|
2
|
+
|
|
3
|
+
"""Same-name-in-two-schemas *exchange-mode* fixtures.
|
|
4
|
+
|
|
5
|
+
The scalar analogue lives in :mod:`vgi._test_fixtures.scalar.same_name` and is
|
|
6
|
+
driven by ``scalar/same_name_schemas.test``. This module covers the two
|
|
7
|
+
exchange-mode shapes, which reach the worker through **different bind call
|
|
8
|
+
sites** in the DuckDB extension than scalars do:
|
|
9
|
+
|
|
10
|
+
* **table-in-out** (:class:`SameNameMainTransform` / :class:`SameNameDataTransform`)
|
|
11
|
+
— ``VgiTableInOutBind`` builds its bind-time connection directly rather than
|
|
12
|
+
going through ``AcquireAndBindConnection``.
|
|
13
|
+
* **table-buffering** (:class:`SameNameMainBuffered` / :class:`SameNameDataBuffered`)
|
|
14
|
+
— shares that same bind site, but its *runtime* connections come from the
|
|
15
|
+
buffering operator's own ``BuildAcquireParams``.
|
|
16
|
+
|
|
17
|
+
That distinction is the point. The extension originally threaded the owning
|
|
18
|
+
schema onto the runtime exchange connections but not onto the bind-time one, so
|
|
19
|
+
an exchange-mode call reached the worker with no ``BindRequest.schema_name`` and
|
|
20
|
+
could not be resolved when the same name was declared in two schemas. The scalar
|
|
21
|
+
fixture could not catch it — scalars bind through an entirely separate call site.
|
|
22
|
+
|
|
23
|
+
Each class registers under a name shared with its sibling, in the ``main`` and
|
|
24
|
+
``data`` schemas of the ``example`` catalog, and tags its rows with its own
|
|
25
|
+
schema, so a mis-routed bind reads as the wrong tag rather than a plausible
|
|
26
|
+
answer.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
from __future__ import annotations
|
|
30
|
+
|
|
31
|
+
from dataclasses import dataclass
|
|
32
|
+
|
|
33
|
+
import pyarrow as pa
|
|
34
|
+
from vgi_rpc import ArrowSerializableDataclass
|
|
35
|
+
from vgi_rpc.rpc import OutputCollector
|
|
36
|
+
|
|
37
|
+
from vgi._test_fixtures.table_in_out import SingleTableArguments
|
|
38
|
+
from vgi.invocation import BindResponse
|
|
39
|
+
from vgi.metadata import FunctionExample
|
|
40
|
+
from vgi.table_buffering_function import (
|
|
41
|
+
TableBufferingFunction,
|
|
42
|
+
TableBufferingParams,
|
|
43
|
+
)
|
|
44
|
+
from vgi.table_function import BindParams, ProcessParams
|
|
45
|
+
from vgi.table_in_out_function import TableInOutGenerator
|
|
46
|
+
|
|
47
|
+
# Deliberately shared across the two schemas — the collision is the point.
|
|
48
|
+
TRANSFORM_NAME = "test_same_name_transform"
|
|
49
|
+
BUFFERED_NAME = "test_same_name_buffered"
|
|
50
|
+
|
|
51
|
+
# The single output column every implementation here emits.
|
|
52
|
+
_OUTPUT_SCHEMA = pa.schema([pa.field("tag", pa.string())])
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _tags(schema_name: str, batch: pa.RecordBatch) -> pa.RecordBatch:
|
|
56
|
+
"""Render ``<schema_name>:<value>`` for every row of the first input column."""
|
|
57
|
+
return pa.RecordBatch.from_pydict(
|
|
58
|
+
{"tag": [None if v is None else f"{schema_name}:{v}" for v in batch.column(0).to_pylist()]},
|
|
59
|
+
schema=_OUTPUT_SCHEMA,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass(kw_only=True)
|
|
64
|
+
class _DrainState(ArrowSerializableDataclass):
|
|
65
|
+
"""Cursor over the buffered state_log; ``after_id`` starts before-first."""
|
|
66
|
+
|
|
67
|
+
after_id: int = -1
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# ---------------------------------------------------------------------------
|
|
71
|
+
# Table-in-out (streaming) pair
|
|
72
|
+
# ---------------------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class _SameNameTransform(TableInOutGenerator[SingleTableArguments]):
|
|
76
|
+
"""Shared body; each subclass supplies the schema it is declared in."""
|
|
77
|
+
|
|
78
|
+
#: Schema this implementation is registered into — the tag it stamps.
|
|
79
|
+
OWNING_SCHEMA: str = ""
|
|
80
|
+
|
|
81
|
+
@classmethod
|
|
82
|
+
def on_bind(cls, params: BindParams[SingleTableArguments]) -> BindResponse:
|
|
83
|
+
"""Emit a single VARCHAR column regardless of the input schema."""
|
|
84
|
+
return BindResponse(output_schema=_OUTPUT_SCHEMA)
|
|
85
|
+
|
|
86
|
+
@classmethod
|
|
87
|
+
def process(
|
|
88
|
+
cls,
|
|
89
|
+
params: ProcessParams[SingleTableArguments],
|
|
90
|
+
state: None,
|
|
91
|
+
batch: pa.RecordBatch,
|
|
92
|
+
out: OutputCollector,
|
|
93
|
+
) -> None:
|
|
94
|
+
"""Tag each input row with the owning schema."""
|
|
95
|
+
out.emit(_tags(cls.OWNING_SCHEMA, batch))
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class SameNameMainTransform(_SameNameTransform):
|
|
99
|
+
"""``test_same_name_transform`` as declared in the ``main`` schema."""
|
|
100
|
+
|
|
101
|
+
OWNING_SCHEMA = "main"
|
|
102
|
+
|
|
103
|
+
class Meta:
|
|
104
|
+
"""Function metadata."""
|
|
105
|
+
|
|
106
|
+
name = TRANSFORM_NAME
|
|
107
|
+
description = "Schema-disambiguation probe; the main-schema table-in-out"
|
|
108
|
+
examples = [
|
|
109
|
+
FunctionExample(
|
|
110
|
+
sql=("SELECT * FROM example.main.test_same_name_transform((SELECT 1 AS n))"),
|
|
111
|
+
description="Returns 'main:1'",
|
|
112
|
+
),
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class SameNameDataTransform(_SameNameTransform):
|
|
117
|
+
"""``test_same_name_transform`` as declared in the ``data`` schema."""
|
|
118
|
+
|
|
119
|
+
OWNING_SCHEMA = "data"
|
|
120
|
+
|
|
121
|
+
class Meta:
|
|
122
|
+
"""Function metadata."""
|
|
123
|
+
|
|
124
|
+
name = TRANSFORM_NAME
|
|
125
|
+
description = "Schema-disambiguation probe; the data-schema table-in-out"
|
|
126
|
+
examples = [
|
|
127
|
+
FunctionExample(
|
|
128
|
+
sql=("SELECT * FROM example.data.test_same_name_transform((SELECT 1 AS n))"),
|
|
129
|
+
description="Returns 'data:1'",
|
|
130
|
+
),
|
|
131
|
+
]
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
# ---------------------------------------------------------------------------
|
|
135
|
+
# Table-buffering pair
|
|
136
|
+
# ---------------------------------------------------------------------------
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class _SameNameBuffered(TableBufferingFunction[SingleTableArguments, _DrainState]):
|
|
140
|
+
"""Shared body; buffers tagged rows in Sink, drains them in Source."""
|
|
141
|
+
|
|
142
|
+
#: Schema this implementation is registered into — the tag it stamps.
|
|
143
|
+
OWNING_SCHEMA: str = ""
|
|
144
|
+
|
|
145
|
+
@classmethod
|
|
146
|
+
def on_bind(cls, params: BindParams[SingleTableArguments]) -> BindResponse:
|
|
147
|
+
"""Emit a single VARCHAR column regardless of the input schema."""
|
|
148
|
+
return BindResponse(output_schema=_OUTPUT_SCHEMA)
|
|
149
|
+
|
|
150
|
+
@classmethod
|
|
151
|
+
def process(
|
|
152
|
+
cls,
|
|
153
|
+
batch: pa.RecordBatch,
|
|
154
|
+
params: TableBufferingParams[SingleTableArguments],
|
|
155
|
+
) -> bytes:
|
|
156
|
+
"""Tag the batch in the Sink phase and buffer it for the Source phase.
|
|
157
|
+
|
|
158
|
+
Tagging here (rather than in ``finalize``) is deliberate: it proves the
|
|
159
|
+
SINK-side worker resolved the right implementation, which is a distinct
|
|
160
|
+
connection from the one the Source phase acquires.
|
|
161
|
+
"""
|
|
162
|
+
sink = pa.BufferOutputStream()
|
|
163
|
+
tagged = _tags(cls.OWNING_SCHEMA, batch)
|
|
164
|
+
with pa.ipc.new_stream(sink, tagged.schema) as writer:
|
|
165
|
+
writer.write_batch(tagged)
|
|
166
|
+
params.storage.state_append(b"buf", b"", sink.getvalue().to_pybytes())
|
|
167
|
+
return params.execution_id
|
|
168
|
+
|
|
169
|
+
@classmethod
|
|
170
|
+
def combine(
|
|
171
|
+
cls,
|
|
172
|
+
state_ids: list[bytes], # noqa: ARG003 - collapse to one finalize stream
|
|
173
|
+
params: TableBufferingParams[SingleTableArguments],
|
|
174
|
+
) -> list[bytes]:
|
|
175
|
+
"""Collapse every Sink bucket into one finalize stream."""
|
|
176
|
+
return [params.execution_id]
|
|
177
|
+
|
|
178
|
+
@classmethod
|
|
179
|
+
def initial_finalize_state(
|
|
180
|
+
cls,
|
|
181
|
+
finalize_state_id: bytes, # noqa: ARG003 - one bucket per execution
|
|
182
|
+
params: TableBufferingParams[SingleTableArguments], # noqa: ARG003
|
|
183
|
+
) -> _DrainState:
|
|
184
|
+
"""Start the drain cursor before the first buffered batch."""
|
|
185
|
+
return _DrainState(after_id=-1)
|
|
186
|
+
|
|
187
|
+
@classmethod
|
|
188
|
+
def finalize(
|
|
189
|
+
cls,
|
|
190
|
+
params: TableBufferingParams[SingleTableArguments],
|
|
191
|
+
finalize_state_id: bytes, # noqa: ARG003
|
|
192
|
+
state: _DrainState,
|
|
193
|
+
out: OutputCollector,
|
|
194
|
+
) -> None:
|
|
195
|
+
"""Emit one buffered batch per tick."""
|
|
196
|
+
rows = params.storage.state_log_scan(
|
|
197
|
+
b"buf",
|
|
198
|
+
b"",
|
|
199
|
+
after_id=state.after_id,
|
|
200
|
+
limit=1,
|
|
201
|
+
)
|
|
202
|
+
if not rows:
|
|
203
|
+
out.finish()
|
|
204
|
+
return
|
|
205
|
+
log_id, value = rows[0]
|
|
206
|
+
out.emit(pa.ipc.open_stream(value).read_next_batch())
|
|
207
|
+
state.after_id = log_id
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
class SameNameMainBuffered(_SameNameBuffered):
|
|
211
|
+
"""``test_same_name_buffered`` as declared in the ``main`` schema."""
|
|
212
|
+
|
|
213
|
+
OWNING_SCHEMA = "main"
|
|
214
|
+
|
|
215
|
+
class Meta:
|
|
216
|
+
"""Function metadata."""
|
|
217
|
+
|
|
218
|
+
name = BUFFERED_NAME
|
|
219
|
+
description = "Schema-disambiguation probe; the main-schema buffered function"
|
|
220
|
+
examples = [
|
|
221
|
+
FunctionExample(
|
|
222
|
+
sql=("SELECT * FROM example.main.test_same_name_buffered((SELECT 1 AS n))"),
|
|
223
|
+
description="Returns 'main:1'",
|
|
224
|
+
),
|
|
225
|
+
]
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
class SameNameDataBuffered(_SameNameBuffered):
|
|
229
|
+
"""``test_same_name_buffered`` as declared in the ``data`` schema."""
|
|
230
|
+
|
|
231
|
+
OWNING_SCHEMA = "data"
|
|
232
|
+
|
|
233
|
+
class Meta:
|
|
234
|
+
"""Function metadata."""
|
|
235
|
+
|
|
236
|
+
name = BUFFERED_NAME
|
|
237
|
+
description = "Schema-disambiguation probe; the data-schema buffered function"
|
|
238
|
+
examples = [
|
|
239
|
+
FunctionExample(
|
|
240
|
+
sql=("SELECT * FROM example.data.test_same_name_buffered((SELECT 1 AS n))"),
|
|
241
|
+
description="Returns 'data:1'",
|
|
242
|
+
),
|
|
243
|
+
]
|