vgi-python 0.37.0__tar.gz → 0.37.2__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.37.0 → vgi_python-0.37.2}/.github/workflows/ci.yml +5 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/PKG-INFO +1 -1
- {vgi_python-0.37.0 → vgi_python-0.37.2}/pyproject.toml +1 -1
- vgi_python-0.37.2/tests/test_landing_discovery.py +81 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/uv.lock +1 -1
- vgi_python-0.37.2/vgi/_test_fixtures/secret_cache.py +237 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/__init__.py +2 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/partition_columns.py +126 -1
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/worker.py +35 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/http/landing.html +14 -14
- vgi_python-0.37.2/vgi/http/vgi-client.js +267 -0
- vgi_python-0.37.0/vgi/http/vgi-client.js +0 -22
- {vgi_python-0.37.0 → vgi_python-0.37.2}/.dockerignore +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/.gitattributes +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/.github/dependabot.yml +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/.github/styles/config/vocabularies/VGI/accept.txt +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/.github/workflows/docs.yml +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/.github/workflows/integration.yml +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/.github/workflows/release.yml +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/.github/workflows/tailnet-integration.yml +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/.gitignore +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/.python-version +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/.vale.ini +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/CLAUDE.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/DOCS_ACCEPTANCE_CRITERIA.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/DOCS_REVIEW_RUBRIC.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/DOCS_USABILITY_TEST.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/LICENSE +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/PROTOCOL.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/README.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/RELEASE-RUNBOOK.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/SECURITY.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/ci/README.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/ci/preprocess-require.awk +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/ci/run-integration.sh +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/README.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/cases/negative/and-too-few-children.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/cases/negative/delta-required-upsert.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/cases/negative/nested-runtime-filter.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/cases/negative/remove-with-expression.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/cases/negative/required-runtime-filter.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/cases/negative/snapshot-nonzero-revision.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/cases/negative/unknown-document-property.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/cases/negative/unknown-node.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/cases/positive/advisory-upsert-delta.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/cases/positive/boolean-column-predicate.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/cases/positive/empty-snapshot.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/cases/positive/nested-required-snapshot.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/cases/positive/remove-delta.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/cases/positive/runtime-filter-snapshot.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/filter-v2.schema.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/generate_runtime.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/manifest.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/run_worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/arithmetic-add/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/arithmetic-add/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/arithmetic-add/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/arithmetic-multiply/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/arithmetic-multiply/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/arithmetic-multiply/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/arithmetic-negate/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/arithmetic-negate/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/arithmetic-negate/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/arithmetic-subtract/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/arithmetic-subtract/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/arithmetic-subtract/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/cast-integer-to-double/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/cast-integer-to-double/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/cast-integer-to-double/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-distinct_from/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-distinct_from/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-distinct_from/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-distinct_from/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-eq/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-eq/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-eq/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-eq/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-ge/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-ge/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-ge/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-ge/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-gt/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-gt/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-gt/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-gt/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-le/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-le/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-le/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-le/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-lt/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-lt/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-lt/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-lt/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-ne/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-ne/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-ne/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-ne/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-not_distinct_from/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-not_distinct_from/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-not_distinct_from/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/comparison-not_distinct_from/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/delta-atomic-multi-update/delta-0.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/delta-atomic-multi-update/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/delta-atomic-multi-update/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/delta-atomic-multi-update/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/delta-empty-noop/delta-0.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/delta-empty-noop/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/delta-empty-noop/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/delta-empty-noop/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/delta-upsert-remove-stale/delta-0.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/delta-upsert-remove-stale/delta-1.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/delta-upsert-remove-stale/delta-2.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/delta-upsert-remove-stale/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/delta-upsert-remove-stale/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/delta-upsert-remove-stale/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/empty-snapshot/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/empty-snapshot/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/empty-snapshot/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/empty-snapshot/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-cast-type-not-null/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-cast-type-not-null/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-column-index/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-column-index/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-column-name/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-column-name/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-contextual-cast-without-session/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-contextual-cast-without-session/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-duplicate-predicate-id/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-duplicate-predicate-id/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-external-column-index/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-external-column-index/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-external-column-index/join-keys-0.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-external-column-name/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-external-column-name/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-external-column-name/join-keys-0.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-field-non-struct/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-field-non-struct/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-in-payload-not-list/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-in-payload-not-list/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-in-payload-null-list/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-in-payload-null-list/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-invalid-overload/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-invalid-overload/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-missing-literal/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-missing-literal/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-non-boolean-root/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-non-boolean-root/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-unknown-standard-function/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/error-unknown-standard-function/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/external-in-nonzero-column/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/external-in-nonzero-column/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/external-in-nonzero-column/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/external-in-nonzero-column/join-keys-0.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/external-in-nonzero-column/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/function-contains/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/function-contains/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/function-contains/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/function-ends-with/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/function-ends-with/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/function-ends-with/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/function-list-contains/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/function-list-contains/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/function-list-contains/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/function-starts-with/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/function-starts-with/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/function-starts-with/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/in-empty/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/in-empty/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/in-empty/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/in-empty/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/in-with-null/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/in-with-null/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/in-with-null/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/in-with-null/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/is-not-null/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/is-not-null/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/is-not-null/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/is-not-null/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/is-null/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/is-null/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/is-null/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/is-null/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/kleene-and/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/kleene-and/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/kleene-and/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/kleene-not/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/kleene-not/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/kleene-not/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/kleene-or/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/kleene-or/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/kleene-or/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/nan-comparison/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/nan-comparison/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/nan-comparison/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/negative-zero-membership/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/negative-zero-membership/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/negative-zero-membership/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/nested-null-propagation/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/nested-null-propagation/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/nested-null-propagation/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/not-in-empty/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/not-in-empty/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/not-in-empty/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/not-in-empty/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/not-in-with-null/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/not-in-with-null/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/not-in-with-null/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/not-in-with-null/worker-expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/session-integer-division/expected.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/session-integer-division/filter.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime/session-integer-division/input.arrow +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/conformance/filter-v2/runtime-manifest.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/dist-vgi/.gitignore +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/aggregate-functions.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/api/arguments.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/api/auth.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/api/catalogs.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/api/client.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/api/exceptions.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/api/filters.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/api/functions.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/api/http.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/api/index.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/api/metadata.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/api/observability.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/api/storage.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/api/transactor.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/api/worker.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/argument-serialization.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/assets/apple-touch-icon.png +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/assets/favicon-16x16.png +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/assets/favicon-32x32.png +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/assets/favicon.ico +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/assets/kinds/aggregate.svg +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/assets/kinds/buffering.svg +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/assets/kinds/scalar.svg +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/assets/kinds/table-in-out.svg +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/assets/kinds/table.svg +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/assets/logo.png +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/assets/social-card.png +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/authentication.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/catalog-interface.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/cli.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/column-statistics.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/concepts/index.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/contributing-docs.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/filter-pushdown.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/generator-api.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/global-functions.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/how-to/catalogs.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/how-to/function-patterns.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/how-to/http-auth.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/how-to/index.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/how-to/iroh.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/how-to/pushdown-and-statistics.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/how-to/state-storage.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/how-to/tailnet.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/index.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/lifecycle.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/metadata.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/overrides/main.html +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/protocol/index.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/protocol/vgi-catalog-query-pushdown-design.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/protocol/vgi-duckdb-filter-adapter.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/protocol/vgi-filter-encoding-v2-spec.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/protocol/vgi-protocol-proposed-changes.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/protocol/vgi-runtime-filter-artifacts.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/robots.txt +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/shared-storage.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/stylesheets/extra.css +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/tutorial/index.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/tutorial/scalar.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/tutorial/table.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/docs/vgi-logo.png +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/examples/batch_index_worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/examples/cache_worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/examples/calc_scalar_worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/examples/calc_worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/examples/copy_format_worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/examples/filter_worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/examples/greeting_scalar_worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/examples/row_count_worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/examples/series_streaming_worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/examples/sum_worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/identity.png +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/mkdocs.yml +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/packages/vgi-fixtures/LICENSE +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/packages/vgi-fixtures/README.md +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/packages/vgi-fixtures/docker/Dockerfile +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/packages/vgi-fixtures/docker/docker-entrypoint.sh +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/packages/vgi-fixtures/pyproject.toml +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/scripts/measure_startup.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/scripts/regen_generated.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/scripts/run_all_tests.sh +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/test-data/generate.sh +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/_http_fixtures.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/catalog/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/catalog/test_attach_option.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/catalog/test_catalog_interface.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/catalog/test_client_catalog.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/catalog/test_column_statistics.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/catalog/test_declarative.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/catalog/test_example_worker_catalog.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/catalog/test_integration.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/catalog/test_required_filters.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/catalog/test_scan_branches.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/catalog/test_serialization.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/catalog/test_setting.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/catalog/test_storage.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/catalog/test_time_travel.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/catalog/test_writable_table.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/test_aggregate_client.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/test_batch_metadata_callback.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/test_bind_and_join_keys.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/test_broken_pipe.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/test_cli.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/test_cli_catalog_functions.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/test_copy_client.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/test_http_response_budget.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/test_iroh_client.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/test_scan_branches_client.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/test_split_client.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/test_stop_force.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/test_table_column_statistics.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/test_time_travel_client.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/client/test_worker_debug.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/_stub.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/conftest.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_accumulate.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_aggregate.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_attach.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_bearer_auth.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_const_param_enforcement.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_container.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_copy_from.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_copy_to.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_directory_parity.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_function_inventory.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_github.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_http_client.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_http_external_location.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_http_upload_url.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_macro.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_overload.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_protocol_inventory.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_protocol_version.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_resumable_scan.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_scalar.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_scalar_attach_opaque_data.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_secret.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_settings.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_splits.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_table.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_table_in_out.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_view.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conformance/test_writable.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/conftest.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/data/split_tokens/anchor_len_overrun.bin +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/data/split_tokens/bad_fingerprint.bin +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/data/split_tokens/bad_flags_unsealed_but_key_present.bin +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/data/split_tokens/bad_version.bin +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/data/split_tokens/generate.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/data/split_tokens/manifest.json +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/data/split_tokens/reserved_flag_bit.bin +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/data/split_tokens/stale_anchor.bin +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/data/split_tokens/truncated.bin +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/data/split_tokens/valid_sealed.bin +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/data/split_tokens/valid_unsealed.bin +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/scalar/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/scalar/test_bernoulli_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/scalar/test_binary_packet_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/scalar/test_client.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/scalar/test_conditional_message_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/scalar/test_hash_seed_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/scalar/test_multiply_by_setting_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/scalar/test_multiply_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/scalar/test_random_bytes_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/scalar/test_return_secret_value_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table/generator/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table/generator/test_constant_columns_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table/generator/test_double_sequence_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table/generator/test_exception_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table/generator/test_filter_echo_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table/generator/test_logging_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table/generator/test_nested_sequence_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table/generator/test_partitioned_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table/generator/test_projected_data_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table/generator/test_sequence_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table/generator/test_settings_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table/generator/test_struct_settings_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table/generator/test_ten_thousand_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table/test_wide_columns.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table_in_out/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table_in_out/generator/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table_in_out/generator/test_buffer_input_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table_in_out/generator/test_echo_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table_in_out/generator/test_exception_functions.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table_in_out/generator/test_filter_by_setting_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table_in_out/generator/test_repeat_inputs_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table_in_out/generator/test_substream_partial_sum_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table_in_out/generator/test_sum_all_columns_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table_in_out/test_blended_exchange.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table_in_out/test_blended_metadata.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/table_in_out/test_client.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/tailnet/Dockerfile +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/tailnet/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/tailnet/compose.yaml +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/tailnet/probe.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/tailnet/run.sh +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/tailnet/test_worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/tailnet/worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_access_log_audit.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_aggregate_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_argument_spec.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_auth.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_bind_exceptions.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_bind_request_at_clause.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_bound_storage_conformance.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_cache_control.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_call_state_attach.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_catalog_auth_binding.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_client_oauth.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_codegen_request_inventory.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_copy_from_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_copy_to_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_docstrings.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_documentation_examples.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_dynamic_filter_http_turns.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_example_function_arg_types.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_examples_workers.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_exception_handling.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_exceptions.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_filter_pushdown.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_filter_pushdown_extension.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_filter_v2.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_filter_v2_builder.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_filter_v2_runtime_corpus.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_filter_v2_spec_schema.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_fixture_catalog_parity.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_function_shape_mismatch.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_function_storage.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_function_storage_azure_sql.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_function_storage_cf_do.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_function_storage_cf_do_integration.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_function_storage_conformance.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_generated_cpp_constants.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_generated_cpp_protocol_name.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_generated_cpp_protocol_version.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_generated_cpp_request_builders.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_generated_cpp_schemas.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_generated_cpp_secret.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_generated_go_schemas.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_generated_java_schemas.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_generated_protocol_version.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_generated_rust_request_builders.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_generated_rust_schemas.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_generated_schemas_cross_lang.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_generated_ts_client.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_generated_ts_schemas.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_http_demo_storage.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_http_s3_offload_input.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_http_s3_offload_output.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_import_side_effects.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_launch_transport.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_metadata.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_mypy_consolidated.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_nest_tensor.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_otel.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_projection_enforcement.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_projection_repro.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_protocol_classes.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_resolved_secrets.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_schema_paths_v2.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_schema_scoped_functions.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_schema_utils.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_serve.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_setting_secret_annotations.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_signing_key.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_split_token.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_subprocess_transport.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_table_buffering_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_table_function_dynamic_to_string.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_tcp_transport.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_type_bounds.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_union_argument.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_wire_record_schema_parity.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_worker_cli.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_worker_page.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/test_write_results.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/transactor/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/tests/transactor/test_transactor.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_duckdb.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_storage_profile.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/accumulate/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/accumulate/worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/aggregate/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/aggregate/_common.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/aggregate/basic.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/aggregate/dynamic.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/aggregate/generic.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/aggregate/listagg.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/aggregate/percentile.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/aggregate/same_name.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/aggregate/secret_typed.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/aggregate/streaming.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/aggregate/varargs.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/aggregate/window.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/attach_options.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/bad_enum.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/bad_protocol.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/cancellable.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/catalog.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/companion.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/copy_from.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/copy_to.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/global_functions.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/http_server.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/narrow_bind/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/narrow_bind/worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/nest_tensor.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/orchard_catalog.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/projection_repro/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/projection_repro/worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/scalar/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/scalar/_common.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/scalar/arithmetic.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/scalar/bench_ladder.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/scalar/binary.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/scalar/formatting.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/scalar/geo.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/scalar/null_handling.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/scalar/random_demo.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/scalar/same_name.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/scalar/settings_secrets.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/scalar/type_info.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/schema_reconcile/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/schema_reconcile/worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/simple_writable.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/_common.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/batch_index.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/batch_index_broken.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/cache.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/catalog_scans.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/filters.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/late_materialization.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/make_series.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/misc.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/order_modes.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/pairs.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/partition_columns_broken.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/profiling_example.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/required_filters.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/same_name_cached.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/same_name_schemas.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/sequence.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/settings.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/splits.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/transaction_storage.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/tt_pushdown.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/typed_probe.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/versioned.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table/wide.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table_in_out.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/table_in_out_same_name.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/twin_catalogs.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/versioned.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/versioned_tables.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/writable/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/writable/generic.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/writable/table.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/_test_fixtures/writable/worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/aggregate_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/argument_spec.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/arguments.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/attach_header.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/auth.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/cache_control.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/catalog/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/catalog/_descriptor_spec.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/catalog/attach_option.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/catalog/catalog_interface.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/catalog/descriptors.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/catalog/duckdb_statistics.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/catalog/secret_type.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/catalog/setting.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/catalog/storage.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/client/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/client/aggregate.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/client/catalog_mixin.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/client/cli.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/client/cli_catalog.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/client/cli_schema.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/client/cli_table.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/client/cli_transaction.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/client/cli_utils.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/client/cli_view.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/client/client.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/client/errors.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/_common.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/cpp_constants.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/cpp_protocol_name.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/cpp_protocol_version.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/cpp_request_builders.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/cpp_schemas.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/cpp_secret_protocol_version.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/cpp_secret_request_builders.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/cpp_secret_schemas.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/go_schemas.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/java_schemas.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/protocol_version.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/rust_request_builders.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/rust_schemas.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/ts_client.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/codegen/ts_schemas.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/copy_from_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/copy_to_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/exceptions.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/filter_v2.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/filter_v2_builder.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/function_storage.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/function_storage_azure_sql.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/function_storage_cf_do.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/http/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/http/demo_storage.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/http/landing_page.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/http/worker_page.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/invocation.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/logging_config.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/meta_worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/metadata.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/otel.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/profiling.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/protocol.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/protocol_version.txt +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/py.typed +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/scalar_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/schema_path.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/schema_utils.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/secret_protocol.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/secret_service.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/serve.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/split_token.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/table_buffering_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/table_filter_pushdown.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/table_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/table_in_out_function.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/transactor/__init__.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/transactor/_duckdb_compat.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/transactor/client.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/transactor/protocol.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/transactor/server.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/worker.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/vgi/write_results.py +0 -0
- {vgi_python-0.37.0 → vgi_python-0.37.2}/wrangler.jsonc +0 -0
|
@@ -35,6 +35,11 @@ jobs:
|
|
|
35
35
|
- name: Set up Python ${{ matrix.python-version }}
|
|
36
36
|
run: uv python install ${{ matrix.python-version }}
|
|
37
37
|
|
|
38
|
+
- name: Install Bun for browser discovery regression tests
|
|
39
|
+
uses: oven-sh/setup-bun@v2
|
|
40
|
+
with:
|
|
41
|
+
bun-version: "1.3.14"
|
|
42
|
+
|
|
38
43
|
- name: Install dependencies
|
|
39
44
|
run: uv sync --all-extras
|
|
40
45
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: vgi-python
|
|
3
|
-
Version: 0.37.
|
|
3
|
+
Version: 0.37.2
|
|
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
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Copyright 2025, 2026 Query Farm LLC - https://query.farm
|
|
2
|
+
|
|
3
|
+
"""Exercise the vendored browser client against the Python HTTP server."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
import shutil
|
|
9
|
+
import subprocess
|
|
10
|
+
import threading
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from wsgiref.simple_server import make_server
|
|
13
|
+
|
|
14
|
+
import pyarrow as pa
|
|
15
|
+
import pytest
|
|
16
|
+
|
|
17
|
+
from vgi.scalar_function import ScalarFunction
|
|
18
|
+
from vgi.serve import create_app
|
|
19
|
+
from vgi.worker import Worker
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class _Double(ScalarFunction):
|
|
23
|
+
class Meta:
|
|
24
|
+
name = "double"
|
|
25
|
+
|
|
26
|
+
def compute(self, x: pa.Int64Array) -> pa.Int64Array:
|
|
27
|
+
return pa.compute.multiply(x, 2)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class _LandingWorker(Worker):
|
|
31
|
+
functions = [_Double]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@pytest.mark.skipif(shutil.which("bun") is None, reason="Bun is required to execute the shipped browser client")
|
|
35
|
+
def test_served_browser_client_discovers_catalog(tmp_path: Path) -> None:
|
|
36
|
+
"""A successful asset GET is insufficient: the bundle must speak the current RPC protocol."""
|
|
37
|
+
script = tmp_path / "discover.mjs"
|
|
38
|
+
script.write_text("""
|
|
39
|
+
const url = process.argv[2];
|
|
40
|
+
let rpc;
|
|
41
|
+
try {
|
|
42
|
+
const response = await fetch(url + '/vgi-client.js');
|
|
43
|
+
if (!response.ok) throw new Error('bundle HTTP ' + response.status);
|
|
44
|
+
const path = new URL('./client.mjs', import.meta.url);
|
|
45
|
+
await Bun.write(path, await response.arrayBuffer());
|
|
46
|
+
const browser = await import(path.href);
|
|
47
|
+
rpc = browser.httpConnect(url);
|
|
48
|
+
const client = new browser.VgiClient(rpc);
|
|
49
|
+
const infos = await client.catalogsInfo();
|
|
50
|
+
if (!infos.length) throw new Error('No catalogs discovered');
|
|
51
|
+
const attached = await client.catalogAttach(infos[0].name);
|
|
52
|
+
const schemas = await client.schemas(attached.attach_opaque_data);
|
|
53
|
+
const names = [];
|
|
54
|
+
for (const schema of schemas) {
|
|
55
|
+
const functions = await client.schemaContentsFunctions(attached.attach_opaque_data, schema.path, 'SCALAR_FUNCTION');
|
|
56
|
+
names.push(...functions.map(f => f.name));
|
|
57
|
+
}
|
|
58
|
+
console.log(JSON.stringify(names));
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.error(error.stack || String(error));
|
|
61
|
+
process.exitCode = 1;
|
|
62
|
+
} finally {
|
|
63
|
+
rpc?.close();
|
|
64
|
+
}
|
|
65
|
+
""")
|
|
66
|
+
app = create_app(_LandingWorker, signing_key=b"landing-discovery-test-key")
|
|
67
|
+
with make_server("127.0.0.1", 0, app) as server:
|
|
68
|
+
thread = threading.Thread(target=server.serve_forever, daemon=True)
|
|
69
|
+
thread.start()
|
|
70
|
+
try:
|
|
71
|
+
result = subprocess.run(
|
|
72
|
+
["bun", str(script), f"http://127.0.0.1:{server.server_port}"],
|
|
73
|
+
capture_output=True,
|
|
74
|
+
text=True,
|
|
75
|
+
timeout=30,
|
|
76
|
+
)
|
|
77
|
+
assert result.returncode == 0, result.stderr
|
|
78
|
+
assert "double" in json.loads(result.stdout)
|
|
79
|
+
finally:
|
|
80
|
+
server.shutdown()
|
|
81
|
+
thread.join(timeout=5)
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# Copyright 2026 Query Farm LLC - https://query.farm
|
|
2
|
+
|
|
3
|
+
"""Cacheable fixtures whose results depend on a secret.
|
|
4
|
+
|
|
5
|
+
The C++ result cache keys a secret-dependent result on a fingerprint of the
|
|
6
|
+
secrets its bind resolved (never their values), so a result is reused while the
|
|
7
|
+
secret is unchanged and recomputed the moment it is rotated, re-scoped or
|
|
8
|
+
dropped. Each fixture here reads the ``vgi_example`` secret's ``secret_string``
|
|
9
|
+
and advertises cacheability, one per cache path the fingerprint has to reach:
|
|
10
|
+
|
|
11
|
+
* ``secret_cache_nonce()`` — producer table function; the secret is declared in
|
|
12
|
+
``Meta.required_secrets``. Also exposed as the ``data.secret_cache_nonce``
|
|
13
|
+
table with ``inline_bind=True``, which covers the client's inline-bind path
|
|
14
|
+
(no bind RPC; the secrets are resolved client-side for init).
|
|
15
|
+
* ``secret_cached_scalar(x)`` — scalar, per-value memoized; secret declared via
|
|
16
|
+
a ``Secret()`` annotation.
|
|
17
|
+
* ``secret_cached_lateral(x)`` — blended map, per-value memoized, called under
|
|
18
|
+
``LATERAL``; the secret is requested in ``on_bind`` (the two-phase bind).
|
|
19
|
+
|
|
20
|
+
Every output carries a ``nonce`` minted only when the worker really runs. It is
|
|
21
|
+
random rather than a counter because a pooled worker may run several processes,
|
|
22
|
+
and a per-process counter can repeat across them: equal nonces prove a cache
|
|
23
|
+
HIT, different ones a MISS, on any pool size.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from __future__ import annotations
|
|
27
|
+
|
|
28
|
+
import os
|
|
29
|
+
from dataclasses import dataclass
|
|
30
|
+
from typing import TYPE_CHECKING, Annotated, Any, ClassVar, cast
|
|
31
|
+
|
|
32
|
+
import pyarrow as pa
|
|
33
|
+
from vgi_rpc import ArrowSerializableDataclass
|
|
34
|
+
from vgi_rpc.rpc import OutputCollector
|
|
35
|
+
|
|
36
|
+
from vgi.arguments import Arg, OutputLength, Param, Returns, Secret, SecretLookupEntry
|
|
37
|
+
from vgi.cache_control import CacheControl
|
|
38
|
+
from vgi.invocation import BindResponse
|
|
39
|
+
from vgi.metadata import FunctionExample
|
|
40
|
+
from vgi.scalar_function import ScalarFunction
|
|
41
|
+
from vgi.schema_utils import schema
|
|
42
|
+
from vgi.table_function import (
|
|
43
|
+
BindParams,
|
|
44
|
+
ProcessParams,
|
|
45
|
+
TableFunctionGenerator,
|
|
46
|
+
bind_fixed_schema,
|
|
47
|
+
init_single_worker,
|
|
48
|
+
)
|
|
49
|
+
from vgi.table_in_out_function import RowTransformFunction
|
|
50
|
+
|
|
51
|
+
if TYPE_CHECKING:
|
|
52
|
+
from vgi.protocol import VgiOutputCollector
|
|
53
|
+
|
|
54
|
+
#: The secret type every fixture here reads. Registered by the C++ extension's
|
|
55
|
+
#: test build (``CREATE SECRET ... (TYPE vgi_example, secret_string '...')``).
|
|
56
|
+
SECRET_TYPE = "vgi_example"
|
|
57
|
+
|
|
58
|
+
#: Long enough that TTL never lapses mid-test.
|
|
59
|
+
_TTL_SECONDS = 300
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _nonce() -> int:
|
|
63
|
+
"""A value unique to this invocation, across every process in a worker pool."""
|
|
64
|
+
return int.from_bytes(os.urandom(7), "big")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _secret_string(secret: dict[str, Any]) -> str | None:
|
|
68
|
+
"""The ``secret_string`` field of a resolved secret, or None when there is none."""
|
|
69
|
+
value = secret.get("secret_string")
|
|
70
|
+
if value is None:
|
|
71
|
+
return None
|
|
72
|
+
return str(value.as_py()) if isinstance(value, pa.Scalar) else str(value)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# ---------------------------------------------------------------------------
|
|
76
|
+
# secret_cache_nonce — producer
|
|
77
|
+
# ---------------------------------------------------------------------------
|
|
78
|
+
@dataclass(slots=True, frozen=True)
|
|
79
|
+
class SecretCacheNonceArgs:
|
|
80
|
+
"""Arguments for SecretCacheNonceFunction (none)."""
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@dataclass(kw_only=True)
|
|
84
|
+
class _SecretCacheNonceState(ArrowSerializableDataclass):
|
|
85
|
+
"""The one row to emit, minted on a real invocation."""
|
|
86
|
+
|
|
87
|
+
secret_string: str | None
|
|
88
|
+
nonce: int
|
|
89
|
+
done: bool = False
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@init_single_worker
|
|
93
|
+
@bind_fixed_schema
|
|
94
|
+
class SecretCacheNonceFunction(TableFunctionGenerator[SecretCacheNonceArgs, _SecretCacheNonceState]):
|
|
95
|
+
"""One row: the secret's ``secret_string`` and a per-invocation nonce; cacheable.
|
|
96
|
+
|
|
97
|
+
``initial_state`` runs only on a cache MISS, so the nonce is stable across
|
|
98
|
+
HITs. A rotated secret must MISS and report the new value; restoring the
|
|
99
|
+
original secret must HIT the entry it produced.
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
class Meta:
|
|
103
|
+
"""Metadata for SecretCacheNonceFunction."""
|
|
104
|
+
|
|
105
|
+
name = "secret_cache_nonce"
|
|
106
|
+
description = "One row with a secret's value and a per-invocation nonce; cacheable per secret"
|
|
107
|
+
categories = ["generator", "cache", "secret", "testing"]
|
|
108
|
+
required_secrets = [SecretLookupEntry(secret_type=SECRET_TYPE)]
|
|
109
|
+
examples = [
|
|
110
|
+
FunctionExample(
|
|
111
|
+
sql="SELECT * FROM secret_cache_nonce()",
|
|
112
|
+
description="The nonce is stable while the vgi_example secret is unchanged",
|
|
113
|
+
),
|
|
114
|
+
]
|
|
115
|
+
|
|
116
|
+
FunctionArguments = SecretCacheNonceArgs
|
|
117
|
+
FIXED_SCHEMA: ClassVar[pa.Schema] = schema(secret_string=pa.string(), nonce=pa.int64())
|
|
118
|
+
|
|
119
|
+
@classmethod
|
|
120
|
+
def initial_state(cls, params: ProcessParams[SecretCacheNonceArgs]) -> _SecretCacheNonceState:
|
|
121
|
+
"""Read the secret and mint a nonce for this (real) invocation."""
|
|
122
|
+
secret = next(iter(params.secrets.of_type(SECRET_TYPE)), {})
|
|
123
|
+
return _SecretCacheNonceState(secret_string=_secret_string(secret), nonce=_nonce())
|
|
124
|
+
|
|
125
|
+
@classmethod
|
|
126
|
+
def process(
|
|
127
|
+
cls,
|
|
128
|
+
params: ProcessParams[SecretCacheNonceArgs],
|
|
129
|
+
state: _SecretCacheNonceState,
|
|
130
|
+
out: OutputCollector,
|
|
131
|
+
) -> None:
|
|
132
|
+
"""Emit the single row once, advertising a cache TTL."""
|
|
133
|
+
if state.done:
|
|
134
|
+
out.finish()
|
|
135
|
+
return
|
|
136
|
+
batch = pa.RecordBatch.from_pydict(
|
|
137
|
+
{"secret_string": [state.secret_string], "nonce": [state.nonce]},
|
|
138
|
+
schema=params.output_schema,
|
|
139
|
+
)
|
|
140
|
+
cast("VgiOutputCollector", out).emit(batch, cache_control=CacheControl(ttl=_TTL_SECONDS))
|
|
141
|
+
state.done = True
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
# ---------------------------------------------------------------------------
|
|
145
|
+
# secret_cached_scalar — scalar, per-value
|
|
146
|
+
# ---------------------------------------------------------------------------
|
|
147
|
+
class SecretCachedScalarFunction(ScalarFunction):
|
|
148
|
+
"""``x`` -> ``'<secret_string>|<nonce>'``, memoized per value per secret.
|
|
149
|
+
|
|
150
|
+
With no secret resolved the label is ``'|<nonce>'``.
|
|
151
|
+
|
|
152
|
+
One nonce per ``compute`` call, shared by the batch, so a served value keeps
|
|
153
|
+
the nonce of the call that produced it. ``per_value`` is a test choice, as on
|
|
154
|
+
``cached_double_scalar``: the point is coverage of the tier, not economics.
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
CACHE_CONTROL = CacheControl(ttl=_TTL_SECONDS, per_value=True)
|
|
158
|
+
|
|
159
|
+
class Meta:
|
|
160
|
+
"""Function metadata."""
|
|
161
|
+
|
|
162
|
+
name = "secret_cached_scalar"
|
|
163
|
+
description = "Returns '<secret_string>|<nonce>' per value; memoized per value per secret"
|
|
164
|
+
examples = [
|
|
165
|
+
FunctionExample(
|
|
166
|
+
sql="SELECT secret_cached_scalar(1)",
|
|
167
|
+
description="Stable while the vgi_example secret is unchanged",
|
|
168
|
+
),
|
|
169
|
+
]
|
|
170
|
+
|
|
171
|
+
@classmethod
|
|
172
|
+
def compute(
|
|
173
|
+
cls,
|
|
174
|
+
value: Annotated[pa.Int64Array, Param(doc="Any value; the output ignores it")],
|
|
175
|
+
_length: Annotated[int, OutputLength()],
|
|
176
|
+
vgi_example: Annotated[dict[str, pa.Scalar[Any]] | None, Secret(SECRET_TYPE)] = None,
|
|
177
|
+
) -> Annotated[pa.StringArray, Returns(pa.string())]:
|
|
178
|
+
"""Label every row with the secret's value ('' when none) and this call's nonce.
|
|
179
|
+
|
|
180
|
+
The framework omits a ``Secret()`` argument when no such secret exists,
|
|
181
|
+
hence the default: a dropped secret is a state this fixture must serve.
|
|
182
|
+
"""
|
|
183
|
+
label = f"{_secret_string(vgi_example or {}) or ''}|{_nonce()}"
|
|
184
|
+
return pa.array([label] * _length, type=pa.string())
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
# ---------------------------------------------------------------------------
|
|
188
|
+
# secret_cached_lateral — blended map, per-value, two-phase secret
|
|
189
|
+
# ---------------------------------------------------------------------------
|
|
190
|
+
@dataclass(slots=True, frozen=True, kw_only=True)
|
|
191
|
+
class _SecretCachedLateralArgs:
|
|
192
|
+
"""One positional input column; the output ignores its value."""
|
|
193
|
+
|
|
194
|
+
x: Annotated[int, Arg(0, doc="Input column")]
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
class SecretCachedLateralFunction(RowTransformFunction[_SecretCachedLateralArgs]):
|
|
198
|
+
"""1->1 map emitting the secret's ``secret_string`` and a per-call nonce.
|
|
199
|
+
|
|
200
|
+
Requests the secret from ``on_bind`` — the two-phase bind, so the secret is
|
|
201
|
+
discovered at bind time rather than declared — and advertises ``per_value``
|
|
202
|
+
so a correlated ``LATERAL`` call is memoized per input value per secret.
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
class Meta:
|
|
206
|
+
"""Function metadata."""
|
|
207
|
+
|
|
208
|
+
name = "secret_cached_lateral"
|
|
209
|
+
description = "Blended map emitting a secret's value and a per-call nonce; memoized per secret"
|
|
210
|
+
categories = ["blended", "cache", "secret", "test"]
|
|
211
|
+
|
|
212
|
+
@classmethod
|
|
213
|
+
def on_bind(cls, params: BindParams[_SecretCachedLateralArgs]) -> BindResponse:
|
|
214
|
+
"""Request the secret (two-phase) and declare the output columns."""
|
|
215
|
+
params.secrets.get(SECRET_TYPE)
|
|
216
|
+
return BindResponse(output_schema=schema(secret_string=pa.string(), nonce=pa.int64()))
|
|
217
|
+
|
|
218
|
+
@classmethod
|
|
219
|
+
def process(
|
|
220
|
+
cls,
|
|
221
|
+
params: ProcessParams[_SecretCachedLateralArgs],
|
|
222
|
+
state: None,
|
|
223
|
+
batch: pa.RecordBatch,
|
|
224
|
+
out: OutputCollector,
|
|
225
|
+
) -> None:
|
|
226
|
+
"""Emit one row per input row, all carrying this call's nonce."""
|
|
227
|
+
secret = next(iter(params.secrets.of_type(SECRET_TYPE)), {})
|
|
228
|
+
rows = batch.num_rows
|
|
229
|
+
cast("VgiOutputCollector", out).emit(
|
|
230
|
+
pa.record_batch(
|
|
231
|
+
{
|
|
232
|
+
"secret_string": pa.array([_secret_string(secret)] * rows, type=pa.string()),
|
|
233
|
+
"nonce": pa.array([_nonce()] * rows, type=pa.int64()),
|
|
234
|
+
}
|
|
235
|
+
),
|
|
236
|
+
cache_control=CacheControl(ttl=_TTL_SECONDS, per_value=True),
|
|
237
|
+
)
|
|
@@ -113,6 +113,7 @@ from vgi._test_fixtures.table.partition_columns import (
|
|
|
113
113
|
OverlappingRangePartitionedFunction,
|
|
114
114
|
PartitionedWithExplicitOverrideFunction,
|
|
115
115
|
RegionYearPartitionedFunction,
|
|
116
|
+
TrailingPartitionSalesFunction,
|
|
116
117
|
)
|
|
117
118
|
from vgi._test_fixtures.table.partition_columns_broken import (
|
|
118
119
|
BrokenMissingPartitionValuesFunction,
|
|
@@ -264,6 +265,7 @@ __all__ = [
|
|
|
264
265
|
"RFF_SIMPLE_COLUMNS",
|
|
265
266
|
"RFF_STRUCT_COLUMNS",
|
|
266
267
|
"RegionYearPartitionedFunction",
|
|
268
|
+
"TrailingPartitionSalesFunction",
|
|
267
269
|
"RepeatValueIntFunction",
|
|
268
270
|
"RepeatValueStrFunction",
|
|
269
271
|
"RffMultiScanFunction",
|
|
@@ -23,6 +23,11 @@ Fixtures:
|
|
|
23
23
|
* :class:`RegionYearPartitionedFunction` — multi-column SINGLE_VALUE.
|
|
24
24
|
Each chunk has a single ``(region, year)`` tuple.
|
|
25
25
|
|
|
26
|
+
* :class:`TrailingPartitionSalesFunction` — same contract as the
|
|
27
|
+
country fixture, but the partition column is declared LAST rather
|
|
28
|
+
than first, so the worker-schema and scan-local index spaces do not
|
|
29
|
+
coincide. Also exposed as a catalog table.
|
|
30
|
+
|
|
26
31
|
* :class:`PartitionedWithProjectedOutColumnFunction` — declares
|
|
27
32
|
partition on ``category`` but DOES NOT include ``category`` in the
|
|
28
33
|
emitted batch. Uses the explicit ``partition_values=`` override on
|
|
@@ -49,7 +54,7 @@ from __future__ import annotations
|
|
|
49
54
|
|
|
50
55
|
import struct
|
|
51
56
|
from dataclasses import dataclass
|
|
52
|
-
from typing import Annotated, ClassVar, cast
|
|
57
|
+
from typing import Annotated, Any, ClassVar, cast
|
|
53
58
|
|
|
54
59
|
import pyarrow as pa
|
|
55
60
|
from vgi_rpc import ArrowSerializableDataclass
|
|
@@ -285,6 +290,126 @@ class RegionYearPartitionedFunction(TableFunctionGenerator[_RegionYearArgs, _Reg
|
|
|
285
290
|
state.current_idx = rpp
|
|
286
291
|
|
|
287
292
|
|
|
293
|
+
# =============================================================================
|
|
294
|
+
# SINGLE_VALUE_PARTITIONS with the partition column NOT first
|
|
295
|
+
# =============================================================================
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
@dataclass(slots=True, frozen=True)
|
|
299
|
+
class _TrailingPartitionArgs:
|
|
300
|
+
"""Arguments for ``trailing_partition_sales``."""
|
|
301
|
+
|
|
302
|
+
rows_per_country: Annotated[int, Arg(0, doc="Rows to emit per country partition", ge=1)]
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
@dataclass(kw_only=True)
|
|
306
|
+
class _TrailingPartitionState(ArrowSerializableDataclass):
|
|
307
|
+
"""Per-worker cursor over countries (same shape as the country fixture)."""
|
|
308
|
+
|
|
309
|
+
current_country: str | None = None
|
|
310
|
+
current_country_idx: int = -1
|
|
311
|
+
current_idx: int = 0
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
@bind_fixed_schema
|
|
315
|
+
@_cardinality_from_count
|
|
316
|
+
class TrailingPartitionSalesFunction(TableFunctionGenerator[_TrailingPartitionArgs, _TrailingPartitionState]):
|
|
317
|
+
"""``country`` is single-valued per chunk, but sits LAST in the schema.
|
|
318
|
+
|
|
319
|
+
Identical contract to :class:`CountryPartitionedSalesFunction`; the only
|
|
320
|
+
difference is where the partition column lives. That difference is the
|
|
321
|
+
point: every other partitioned fixture declares its partition column at
|
|
322
|
+
index 0, which makes two distinct index spaces accidentally agree.
|
|
323
|
+
|
|
324
|
+
``CanUsePartitionedAggregate`` asks ``get_partition_info`` about
|
|
325
|
+
WORKER-SCHEMA indices, but the sink later asks ``get_partition_data``
|
|
326
|
+
about SCAN-LOCAL ones (positions in the scan's own ``column_ids``, after
|
|
327
|
+
projection pushdown). ``GROUP BY country`` projects just ``country`` and
|
|
328
|
+
``sales``, so here the sink asks about scan-local 0 while the declared
|
|
329
|
+
index is 3 — and a client that compares them without mapping raises
|
|
330
|
+
"sink requested partition column 0 that is not in the declared partition
|
|
331
|
+
set", which is fatal. With the partition column at index 0 both spaces
|
|
332
|
+
say 0 and the bug is invisible.
|
|
333
|
+
|
|
334
|
+
Also registered as a catalog TABLE (``example.data.trailing_partition_sales``)
|
|
335
|
+
because the two paths install their scan functions separately: a client can
|
|
336
|
+
wire ``get_partition_info`` for direct function calls and miss it for
|
|
337
|
+
catalog tables, in which case the planner silently never picks
|
|
338
|
+
``PARTITIONED_AGGREGATE`` for a table however it is declared.
|
|
339
|
+
"""
|
|
340
|
+
|
|
341
|
+
FIXED_SCHEMA: ClassVar[pa.Schema] = pa.schema(
|
|
342
|
+
cast(
|
|
343
|
+
"list[pa.Field[Any]]",
|
|
344
|
+
[
|
|
345
|
+
pa.field("seq", pa.int64()),
|
|
346
|
+
pa.field("label", pa.string()),
|
|
347
|
+
pa.field("sales", pa.int64()),
|
|
348
|
+
partition_field("country", pa.string()),
|
|
349
|
+
],
|
|
350
|
+
)
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
class Meta:
|
|
354
|
+
name = "trailing_partition_sales"
|
|
355
|
+
projection_pushdown = True
|
|
356
|
+
description = (
|
|
357
|
+
"Per-country sales rows, one Arrow batch per country, with the "
|
|
358
|
+
"SINGLE_VALUE partition column declared LAST in the schema "
|
|
359
|
+
"instead of first."
|
|
360
|
+
)
|
|
361
|
+
categories = ["generator", "partitioning"]
|
|
362
|
+
partition_kind = PartitionKind.SINGLE_VALUE_PARTITIONS
|
|
363
|
+
examples = [
|
|
364
|
+
FunctionExample(
|
|
365
|
+
sql="SELECT country, SUM(sales) FROM trailing_partition_sales(100) GROUP BY country",
|
|
366
|
+
description="Partitioned aggregate over a non-leading partition column",
|
|
367
|
+
),
|
|
368
|
+
]
|
|
369
|
+
|
|
370
|
+
@classmethod
|
|
371
|
+
def on_init(cls, params: InitParams[_TrailingPartitionArgs]) -> GlobalInitResponse:
|
|
372
|
+
items = [struct.pack(_QUEUE_ITEM_FMT, i) for i in range(len(_COUNTRIES))]
|
|
373
|
+
params.storage.queue_push(items)
|
|
374
|
+
return GlobalInitResponse()
|
|
375
|
+
|
|
376
|
+
@classmethod
|
|
377
|
+
def initial_state(cls, params: ProcessParams[_TrailingPartitionArgs]) -> _TrailingPartitionState:
|
|
378
|
+
return _TrailingPartitionState()
|
|
379
|
+
|
|
380
|
+
@classmethod
|
|
381
|
+
def process(
|
|
382
|
+
cls,
|
|
383
|
+
params: ProcessParams[_TrailingPartitionArgs],
|
|
384
|
+
state: _TrailingPartitionState,
|
|
385
|
+
out: OutputCollector,
|
|
386
|
+
) -> None:
|
|
387
|
+
if state.current_country is None or state.current_idx >= params.args.rows_per_country:
|
|
388
|
+
item = params.storage.queue_pop()
|
|
389
|
+
if item is None:
|
|
390
|
+
out.finish()
|
|
391
|
+
return
|
|
392
|
+
(state.current_country_idx,) = struct.unpack(_QUEUE_ITEM_FMT, item)
|
|
393
|
+
state.current_country = _COUNTRIES[state.current_country_idx]
|
|
394
|
+
state.current_idx = 0
|
|
395
|
+
|
|
396
|
+
rpc = params.args.rows_per_country
|
|
397
|
+
# Same deterministic sales values as country_partitioned_sales, so a
|
|
398
|
+
# test can assert the two agree column-for-column despite the layout.
|
|
399
|
+
base = state.current_country_idx * 1_000_000
|
|
400
|
+
batch = pa.RecordBatch.from_pydict(
|
|
401
|
+
{
|
|
402
|
+
"seq": list(range(rpc)),
|
|
403
|
+
"label": [f"{state.current_country}-{i}" for i in range(rpc)],
|
|
404
|
+
"sales": [base + i for i in range(rpc)],
|
|
405
|
+
"country": [state.current_country] * rpc,
|
|
406
|
+
},
|
|
407
|
+
schema=cls.FIXED_SCHEMA,
|
|
408
|
+
)
|
|
409
|
+
out.emit(batch)
|
|
410
|
+
state.current_idx = rpc
|
|
411
|
+
|
|
412
|
+
|
|
288
413
|
# =============================================================================
|
|
289
414
|
# Projected-out partition column — exercises explicit override path
|
|
290
415
|
# =============================================================================
|
|
@@ -130,6 +130,11 @@ from vgi._test_fixtures.scalar import (
|
|
|
130
130
|
UpperCaseFunction,
|
|
131
131
|
WhoAmIFunction,
|
|
132
132
|
)
|
|
133
|
+
from vgi._test_fixtures.secret_cache import (
|
|
134
|
+
SecretCachedLateralFunction,
|
|
135
|
+
SecretCachedScalarFunction,
|
|
136
|
+
SecretCacheNonceFunction,
|
|
137
|
+
)
|
|
133
138
|
from vgi._test_fixtures.table import (
|
|
134
139
|
_VERSIONED_CONSTRAINTS_SCHEMAS,
|
|
135
140
|
_VERSIONED_SCHEMAS,
|
|
@@ -243,6 +248,7 @@ from vgi._test_fixtures.table import (
|
|
|
243
248
|
SplitZeroFunction,
|
|
244
249
|
StructSettingsFunction,
|
|
245
250
|
TenThousandFunction,
|
|
251
|
+
TrailingPartitionSalesFunction,
|
|
246
252
|
TxCachedValueFunction,
|
|
247
253
|
TypedProbeFunction,
|
|
248
254
|
UnionVarargsFunction,
|
|
@@ -450,6 +456,9 @@ _EXAMPLE_CATALOG = Catalog(
|
|
|
450
456
|
BufferInputFunction,
|
|
451
457
|
FilterBySettingFunction,
|
|
452
458
|
SecretInOutFunction,
|
|
459
|
+
# Secret-dependent + per_value: cached per secret fingerprint
|
|
460
|
+
# (see vgi/_test_fixtures/secret_cache.py).
|
|
461
|
+
SecretCachedLateralFunction,
|
|
453
462
|
RepeatInputsFunction,
|
|
454
463
|
SlowCancellableInOutFunction,
|
|
455
464
|
MultiBatchFinishFunction,
|
|
@@ -528,6 +537,7 @@ _EXAMPLE_CATALOG = Catalog(
|
|
|
528
537
|
OverlappingRangePartitionedFunction,
|
|
529
538
|
PartitionedWithExplicitOverrideFunction,
|
|
530
539
|
RegionYearPartitionedFunction,
|
|
540
|
+
TrailingPartitionSalesFunction,
|
|
531
541
|
# Deliberately-broken batch_index fixtures (see
|
|
532
542
|
# vgi/_test_fixtures/table/batch_index_broken.py). Registered
|
|
533
543
|
# so SQL integration tests in batch_index_contract.test can
|
|
@@ -571,6 +581,7 @@ _EXAMPLE_CATALOG = Catalog(
|
|
|
571
581
|
SecretDemoFunction,
|
|
572
582
|
MultiSecretDemoFunction,
|
|
573
583
|
ScopedSecretDemoFunction,
|
|
584
|
+
SecretCacheNonceFunction,
|
|
574
585
|
ExpressionFilterTestFunction,
|
|
575
586
|
SequenceFunction,
|
|
576
587
|
# Split-capable scans (plan() -> named units -> per-split init).
|
|
@@ -650,6 +661,7 @@ _EXAMPLE_CATALOG = Catalog(
|
|
|
650
661
|
RandomBytesFunction,
|
|
651
662
|
RandomIntFunction,
|
|
652
663
|
ReturnSecretValueFunction,
|
|
664
|
+
SecretCachedScalarFunction,
|
|
653
665
|
# Schema-disambiguation probes: each name is also registered in
|
|
654
666
|
# the `data` schema below with a different body. The scalar
|
|
655
667
|
# covers the scalar bind path; the table-in-out and buffered
|
|
@@ -883,6 +895,20 @@ _EXAMPLE_CATALOG = Catalog(
|
|
|
883
895
|
columns=schema(n=pa.int64()),
|
|
884
896
|
comment="123456 integers; stats served by the sequence function, not the table",
|
|
885
897
|
),
|
|
898
|
+
# PartitionColumns as a CATALOG TABLE. A table's scan function is
|
|
899
|
+
# built through a different path than a direct function call, so a
|
|
900
|
+
# client can support partitioned aggregates for one and silently
|
|
901
|
+
# not the other; only a table exercises the catalog path. Paired
|
|
902
|
+
# with a partition column declared last — see the fixture docstring.
|
|
903
|
+
Table(
|
|
904
|
+
name="trailing_partition_sales",
|
|
905
|
+
function=TrailingPartitionSalesFunction,
|
|
906
|
+
arguments=Arguments(positional=(pa.scalar(100),)),
|
|
907
|
+
comment=(
|
|
908
|
+
"Per-country sales, SINGLE_VALUE partition column declared last; "
|
|
909
|
+
"GROUP BY country must plan as PARTITIONED_AGGREGATE"
|
|
910
|
+
),
|
|
911
|
+
),
|
|
886
912
|
# Result-cache fixtures, exposed as function-backed tables so the
|
|
887
913
|
# catalog-attached path (SELECT ... FROM ex.data.<name>) exercises
|
|
888
914
|
# the C++ result cache. See vgi/_test_fixtures/table/cache.py.
|
|
@@ -896,6 +922,15 @@ _EXAMPLE_CATALOG = Catalog(
|
|
|
896
922
|
function=CacheNonceFunction,
|
|
897
923
|
comment="One-row cacheable result whose value changes per real invocation",
|
|
898
924
|
),
|
|
925
|
+
# A secret-dependent cacheable table, pre-bound (inline_bind) so a
|
|
926
|
+
# scan takes the client's no-RPC bind path, where the secrets the
|
|
927
|
+
# cache keys on are resolved client-side. See secret_cache.py.
|
|
928
|
+
Table(
|
|
929
|
+
name="secret_cache_nonce",
|
|
930
|
+
function=SecretCacheNonceFunction,
|
|
931
|
+
inline_bind=True,
|
|
932
|
+
comment="One-row cacheable result keyed on the vgi_example secret",
|
|
933
|
+
),
|
|
899
934
|
Table(
|
|
900
935
|
name="cache_multicol",
|
|
901
936
|
function=CacheMultiColFunction,
|