vgi-python 0.23.0__tar.gz → 0.24.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.23.0 → vgi_python-0.24.0}/.github/workflows/integration.yml +1 -1
- {vgi_python-0.23.0 → vgi_python-0.24.0}/CLAUDE.md +1 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/PKG-INFO +6 -3
- vgi_python-0.24.0/docs/global-functions.md +88 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/pyproject.toml +13 -3
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/catalog/test_declarative.py +148 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/catalog/test_serialization.py +3 -1
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_directory_parity.py +13 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_protocol_version.py +3 -3
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/landing/describe.expected.json +39 -1
- vgi_python-0.24.0/tests/table/test_wide_columns.py +84 -0
- vgi_python-0.24.0/tests/test_call_state_attach.py +346 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_protocol_classes.py +90 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_setting_secret_annotations.py +47 -2
- vgi_python-0.24.0/tests/test_signing_key.py +96 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/uv.lock +164 -32
- vgi_python-0.24.0/vgi/_test_fixtures/global_functions.py +316 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/_common.py +46 -3
- vgi_python-0.24.0/vgi/_test_fixtures/table/wide.py +113 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/worker.py +27 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/catalog/catalog_interface.py +39 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/catalog/descriptors.py +79 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/function.py +54 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/function_storage.py +71 -1
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/meta_worker.py +31 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/protocol.py +261 -110
- vgi_python-0.24.0/vgi/protocol_version.txt +1 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/serve.py +365 -17
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/table_function.py +147 -53
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/worker.py +146 -15
- vgi_python-0.23.0/vgi/protocol_version.txt +0 -1
- {vgi_python-0.23.0 → vgi_python-0.24.0}/.gitattributes +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/.github/dependabot.yml +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/.github/styles/config/vocabularies/VGI/accept.txt +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/.github/workflows/ci.yml +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/.github/workflows/docs.yml +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/.github/workflows/release.yml +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/.gitignore +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/.python-version +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/.vale.ini +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/DOCS_ACCEPTANCE_CRITERIA.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/DOCS_REVIEW_RUBRIC.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/DOCS_USABILITY_TEST.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/LICENSE +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/README.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/SECURITY.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/ci/README.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/ci/preprocess-require.awk +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/ci/run-integration.sh +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/dist-vgi/.gitignore +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/aggregate-functions.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/api/arguments.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/api/auth.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/api/catalogs.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/api/client.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/api/exceptions.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/api/filters.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/api/functions.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/api/http.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/api/index.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/api/metadata.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/api/observability.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/api/storage.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/api/transactor.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/api/worker.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/argument-serialization.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/assets/apple-touch-icon.png +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/assets/favicon-16x16.png +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/assets/favicon-32x32.png +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/assets/favicon.ico +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/assets/kinds/aggregate.svg +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/assets/kinds/buffering.svg +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/assets/kinds/scalar.svg +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/assets/kinds/table-in-out.svg +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/assets/kinds/table.svg +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/assets/logo.png +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/assets/social-card.png +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/authentication.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/catalog-interface.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/cli.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/column-statistics.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/concepts/index.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/contributing-docs.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/filter-pushdown.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/generator-api.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/how-to/catalogs.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/how-to/function-patterns.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/how-to/http-auth.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/how-to/index.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/how-to/pushdown-and-statistics.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/how-to/state-storage.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/index.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/lifecycle.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/metadata.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/overrides/main.html +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/robots.txt +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/shared-storage.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/stylesheets/extra.css +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/tutorial/index.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/tutorial/scalar.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/tutorial/table.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/docs/vgi-logo.png +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/examples/calc_scalar_worker.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/examples/calc_worker.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/examples/filter_worker.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/examples/greeting_scalar_worker.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/examples/row_count_worker.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/examples/series_streaming_worker.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/examples/sum_worker.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/mkdocs.yml +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/packages/vgi-fixtures/LICENSE +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/packages/vgi-fixtures/README.md +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/packages/vgi-fixtures/docker/Dockerfile +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/packages/vgi-fixtures/docker/docker-entrypoint.sh +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/packages/vgi-fixtures/pyproject.toml +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/scripts/measure_startup.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/scripts/run_all_tests.sh +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/test-data/generate.sh +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/_http_fixtures.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/catalog/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/catalog/test_catalog_interface.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/catalog/test_client_catalog.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/catalog/test_column_statistics.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/catalog/test_example_worker_catalog.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/catalog/test_integration.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/catalog/test_required_filters.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/catalog/test_scan_branches.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/catalog/test_setting.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/catalog/test_storage.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/catalog/test_time_travel.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/catalog/test_writable_table.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/client/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/client/test_broken_pipe.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/client/test_cli.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/client/test_cli_catalog_functions.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/client/test_worker_debug.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/_stub.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/conftest.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_accumulate.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_aggregate.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_attach.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_bearer_auth.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_const_param_enforcement.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_container.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_copy_from.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_copy_to.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_function_inventory.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_github.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_http_client.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_http_external_location.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_http_upload_url.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_macro.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_overload.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_protocol_inventory.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_resumable_scan.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_scalar.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_scalar_attach_opaque_data.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_secret.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_settings.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_table.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_table_in_out.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_view.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conformance/test_writable.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/conftest.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/landing/_checker.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/landing/describe.schema.json +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/scalar/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/scalar/test_bernoulli_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/scalar/test_binary_packet_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/scalar/test_client.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/scalar/test_conditional_message_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/scalar/test_hash_seed_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/scalar/test_multiply_by_setting_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/scalar/test_multiply_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/scalar/test_random_bytes_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/scalar/test_return_secret_value_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table/generator/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table/generator/test_constant_columns_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table/generator/test_double_sequence_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table/generator/test_exception_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table/generator/test_filter_echo_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table/generator/test_logging_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table/generator/test_nested_sequence_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table/generator/test_partitioned_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table/generator/test_projected_data_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table/generator/test_sequence_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table/generator/test_settings_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table/generator/test_struct_settings_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table/generator/test_ten_thousand_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table_in_out/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table_in_out/generator/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table_in_out/generator/test_buffer_input_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table_in_out/generator/test_echo_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table_in_out/generator/test_exception_functions.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table_in_out/generator/test_filter_by_setting_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table_in_out/generator/test_repeat_inputs_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table_in_out/generator/test_substream_partial_sum_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table_in_out/generator/test_sum_all_columns_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table_in_out/test_blended_metadata.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/table_in_out/test_client.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_access_log_audit.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_aggregate_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_argument_spec.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_auth.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_bind_exceptions.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_bind_request_at_clause.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_bound_storage_conformance.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_cache_control.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_catalog_auth_binding.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_copy_from_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_copy_to_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_docstrings.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_documentation_examples.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_example_function_arg_types.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_examples_workers.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_exception_handling.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_exceptions.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_filter_pushdown.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_filter_pushdown_extension.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_function_storage.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_function_storage_azure_sql.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_function_storage_cf_do.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_function_storage_cf_do_integration.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_function_storage_conformance.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_generated_cpp_constants.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_generated_cpp_protocol_version.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_generated_cpp_request_builders.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_generated_cpp_schemas.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_generated_cpp_secret.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_generated_go_schemas.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_generated_protocol_version.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_generated_schemas_cross_lang.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_generated_ts_client.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_generated_ts_schemas.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_http_demo_storage.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_http_s3_offload_input.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_http_s3_offload_output.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_landing_conformance.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_metadata.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_mypy_consolidated.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_nest_tensor.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_otel.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_projection_enforcement.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_projection_repro.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_resolved_secrets.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_schema_scoped_functions.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_schema_utils.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_serve.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_table_buffering_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_table_function_dynamic_to_string.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_tcp_transport.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_type_bounds.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_union_argument.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_worker.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_worker_cli.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/test_worker_page.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/transactor/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/tests/transactor/test_transactor.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_duckdb.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_storage_profile.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/accumulate/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/accumulate/worker.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/_common.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/basic.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/dynamic.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/generic.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/listagg.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/percentile.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/same_name.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/secret_typed.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/streaming.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/varargs.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/aggregate/window.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/attach_options.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/bad_enum.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/bad_protocol.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/cancellable.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/catalog.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/companion.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/copy_from.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/copy_to.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/http_server.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/narrow_bind/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/narrow_bind/worker.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/nest_tensor.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/orchard_catalog.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/projection_repro/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/projection_repro/worker.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/_common.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/arithmetic.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/bench_ladder.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/binary.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/formatting.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/geo.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/null_handling.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/random_demo.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/same_name.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/settings_secrets.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/scalar/type_info.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/schema_reconcile/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/schema_reconcile/worker.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/simple_writable.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/batch_index.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/batch_index_broken.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/cache.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/catalog_scans.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/filters.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/late_materialization.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/make_series.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/misc.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/order_modes.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/pairs.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/partition_columns.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/partition_columns_broken.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/profiling_example.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/required_filters.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/same_name_cached.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/sequence.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/settings.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/transaction_storage.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/tt_pushdown.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/typed_probe.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table/versioned.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table_in_out.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/table_in_out_same_name.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/twin_catalogs.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/versioned.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/versioned_tables.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/writable/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/writable/generic.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/writable/table.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/_test_fixtures/writable/worker.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/aggregate_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/argument_spec.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/arguments.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/attach_header.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/auth.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/cache_control.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/catalog/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/catalog/_descriptor_spec.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/catalog/attach_option.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/catalog/duckdb_statistics.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/catalog/secret_type.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/catalog/setting.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/catalog/storage.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/client/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/client/catalog_mixin.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/client/cli.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/client/cli_catalog.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/client/cli_schema.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/client/cli_table.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/client/cli_transaction.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/client/cli_utils.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/client/cli_view.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/client/client.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/codegen/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/codegen/_common.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/codegen/cpp_constants.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/codegen/cpp_protocol_version.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/codegen/cpp_request_builders.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/codegen/cpp_schemas.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/codegen/cpp_secret_protocol_version.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/codegen/cpp_secret_request_builders.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/codegen/cpp_secret_schemas.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/codegen/go_schemas.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/codegen/protocol_version.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/codegen/ts_client.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/codegen/ts_schemas.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/copy_from_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/copy_to_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/exceptions.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/function_storage_azure_sql.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/function_storage_cf_do.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/http/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/http/demo_storage.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/http/describe_json.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/http/landing.html +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/http/landing_page.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/http/worker_page.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/invocation.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/logging_config.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/metadata.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/otel.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/profiling.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/py.typed +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/scalar_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/schema_utils.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/secret_protocol.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/secret_service.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/table_buffering_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/table_filter_pushdown.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/table_in_out_function.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/transactor/__init__.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/transactor/_duckdb_compat.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/transactor/client.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/transactor/protocol.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/vgi/transactor/server.py +0 -0
- {vgi_python-0.23.0 → vgi_python-0.24.0}/wrangler.jsonc +0 -0
|
@@ -32,7 +32,7 @@ env:
|
|
|
32
32
|
VGI_REF: main
|
|
33
33
|
# The Haybarn release providing the prebuilt haybarn-unittest binary. Must be
|
|
34
34
|
# ABI-compatible with the community-published vgi extension.
|
|
35
|
-
HAYBARN_RELEASE: haybarn-v1.5.
|
|
35
|
+
HAYBARN_RELEASE: haybarn-v1.5.5-rc1
|
|
36
36
|
# CI is not a user: its ATTACHes should not land in Query.Farm's adoption data.
|
|
37
37
|
# The vgi extension fires a telemetry event per successful ATTACH, and this
|
|
38
38
|
# suite performs several hundred of them per lane, so opting out keeps the
|
|
@@ -508,4 +508,5 @@ The table schema is automatically derived from the function's `output_schema`:
|
|
|
508
508
|
- **Function lifecycle**: `docs/lifecycle.md`
|
|
509
509
|
- **Generator API (advanced)**: `docs/generator-api.md`
|
|
510
510
|
- **Catalog interface**: `docs/catalog-interface.md`
|
|
511
|
+
- **Global functions (system.main)**: `docs/global-functions.md`
|
|
511
512
|
- **Shared storage backends**: `docs/shared-storage.md`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vgi-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.24.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
|
|
@@ -162,7 +162,7 @@ Requires-Dist: httpx>=0.24
|
|
|
162
162
|
Requires-Dist: platformdirs
|
|
163
163
|
Requires-Dist: pyarrow
|
|
164
164
|
Requires-Dist: typer>=0.9
|
|
165
|
-
Requires-Dist: vgi-rpc>=0.
|
|
165
|
+
Requires-Dist: vgi-rpc>=0.33.0
|
|
166
166
|
Provides-Extra: azure
|
|
167
167
|
Requires-Dist: azure-identity>=1.16.0; extra == 'azure'
|
|
168
168
|
Requires-Dist: pymssql>=2.3.0; extra == 'azure'
|
|
@@ -190,8 +190,11 @@ Provides-Extra: duckdb
|
|
|
190
190
|
Requires-Dist: duckdb>=1.5.3; extra == 'duckdb'
|
|
191
191
|
Provides-Extra: fixtures
|
|
192
192
|
Requires-Dist: vgi-fixtures; extra == 'fixtures'
|
|
193
|
+
Provides-Extra: granian
|
|
194
|
+
Requires-Dist: granian>=2.7; extra == 'granian'
|
|
195
|
+
Requires-Dist: vgi-rpc[http]; extra == 'granian'
|
|
193
196
|
Provides-Extra: haybarn
|
|
194
|
-
Requires-Dist: haybarn>=1.5.
|
|
197
|
+
Requires-Dist: haybarn>=1.5.5rc1; extra == 'haybarn'
|
|
195
198
|
Provides-Extra: http
|
|
196
199
|
Requires-Dist: vgi-rpc[http]; extra == 'http'
|
|
197
200
|
Provides-Extra: oauth
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Global functions
|
|
2
|
+
|
|
3
|
+
A VGI catalog normally exposes its functions under its own name — `mycat.main.my_func()`.
|
|
4
|
+
Some functions aren't *about* the attached catalog at all: diagnostics, converters, format
|
|
5
|
+
helpers. For those, a worker can ask the client to also publish them into the **global**
|
|
6
|
+
function namespace (DuckDB's `system.main`), so they can be called unqualified:
|
|
7
|
+
|
|
8
|
+
```sql
|
|
9
|
+
ATTACH 'acme' AS acme (TYPE vgi, LOCATION 'acme-worker');
|
|
10
|
+
SELECT * FROM acme_table_info('acme'); -- no catalog qualifier
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This mirrors how `ducklake_table_info` is reachable after `LOAD ducklake`, except that a VGI
|
|
14
|
+
worker's globals appear at `ATTACH` time rather than at extension load.
|
|
15
|
+
|
|
16
|
+
## Declaring globals
|
|
17
|
+
|
|
18
|
+
Add the function classes to `Catalog.global_functions` and pick a prefix:
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
from vgi.catalog import Catalog, Schema
|
|
22
|
+
|
|
23
|
+
CATALOG = Catalog(
|
|
24
|
+
name="acme",
|
|
25
|
+
global_function_prefix="acme",
|
|
26
|
+
global_functions=[TableInfoFunction, ChecksumFunction],
|
|
27
|
+
schemas=[
|
|
28
|
+
Schema(name="main", functions=[TableInfoFunction, ChecksumFunction, ...]),
|
|
29
|
+
],
|
|
30
|
+
)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
All four function types are supported: scalar, aggregate, table, and table-buffering.
|
|
34
|
+
|
|
35
|
+
**Every global must also appear in exactly one `Schema.functions`.** This is enforced in
|
|
36
|
+
`Catalog.__post_init__`. Bind dispatch is keyed on `(schema_name, name)`, so a function listed
|
|
37
|
+
only in `global_functions` would be registered by the client but never dispatchable. Keeping it
|
|
38
|
+
schema-resident also means the qualified name (`acme.main.table_info()`) keeps working, which is
|
|
39
|
+
the unambiguous fallback if the global name is unavailable.
|
|
40
|
+
|
|
41
|
+
### The prefix
|
|
42
|
+
|
|
43
|
+
`global_function_prefix` is applied by the client to form the globally visible name:
|
|
44
|
+
|
|
45
|
+
| prefix | function name | published as |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| `"acme"` | `table_info` | `acme_table_info` |
|
|
48
|
+
| `None` | `table_info` | `table_info` |
|
|
49
|
+
|
|
50
|
+
The prefix must match `[a-z_][a-z0-9_]*` — it is concatenated into a SQL identifier.
|
|
51
|
+
|
|
52
|
+
**Prefer a prefix.** `system.main` is shared by every extension and every attached VGI worker in
|
|
53
|
+
the process. An unprefixed name like `table_info` is very likely to be claimed by someone else,
|
|
54
|
+
in which case yours is silently skipped (see below). A prefix that identifies your worker makes
|
|
55
|
+
collisions essentially impossible.
|
|
56
|
+
|
|
57
|
+
## What the client does with them
|
|
58
|
+
|
|
59
|
+
Registration is **best-effort and advisory**. Do not build anything that requires a global name
|
|
60
|
+
to resolve — treat it as an ergonomic alias for the schema-qualified name, which is the one with
|
|
61
|
+
guarantees.
|
|
62
|
+
|
|
63
|
+
Specifically, on the DuckDB side:
|
|
64
|
+
|
|
65
|
+
- **First attach wins.** If the name is already owned by a different worker, yours is skipped and
|
|
66
|
+
logged; your `ATTACH` still succeeds and the function stays reachable at its qualified path.
|
|
67
|
+
- **Re-`ATTACH` is idempotent.** Attaching the same worker again reuses the existing registration
|
|
68
|
+
and refreshes its connection state.
|
|
69
|
+
- **The user can turn it off.** `ATTACH ... (TYPE vgi, global_functions false)` suppresses
|
|
70
|
+
publishing entirely for that attach.
|
|
71
|
+
- **Registration outlives `DETACH`.** DuckDB has no API to unregister a function, so the entry
|
|
72
|
+
persists for the life of the process. Calling it after `DETACH` raises an error telling the user
|
|
73
|
+
to re-`ATTACH` rather than silently reconnecting to a detached catalog.
|
|
74
|
+
|
|
75
|
+
Use `vgi_global_functions()` to see what is currently published, who owns it, and whether it is
|
|
76
|
+
still live.
|
|
77
|
+
|
|
78
|
+
## Protocol
|
|
79
|
+
|
|
80
|
+
Globals ride on the existing attach response — there is no extra round trip and no separate RPC.
|
|
81
|
+
`CatalogAttachResult` carries:
|
|
82
|
+
|
|
83
|
+
- `global_functions: list[bytes]` — IPC-serialized `FunctionInfo` records. `name` and
|
|
84
|
+
`schema_name` are the real dispatch coordinates; the prefix is *not* baked into `name`.
|
|
85
|
+
- `global_function_prefix: str` — empty string means publish bare names.
|
|
86
|
+
|
|
87
|
+
Both fields are additive and default to empty, so a worker that doesn't set them advertises
|
|
88
|
+
nothing. Introduced in protocol version 1.3.0.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "vgi-python"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.24.0"
|
|
4
4
|
description = "Vector Gateway Interface - Connect DuckDB to external programs via Apache Arrow"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
keywords = [
|
|
@@ -40,7 +40,7 @@ dependencies = [
|
|
|
40
40
|
"pyarrow",
|
|
41
41
|
"typer>=0.9",
|
|
42
42
|
"platformdirs",
|
|
43
|
-
"vgi-rpc>=0.
|
|
43
|
+
"vgi-rpc>=0.33.0",
|
|
44
44
|
"httpx>=0.24",
|
|
45
45
|
]
|
|
46
46
|
|
|
@@ -49,9 +49,13 @@ dependencies = [
|
|
|
49
49
|
# evaluation, the transactor, and the statistics fixtures. It is resolved
|
|
50
50
|
# lazily in vgi/_duckdb.py: haybarn is preferred, stock duckdb is the
|
|
51
51
|
# fallback. Neither is a hard dependency — install one via these extras.
|
|
52
|
-
haybarn = ["haybarn>=1.5.
|
|
52
|
+
haybarn = ["haybarn>=1.5.5rc1"]
|
|
53
53
|
duckdb = ["duckdb>=1.5.3"]
|
|
54
54
|
http = ["vgi-rpc[http]"]
|
|
55
|
+
# Alternative HTTP server: granian moves socket I/O and HTTP parsing into Rust,
|
|
56
|
+
# off the GIL. Optional because it is a compiled extension where waitress is
|
|
57
|
+
# pure Python; select it with `vgi-serve --http --server granian`.
|
|
58
|
+
granian = ["vgi-rpc[http]", "granian>=2.7"]
|
|
55
59
|
oauth = ["vgi-rpc[oauth]"]
|
|
56
60
|
otel = ["vgi-rpc[otel]"]
|
|
57
61
|
sentry = ["vgi-rpc[sentry]"]
|
|
@@ -187,6 +191,12 @@ warn_unused_ignores = true
|
|
|
187
191
|
module = "typer.*"
|
|
188
192
|
ignore_missing_imports = true
|
|
189
193
|
|
|
194
|
+
[[tool.mypy.overrides]]
|
|
195
|
+
# granian ships no stubs, and is an optional extra used only behind
|
|
196
|
+
# `--server granian`.
|
|
197
|
+
module = "granian.*"
|
|
198
|
+
ignore_missing_imports = true
|
|
199
|
+
|
|
190
200
|
[[tool.mypy.overrides]]
|
|
191
201
|
# These files have type: ignore comments for ty that mypy doesn't need
|
|
192
202
|
module = ["vgi._test_fixtures.scalar.null_handling", "vgi.table_function"]
|
|
@@ -26,6 +26,7 @@ from vgi.catalog import (
|
|
|
26
26
|
Catalog,
|
|
27
27
|
CatalogAttachResult,
|
|
28
28
|
ForeignKeyDef,
|
|
29
|
+
FunctionInfo,
|
|
29
30
|
Macro,
|
|
30
31
|
MacroInfo,
|
|
31
32
|
MacroType,
|
|
@@ -41,6 +42,7 @@ from vgi.catalog import (
|
|
|
41
42
|
View,
|
|
42
43
|
ViewInfo,
|
|
43
44
|
)
|
|
45
|
+
from vgi.catalog.catalog_interface import FunctionType as CatalogInterfaceFunctionType
|
|
44
46
|
from vgi.invocation import BindResponse
|
|
45
47
|
from vgi.schema_utils import schema
|
|
46
48
|
from vgi.table_function import (
|
|
@@ -1394,6 +1396,152 @@ class TestCatalogValidation:
|
|
|
1394
1396
|
Catalog(name="myapp", schemas=[s1, s2])
|
|
1395
1397
|
|
|
1396
1398
|
|
|
1399
|
+
class TestGlobalFunctionsValidation:
|
|
1400
|
+
"""Validation for ``Catalog.global_functions`` / ``global_function_prefix``."""
|
|
1401
|
+
|
|
1402
|
+
def test_defaults_are_empty(self) -> None:
|
|
1403
|
+
"""A catalog publishes nothing globally unless it asks to."""
|
|
1404
|
+
catalog = Catalog(name="myapp", schemas=[Schema(name="main")])
|
|
1405
|
+
assert catalog.global_functions == ()
|
|
1406
|
+
assert catalog.global_function_prefix is None
|
|
1407
|
+
|
|
1408
|
+
def test_accepts_schema_resident_function(self) -> None:
|
|
1409
|
+
"""The happy path: listed once globally, resident in exactly one schema."""
|
|
1410
|
+
catalog = Catalog(
|
|
1411
|
+
name="myapp",
|
|
1412
|
+
schemas=[Schema(name="main", functions=[UsersFunction])],
|
|
1413
|
+
global_functions=[UsersFunction],
|
|
1414
|
+
global_function_prefix="myapp",
|
|
1415
|
+
)
|
|
1416
|
+
assert list(catalog.global_functions) == [UsersFunction]
|
|
1417
|
+
assert catalog.global_function_prefix == "myapp"
|
|
1418
|
+
|
|
1419
|
+
def test_rejects_function_absent_from_every_schema(self) -> None:
|
|
1420
|
+
"""A global function that isn't schema-resident would never dispatch."""
|
|
1421
|
+
with pytest.raises(ValueError, match="does not appear in any Schema.functions"):
|
|
1422
|
+
Catalog(
|
|
1423
|
+
name="myapp",
|
|
1424
|
+
schemas=[Schema(name="main")],
|
|
1425
|
+
global_functions=[UsersFunction],
|
|
1426
|
+
)
|
|
1427
|
+
|
|
1428
|
+
def test_rejects_function_resident_in_multiple_schemas(self) -> None:
|
|
1429
|
+
"""Two homes make the global registration ambiguous about dispatch."""
|
|
1430
|
+
with pytest.raises(ValueError, match="appears in multiple schemas"):
|
|
1431
|
+
Catalog(
|
|
1432
|
+
name="myapp",
|
|
1433
|
+
schemas=[
|
|
1434
|
+
Schema(name="main", functions=[UsersFunction]),
|
|
1435
|
+
Schema(name="other", functions=[UsersFunction]),
|
|
1436
|
+
],
|
|
1437
|
+
global_functions=[UsersFunction],
|
|
1438
|
+
)
|
|
1439
|
+
|
|
1440
|
+
def test_rejects_duplicate_global_entries(self) -> None:
|
|
1441
|
+
"""Listing a class twice would publish the same name twice."""
|
|
1442
|
+
with pytest.raises(ValueError, match="duplicate entry UsersFunction"):
|
|
1443
|
+
Catalog(
|
|
1444
|
+
name="myapp",
|
|
1445
|
+
schemas=[Schema(name="main", functions=[UsersFunction])],
|
|
1446
|
+
global_functions=[UsersFunction, UsersFunction],
|
|
1447
|
+
)
|
|
1448
|
+
|
|
1449
|
+
@pytest.mark.parametrize("prefix", ["9bad", "Bad", "has-dash", "has space", "", "trailing;"])
|
|
1450
|
+
def test_rejects_non_identifier_prefix(self, prefix: str) -> None:
|
|
1451
|
+
"""The prefix is concatenated into a SQL identifier, so it must be safe."""
|
|
1452
|
+
with pytest.raises(ValueError, match="not a valid SQL identifier prefix"):
|
|
1453
|
+
Catalog(
|
|
1454
|
+
name="myapp",
|
|
1455
|
+
schemas=[Schema(name="main", functions=[UsersFunction])],
|
|
1456
|
+
global_functions=[UsersFunction],
|
|
1457
|
+
global_function_prefix=prefix,
|
|
1458
|
+
)
|
|
1459
|
+
|
|
1460
|
+
def test_prefix_validated_even_without_global_functions(self) -> None:
|
|
1461
|
+
"""A bad prefix is a bug worth reporting even if nothing uses it yet."""
|
|
1462
|
+
with pytest.raises(ValueError, match="not a valid SQL identifier prefix"):
|
|
1463
|
+
Catalog(name="myapp", schemas=[Schema(name="main")], global_function_prefix="Bad")
|
|
1464
|
+
|
|
1465
|
+
|
|
1466
|
+
class TestGlobalFunctionsAttachResult:
|
|
1467
|
+
"""``catalog_attach`` advertises globals so the client can publish them."""
|
|
1468
|
+
|
|
1469
|
+
@staticmethod
|
|
1470
|
+
def _attach(catalog_obj: Catalog) -> CatalogAttachResult:
|
|
1471
|
+
class _TestCatalog(ReadOnlyCatalogInterface):
|
|
1472
|
+
catalog = catalog_obj
|
|
1473
|
+
|
|
1474
|
+
return _TestCatalog().catalog_attach(
|
|
1475
|
+
name=catalog_obj.name,
|
|
1476
|
+
options={},
|
|
1477
|
+
data_version_spec=None,
|
|
1478
|
+
implementation_version=None,
|
|
1479
|
+
)
|
|
1480
|
+
|
|
1481
|
+
def test_absent_when_not_declared(self) -> None:
|
|
1482
|
+
"""Catalogs that declare nothing advertise an empty list and no prefix."""
|
|
1483
|
+
result = self._attach(Catalog(name="myapp", schemas=[Schema(name="main", functions=[UsersFunction])]))
|
|
1484
|
+
assert result.global_functions == []
|
|
1485
|
+
assert result.global_function_prefix == ""
|
|
1486
|
+
|
|
1487
|
+
def test_carries_serialized_function_info(self) -> None:
|
|
1488
|
+
"""Each global arrives as a FunctionInfo with real dispatch coordinates.
|
|
1489
|
+
|
|
1490
|
+
``name``/``schema_name`` must stay the values bind dispatches on — the
|
|
1491
|
+
prefix is applied client-side, not baked into the name here.
|
|
1492
|
+
"""
|
|
1493
|
+
result = self._attach(
|
|
1494
|
+
Catalog(
|
|
1495
|
+
name="myapp",
|
|
1496
|
+
schemas=[Schema(name="analytics", functions=[UsersFunction])],
|
|
1497
|
+
default_schema="analytics",
|
|
1498
|
+
global_functions=[UsersFunction],
|
|
1499
|
+
global_function_prefix="myapp",
|
|
1500
|
+
)
|
|
1501
|
+
)
|
|
1502
|
+
assert result.global_function_prefix == "myapp"
|
|
1503
|
+
assert len(result.global_functions) == 1
|
|
1504
|
+
|
|
1505
|
+
info = FunctionInfo.deserialize_from_bytes(result.global_functions[0])
|
|
1506
|
+
assert info.name == "users"
|
|
1507
|
+
assert info.schema_name == "analytics"
|
|
1508
|
+
assert info.function_type == CatalogInterfaceFunctionType.TABLE
|
|
1509
|
+
|
|
1510
|
+
def test_prefix_empty_string_when_unset(self) -> None:
|
|
1511
|
+
"""``None`` prefix serializes as empty string — the wire type is str."""
|
|
1512
|
+
result = self._attach(
|
|
1513
|
+
Catalog(
|
|
1514
|
+
name="myapp",
|
|
1515
|
+
schemas=[Schema(name="main", functions=[UsersFunction])],
|
|
1516
|
+
global_functions=[UsersFunction],
|
|
1517
|
+
)
|
|
1518
|
+
)
|
|
1519
|
+
assert result.global_function_prefix == ""
|
|
1520
|
+
assert len(result.global_functions) == 1
|
|
1521
|
+
|
|
1522
|
+
def test_example_fixture_publishes_one_of_each_function_type(self) -> None:
|
|
1523
|
+
"""The shipped fixture covers all four types for the C++ integration suite."""
|
|
1524
|
+
from vgi._test_fixtures.worker import ExampleCatalog
|
|
1525
|
+
|
|
1526
|
+
result = ExampleCatalog().catalog_attach(
|
|
1527
|
+
name="example",
|
|
1528
|
+
options={},
|
|
1529
|
+
data_version_spec=None,
|
|
1530
|
+
implementation_version=None,
|
|
1531
|
+
)
|
|
1532
|
+
assert result.global_function_prefix == "vgi_example"
|
|
1533
|
+
infos = [FunctionInfo.deserialize_from_bytes(b) for b in result.global_functions]
|
|
1534
|
+
assert {i.function_type for i in infos} == {
|
|
1535
|
+
CatalogInterfaceFunctionType.SCALAR,
|
|
1536
|
+
CatalogInterfaceFunctionType.TABLE,
|
|
1537
|
+
CatalogInterfaceFunctionType.AGGREGATE,
|
|
1538
|
+
CatalogInterfaceFunctionType.TABLE_BUFFERING,
|
|
1539
|
+
}
|
|
1540
|
+
# Every advertised global must be schema-resident, or it could never
|
|
1541
|
+
# be dispatched after the client registers it.
|
|
1542
|
+
assert all(i.schema_name == "main" for i in infos)
|
|
1543
|
+
|
|
1544
|
+
|
|
1397
1545
|
# =============================================================================
|
|
1398
1546
|
# ReadOnlyCatalogInterface with Catalog Object Tests
|
|
1399
1547
|
# =============================================================================
|
|
@@ -1110,7 +1110,7 @@ class TestArrowSchemaCorrectness:
|
|
|
1110
1110
|
def test_catalog_attach_result_schema(self) -> None:
|
|
1111
1111
|
"""Verify CatalogAttachResult Arrow schema."""
|
|
1112
1112
|
schema = CatalogAttachResult.ARROW_SCHEMA
|
|
1113
|
-
assert len(schema) ==
|
|
1113
|
+
assert len(schema) == 17
|
|
1114
1114
|
assert schema.field("attach_opaque_data").type == pa.binary()
|
|
1115
1115
|
assert schema.field("supports_transactions").type == pa.bool_()
|
|
1116
1116
|
assert schema.field("supports_time_travel").type == pa.bool_()
|
|
@@ -1121,6 +1121,8 @@ class TestArrowSchemaCorrectness:
|
|
|
1121
1121
|
assert schema.field("settings").type == pa.list_(pa.binary())
|
|
1122
1122
|
assert schema.field("secret_types").type == pa.list_(pa.binary())
|
|
1123
1123
|
assert schema.field("attach_catalogs").type == pa.list_(pa.binary())
|
|
1124
|
+
assert schema.field("global_functions").type == pa.list_(pa.binary())
|
|
1125
|
+
assert schema.field("global_function_prefix").type == pa.string()
|
|
1124
1126
|
assert schema.field("resolved_data_version").type == pa.string()
|
|
1125
1127
|
assert schema.field("resolved_implementation_version").type == pa.string()
|
|
1126
1128
|
|
|
@@ -42,6 +42,19 @@ _EXEMPTIONS: dict[str, str] = {
|
|
|
42
42
|
"path, ProcessParams.if_none_match threading, and the revalidatable "
|
|
43
43
|
"fixture's 304 behavior)."
|
|
44
44
|
),
|
|
45
|
+
"global_functions": (
|
|
46
|
+
"Publishing worker-declared functions into DuckDB's system.main is "
|
|
47
|
+
"entirely a C++-extension concern: the registry, prefix application, "
|
|
48
|
+
"first-attach-wins collision policy, post-DETACH liveness, and the "
|
|
49
|
+
"vgi_global_functions() introspection surface all live in the "
|
|
50
|
+
"extension. The Python worker's only role is advertising "
|
|
51
|
+
"global_functions/global_function_prefix on the attach response, which "
|
|
52
|
+
"tests/catalog/test_declarative.py covers directly (descriptor "
|
|
53
|
+
"validation + the serialized FunctionInfo payload). The observable "
|
|
54
|
+
"behaviour is cross-language by construction and is covered by "
|
|
55
|
+
"vgi/test/sql/integration/global_functions/, which any worker "
|
|
56
|
+
"implementation runs via VGI_TEST_WORKER."
|
|
57
|
+
),
|
|
45
58
|
"filter_pushdown": (
|
|
46
59
|
"Per-type filter-pushdown coverage is mirrored by tests/test_filter_pushdown.py "
|
|
47
60
|
"and tests/test_filter_pushdown_extension.py, which drive the same predicate "
|
|
@@ -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.3.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.3.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.3.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": 221,
|
|
7
7
|
"schemas": 2,
|
|
8
8
|
"tables": 59,
|
|
9
9
|
"views": 3
|
|
@@ -371,6 +371,19 @@
|
|
|
371
371
|
{
|
|
372
372
|
"doc": "Example functions for testing VGI",
|
|
373
373
|
"functions": [
|
|
374
|
+
{
|
|
375
|
+
"args": [
|
|
376
|
+
{
|
|
377
|
+
"desc": "Column to sum",
|
|
378
|
+
"name": "value",
|
|
379
|
+
"type": "int64"
|
|
380
|
+
}
|
|
381
|
+
],
|
|
382
|
+
"doc": "Global-registration probe (aggregate)",
|
|
383
|
+
"name": "global_agg",
|
|
384
|
+
"returns": "int64",
|
|
385
|
+
"type": "aggregate"
|
|
386
|
+
},
|
|
374
387
|
{
|
|
375
388
|
"args": [
|
|
376
389
|
{
|
|
@@ -979,6 +992,19 @@
|
|
|
979
992
|
"returns": "double",
|
|
980
993
|
"type": "scalar"
|
|
981
994
|
},
|
|
995
|
+
{
|
|
996
|
+
"args": [
|
|
997
|
+
{
|
|
998
|
+
"desc": "Value to label",
|
|
999
|
+
"name": "value",
|
|
1000
|
+
"type": "int64"
|
|
1001
|
+
}
|
|
1002
|
+
],
|
|
1003
|
+
"doc": "Global-registration probe (scalar)",
|
|
1004
|
+
"name": "global_scalar",
|
|
1005
|
+
"returns": "string",
|
|
1006
|
+
"type": "scalar"
|
|
1007
|
+
},
|
|
982
1008
|
{
|
|
983
1009
|
"args": [
|
|
984
1010
|
{
|
|
@@ -2146,6 +2172,12 @@
|
|
|
2146
2172
|
"name": "geo_encode",
|
|
2147
2173
|
"type": "table"
|
|
2148
2174
|
},
|
|
2175
|
+
{
|
|
2176
|
+
"args": [],
|
|
2177
|
+
"doc": "Global-registration probe (table)",
|
|
2178
|
+
"name": "global_table",
|
|
2179
|
+
"type": "table"
|
|
2180
|
+
},
|
|
2149
2181
|
{
|
|
2150
2182
|
"args": [
|
|
2151
2183
|
{
|
|
@@ -3281,6 +3313,12 @@
|
|
|
3281
3313
|
"name": "exception_process",
|
|
3282
3314
|
"type": "table_in_out"
|
|
3283
3315
|
},
|
|
3316
|
+
{
|
|
3317
|
+
"args": [],
|
|
3318
|
+
"doc": "Global-registration probe (table-buffering)",
|
|
3319
|
+
"name": "global_buffered",
|
|
3320
|
+
"type": "table_in_out"
|
|
3321
|
+
},
|
|
3284
3322
|
{
|
|
3285
3323
|
"args": [],
|
|
3286
3324
|
"doc": "Worker sleeps in process (manual cancel test)",
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Copyright 2025, 2026 Query Farm LLC - https://query.farm
|
|
2
|
+
|
|
3
|
+
"""Tests for the wide-schema benchmark fixture.
|
|
4
|
+
|
|
5
|
+
Guards the fixture the width benchmarks depend on: if ``wide`` stops
|
|
6
|
+
producing the schema it claims, a profile taken against it measures
|
|
7
|
+
something other than what it says on the tin.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import pyarrow as pa
|
|
13
|
+
import pytest
|
|
14
|
+
from vgi_rpc.rpc import RpcServer
|
|
15
|
+
|
|
16
|
+
from vgi._test_fixtures.table.wide import DEFAULT_COLUMNS, WideFunction
|
|
17
|
+
from vgi.arguments import Arguments
|
|
18
|
+
from vgi.protocol import BindRequest, FunctionType, InitRequest, VgiProtocol
|
|
19
|
+
from vgi.worker import Worker
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class _WideWorker(Worker):
|
|
23
|
+
"""Worker exposing only the wide fixture, so it stays off ExampleWorker."""
|
|
24
|
+
|
|
25
|
+
functions = [WideFunction]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _scan(columns: int, count: int, batch_size: int) -> list[pa.RecordBatch]:
|
|
29
|
+
from vgi_rpc.http import http_connect, make_sync_client
|
|
30
|
+
|
|
31
|
+
key = b"\x11" * 32
|
|
32
|
+
worker = _WideWorker(quiet=True)
|
|
33
|
+
worker._signing_key = key
|
|
34
|
+
client = make_sync_client(RpcServer(VgiProtocol, worker, enable_describe=False), token_key=key)
|
|
35
|
+
with http_connect(VgiProtocol, client=client, compression_level=None) as proxy: # type: ignore[type-abstract]
|
|
36
|
+
bind = BindRequest(
|
|
37
|
+
function_name="wide",
|
|
38
|
+
arguments=Arguments(
|
|
39
|
+
positional=(pa.scalar(count),),
|
|
40
|
+
named={"columns": pa.scalar(columns), "batch_size": pa.scalar(batch_size)},
|
|
41
|
+
),
|
|
42
|
+
function_type=FunctionType.TABLE,
|
|
43
|
+
input_schema=pa.schema([]),
|
|
44
|
+
)
|
|
45
|
+
resp = proxy.bind(request=bind)
|
|
46
|
+
assert len(resp.output_schema) == columns
|
|
47
|
+
stream = proxy.init(
|
|
48
|
+
request=InitRequest(bind_call=bind, output_schema=resp.output_schema, bind_opaque_data=resp.opaque_data)
|
|
49
|
+
)
|
|
50
|
+
try:
|
|
51
|
+
return [ab.batch for ab in stream]
|
|
52
|
+
finally:
|
|
53
|
+
stream.close()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@pytest.mark.parametrize("columns", [1, 12, 2000])
|
|
57
|
+
def test_wide_emits_the_requested_width(columns: int) -> None:
|
|
58
|
+
"""The bound schema and every emitted batch carry exactly ``columns``."""
|
|
59
|
+
batches = _scan(columns=columns, count=8, batch_size=4)
|
|
60
|
+
assert batches, "expected at least one batch"
|
|
61
|
+
assert sum(b.num_rows for b in batches) == 8
|
|
62
|
+
for batch in batches:
|
|
63
|
+
assert batch.num_columns == columns
|
|
64
|
+
assert batch.schema.names[0] == "c0"
|
|
65
|
+
assert batch.schema.names[-1] == f"c{columns - 1}"
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def test_wide_survives_multi_turn_state_round_trip() -> None:
|
|
69
|
+
"""Rows stay contiguous across turns, so the cursor round-trips at width.
|
|
70
|
+
|
|
71
|
+
Each turn re-serializes state and rebuilds a zero-row sentinel batch of
|
|
72
|
+
the full width; this is the path the width benchmark exercises.
|
|
73
|
+
"""
|
|
74
|
+
batches = _scan(columns=DEFAULT_COLUMNS, count=20, batch_size=4)
|
|
75
|
+
values = [v for b in batches for v in b.column(0).to_pylist()]
|
|
76
|
+
assert values == list(range(20))
|
|
77
|
+
assert all(b.num_columns == DEFAULT_COLUMNS for b in batches)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_wide_is_not_registered_on_the_example_worker() -> None:
|
|
81
|
+
"""Keep it off ExampleWorker: that count is asserted by the C++ suite."""
|
|
82
|
+
from vgi._test_fixtures.worker import ExampleWorker
|
|
83
|
+
|
|
84
|
+
assert WideFunction not in ExampleWorker.functions
|