vgi-python 0.36.1__tar.gz → 0.36.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.36.1 → vgi_python-0.36.2}/PKG-INFO +1 -1
- vgi_python-0.36.2/conformance/filter-v2/cases/positive/boolean-column-predicate.json +32 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/manifest.json +5 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/pyproject.toml +1 -1
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_filter_v2.py +166 -1
- {vgi_python-0.36.1 → vgi_python-0.36.2}/uv.lock +1 -1
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/__init__.py +2 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/filters.py +123 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/worker.py +2 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/filter_v2.py +18 -5
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/table_filter_pushdown.py +79 -1
- {vgi_python-0.36.1 → vgi_python-0.36.2}/.dockerignore +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/.gitattributes +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/.github/dependabot.yml +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/.github/styles/config/vocabularies/VGI/accept.txt +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/.github/workflows/ci.yml +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/.github/workflows/docs.yml +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/.github/workflows/integration.yml +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/.github/workflows/release.yml +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/.github/workflows/tailnet-integration.yml +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/.gitignore +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/.python-version +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/.vale.ini +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/CLAUDE.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/DOCS_ACCEPTANCE_CRITERIA.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/DOCS_REVIEW_RUBRIC.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/DOCS_USABILITY_TEST.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/LICENSE +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/PROTOCOL.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/README.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/RELEASE-RUNBOOK.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/SECURITY.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/ci/README.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/ci/preprocess-require.awk +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/ci/run-integration.sh +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/README.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/cases/negative/and-too-few-children.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/cases/negative/delta-required-upsert.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/cases/negative/nested-runtime-filter.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/cases/negative/remove-with-expression.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/cases/negative/required-runtime-filter.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/cases/negative/snapshot-nonzero-revision.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/cases/negative/unknown-document-property.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/cases/negative/unknown-node.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/cases/positive/advisory-upsert-delta.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/cases/positive/empty-snapshot.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/cases/positive/nested-required-snapshot.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/cases/positive/remove-delta.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/cases/positive/runtime-filter-snapshot.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/filter-v2.schema.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/generate_runtime.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/run_worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/arithmetic-add/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/arithmetic-add/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/arithmetic-add/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/arithmetic-multiply/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/arithmetic-multiply/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/arithmetic-multiply/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/arithmetic-negate/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/arithmetic-negate/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/arithmetic-negate/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/arithmetic-subtract/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/arithmetic-subtract/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/arithmetic-subtract/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/cast-integer-to-double/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/cast-integer-to-double/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/cast-integer-to-double/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-distinct_from/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-distinct_from/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-distinct_from/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-distinct_from/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-eq/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-eq/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-eq/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-eq/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-ge/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-ge/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-ge/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-ge/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-gt/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-gt/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-gt/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-gt/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-le/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-le/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-le/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-le/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-lt/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-lt/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-lt/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-lt/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-ne/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-ne/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-ne/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-ne/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-not_distinct_from/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-not_distinct_from/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-not_distinct_from/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/comparison-not_distinct_from/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/delta-atomic-multi-update/delta-0.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/delta-atomic-multi-update/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/delta-atomic-multi-update/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/delta-atomic-multi-update/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/delta-empty-noop/delta-0.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/delta-empty-noop/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/delta-empty-noop/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/delta-empty-noop/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/delta-upsert-remove-stale/delta-0.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/delta-upsert-remove-stale/delta-1.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/delta-upsert-remove-stale/delta-2.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/delta-upsert-remove-stale/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/delta-upsert-remove-stale/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/delta-upsert-remove-stale/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/empty-snapshot/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/empty-snapshot/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/empty-snapshot/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/empty-snapshot/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-cast-type-not-null/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-cast-type-not-null/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-column-index/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-column-index/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-column-name/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-column-name/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-contextual-cast-without-session/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-contextual-cast-without-session/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-duplicate-predicate-id/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-duplicate-predicate-id/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-external-column-index/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-external-column-index/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-external-column-index/join-keys-0.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-external-column-name/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-external-column-name/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-external-column-name/join-keys-0.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-field-non-struct/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-field-non-struct/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-in-payload-not-list/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-in-payload-not-list/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-in-payload-null-list/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-in-payload-null-list/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-invalid-overload/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-invalid-overload/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-missing-literal/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-missing-literal/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-non-boolean-root/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-non-boolean-root/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-unknown-standard-function/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/error-unknown-standard-function/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/external-in-nonzero-column/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/external-in-nonzero-column/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/external-in-nonzero-column/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/external-in-nonzero-column/join-keys-0.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/external-in-nonzero-column/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/function-contains/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/function-contains/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/function-contains/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/function-ends-with/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/function-ends-with/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/function-ends-with/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/function-list-contains/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/function-list-contains/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/function-list-contains/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/function-starts-with/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/function-starts-with/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/function-starts-with/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/in-empty/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/in-empty/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/in-empty/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/in-empty/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/in-with-null/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/in-with-null/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/in-with-null/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/in-with-null/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/is-not-null/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/is-not-null/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/is-not-null/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/is-not-null/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/is-null/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/is-null/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/is-null/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/is-null/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/kleene-and/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/kleene-and/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/kleene-and/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/kleene-not/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/kleene-not/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/kleene-not/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/kleene-or/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/kleene-or/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/kleene-or/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/nan-comparison/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/nan-comparison/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/nan-comparison/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/negative-zero-membership/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/negative-zero-membership/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/negative-zero-membership/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/nested-null-propagation/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/nested-null-propagation/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/nested-null-propagation/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/not-in-empty/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/not-in-empty/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/not-in-empty/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/not-in-empty/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/not-in-with-null/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/not-in-with-null/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/not-in-with-null/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/not-in-with-null/worker-expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/session-integer-division/expected.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/session-integer-division/filter.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime/session-integer-division/input.arrow +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/runtime-manifest.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/dist-vgi/.gitignore +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/aggregate-functions.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/api/arguments.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/api/auth.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/api/catalogs.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/api/client.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/api/exceptions.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/api/filters.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/api/functions.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/api/http.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/api/index.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/api/metadata.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/api/observability.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/api/storage.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/api/transactor.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/api/worker.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/argument-serialization.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/assets/apple-touch-icon.png +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/assets/favicon-16x16.png +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/assets/favicon-32x32.png +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/assets/favicon.ico +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/assets/kinds/aggregate.svg +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/assets/kinds/buffering.svg +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/assets/kinds/scalar.svg +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/assets/kinds/table-in-out.svg +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/assets/kinds/table.svg +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/assets/logo.png +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/assets/social-card.png +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/authentication.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/catalog-interface.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/cli.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/column-statistics.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/concepts/index.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/contributing-docs.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/filter-pushdown.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/generator-api.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/global-functions.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/how-to/catalogs.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/how-to/function-patterns.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/how-to/http-auth.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/how-to/index.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/how-to/iroh.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/how-to/pushdown-and-statistics.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/how-to/state-storage.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/how-to/tailnet.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/index.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/lifecycle.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/metadata.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/overrides/main.html +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/protocol/index.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/protocol/vgi-catalog-query-pushdown-design.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/protocol/vgi-duckdb-filter-adapter.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/protocol/vgi-filter-encoding-v2-spec.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/protocol/vgi-protocol-proposed-changes.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/protocol/vgi-runtime-filter-artifacts.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/robots.txt +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/shared-storage.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/stylesheets/extra.css +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/tutorial/index.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/tutorial/scalar.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/tutorial/table.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/docs/vgi-logo.png +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/examples/batch_index_worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/examples/cache_worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/examples/calc_scalar_worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/examples/calc_worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/examples/copy_format_worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/examples/filter_worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/examples/greeting_scalar_worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/examples/row_count_worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/examples/series_streaming_worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/examples/sum_worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/identity.png +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/mkdocs.yml +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/packages/vgi-fixtures/LICENSE +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/packages/vgi-fixtures/README.md +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/packages/vgi-fixtures/docker/Dockerfile +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/packages/vgi-fixtures/docker/docker-entrypoint.sh +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/packages/vgi-fixtures/pyproject.toml +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/scripts/measure_startup.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/scripts/regen_generated.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/scripts/run_all_tests.sh +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/test-data/generate.sh +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/_http_fixtures.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/catalog/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/catalog/test_attach_option.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/catalog/test_catalog_interface.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/catalog/test_client_catalog.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/catalog/test_column_statistics.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/catalog/test_declarative.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/catalog/test_example_worker_catalog.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/catalog/test_integration.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/catalog/test_required_filters.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/catalog/test_scan_branches.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/catalog/test_serialization.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/catalog/test_setting.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/catalog/test_storage.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/catalog/test_time_travel.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/catalog/test_writable_table.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/test_aggregate_client.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/test_batch_metadata_callback.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/test_bind_and_join_keys.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/test_broken_pipe.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/test_cli.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/test_cli_catalog_functions.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/test_copy_client.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/test_http_response_budget.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/test_iroh_client.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/test_scan_branches_client.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/test_split_client.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/test_stop_force.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/test_table_column_statistics.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/test_time_travel_client.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/client/test_worker_debug.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/_stub.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/conftest.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_accumulate.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_aggregate.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_attach.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_bearer_auth.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_const_param_enforcement.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_container.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_copy_from.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_copy_to.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_directory_parity.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_function_inventory.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_github.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_http_client.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_http_external_location.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_http_upload_url.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_macro.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_overload.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_protocol_inventory.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_protocol_version.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_resumable_scan.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_scalar.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_scalar_attach_opaque_data.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_secret.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_settings.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_splits.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_table.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_table_in_out.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_view.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conformance/test_writable.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/conftest.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/data/split_tokens/anchor_len_overrun.bin +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/data/split_tokens/bad_fingerprint.bin +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/data/split_tokens/bad_flags_unsealed_but_key_present.bin +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/data/split_tokens/bad_version.bin +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/data/split_tokens/generate.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/data/split_tokens/manifest.json +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/data/split_tokens/reserved_flag_bit.bin +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/data/split_tokens/stale_anchor.bin +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/data/split_tokens/truncated.bin +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/data/split_tokens/valid_sealed.bin +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/data/split_tokens/valid_unsealed.bin +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/scalar/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/scalar/test_bernoulli_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/scalar/test_binary_packet_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/scalar/test_client.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/scalar/test_conditional_message_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/scalar/test_hash_seed_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/scalar/test_multiply_by_setting_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/scalar/test_multiply_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/scalar/test_random_bytes_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/scalar/test_return_secret_value_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table/generator/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table/generator/test_constant_columns_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table/generator/test_double_sequence_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table/generator/test_exception_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table/generator/test_filter_echo_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table/generator/test_logging_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table/generator/test_nested_sequence_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table/generator/test_partitioned_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table/generator/test_projected_data_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table/generator/test_sequence_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table/generator/test_settings_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table/generator/test_struct_settings_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table/generator/test_ten_thousand_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table/test_wide_columns.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table_in_out/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table_in_out/generator/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table_in_out/generator/test_buffer_input_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table_in_out/generator/test_echo_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table_in_out/generator/test_exception_functions.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table_in_out/generator/test_filter_by_setting_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table_in_out/generator/test_repeat_inputs_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table_in_out/generator/test_substream_partial_sum_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table_in_out/generator/test_sum_all_columns_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table_in_out/test_blended_exchange.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table_in_out/test_blended_metadata.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/table_in_out/test_client.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/tailnet/Dockerfile +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/tailnet/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/tailnet/compose.yaml +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/tailnet/probe.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/tailnet/run.sh +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/tailnet/test_worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/tailnet/worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_access_log_audit.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_aggregate_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_argument_spec.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_auth.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_bind_exceptions.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_bind_request_at_clause.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_bound_storage_conformance.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_cache_control.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_call_state_attach.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_catalog_auth_binding.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_client_oauth.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_codegen_request_inventory.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_copy_from_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_copy_to_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_docstrings.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_documentation_examples.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_dynamic_filter_http_turns.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_example_function_arg_types.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_examples_workers.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_exception_handling.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_exceptions.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_filter_pushdown.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_filter_pushdown_extension.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_filter_v2_builder.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_filter_v2_runtime_corpus.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_filter_v2_spec_schema.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_fixture_catalog_parity.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_function_shape_mismatch.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_function_storage.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_function_storage_azure_sql.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_function_storage_cf_do.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_function_storage_cf_do_integration.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_function_storage_conformance.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_generated_cpp_constants.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_generated_cpp_protocol_name.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_generated_cpp_protocol_version.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_generated_cpp_request_builders.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_generated_cpp_schemas.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_generated_cpp_secret.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_generated_go_schemas.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_generated_java_schemas.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_generated_protocol_version.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_generated_rust_request_builders.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_generated_rust_schemas.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_generated_schemas_cross_lang.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_generated_ts_client.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_generated_ts_schemas.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_http_demo_storage.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_http_s3_offload_input.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_http_s3_offload_output.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_import_side_effects.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_launch_transport.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_metadata.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_mypy_consolidated.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_nest_tensor.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_otel.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_projection_enforcement.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_projection_repro.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_protocol_classes.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_resolved_secrets.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_schema_paths_v2.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_schema_scoped_functions.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_schema_utils.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_serve.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_setting_secret_annotations.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_signing_key.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_split_token.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_subprocess_transport.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_table_buffering_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_table_function_dynamic_to_string.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_tcp_transport.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_type_bounds.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_union_argument.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_wire_record_schema_parity.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_worker_cli.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_worker_page.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/test_write_results.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/transactor/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/tests/transactor/test_transactor.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_duckdb.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_storage_profile.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/accumulate/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/accumulate/worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/aggregate/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/aggregate/_common.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/aggregate/basic.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/aggregate/dynamic.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/aggregate/generic.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/aggregate/listagg.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/aggregate/percentile.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/aggregate/same_name.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/aggregate/secret_typed.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/aggregate/streaming.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/aggregate/varargs.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/aggregate/window.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/attach_options.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/bad_enum.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/bad_protocol.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/cancellable.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/catalog.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/companion.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/copy_from.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/copy_to.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/global_functions.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/http_server.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/narrow_bind/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/narrow_bind/worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/nest_tensor.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/orchard_catalog.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/projection_repro/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/projection_repro/worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/scalar/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/scalar/_common.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/scalar/arithmetic.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/scalar/bench_ladder.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/scalar/binary.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/scalar/formatting.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/scalar/geo.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/scalar/null_handling.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/scalar/random_demo.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/scalar/same_name.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/scalar/settings_secrets.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/scalar/type_info.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/schema_reconcile/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/schema_reconcile/worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/simple_writable.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/_common.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/batch_index.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/batch_index_broken.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/cache.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/catalog_scans.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/late_materialization.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/make_series.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/misc.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/order_modes.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/pairs.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/partition_columns.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/partition_columns_broken.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/profiling_example.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/required_filters.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/same_name_cached.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/same_name_schemas.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/sequence.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/settings.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/splits.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/transaction_storage.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/tt_pushdown.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/typed_probe.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/versioned.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table/wide.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table_in_out.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/table_in_out_same_name.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/twin_catalogs.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/versioned.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/versioned_tables.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/writable/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/writable/generic.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/writable/table.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/_test_fixtures/writable/worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/aggregate_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/argument_spec.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/arguments.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/attach_header.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/auth.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/cache_control.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/catalog/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/catalog/_descriptor_spec.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/catalog/attach_option.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/catalog/catalog_interface.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/catalog/descriptors.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/catalog/duckdb_statistics.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/catalog/secret_type.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/catalog/setting.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/catalog/storage.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/client/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/client/aggregate.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/client/catalog_mixin.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/client/cli.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/client/cli_catalog.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/client/cli_schema.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/client/cli_table.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/client/cli_transaction.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/client/cli_utils.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/client/cli_view.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/client/client.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/client/errors.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/_common.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/cpp_constants.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/cpp_protocol_name.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/cpp_protocol_version.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/cpp_request_builders.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/cpp_schemas.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/cpp_secret_protocol_version.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/cpp_secret_request_builders.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/cpp_secret_schemas.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/go_schemas.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/java_schemas.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/protocol_version.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/rust_request_builders.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/rust_schemas.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/ts_client.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/codegen/ts_schemas.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/copy_from_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/copy_to_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/exceptions.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/filter_v2_builder.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/function_storage.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/function_storage_azure_sql.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/function_storage_cf_do.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/http/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/http/demo_storage.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/http/landing.html +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/http/landing_page.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/http/vgi-client.js +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/http/worker_page.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/invocation.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/logging_config.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/meta_worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/metadata.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/otel.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/profiling.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/protocol.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/protocol_version.txt +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/py.typed +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/scalar_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/schema_path.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/schema_utils.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/secret_protocol.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/secret_service.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/serve.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/split_token.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/table_buffering_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/table_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/table_in_out_function.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/transactor/__init__.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/transactor/_duckdb_compat.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/transactor/client.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/transactor/protocol.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/transactor/server.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/worker.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/vgi/write_results.py +0 -0
- {vgi_python-0.36.1 → vgi_python-0.36.2}/wrangler.jsonc +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: vgi-python
|
|
3
|
-
Version: 0.36.
|
|
3
|
+
Version: 0.36.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,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"encoding": "vgi.filters.v2",
|
|
3
|
+
"semantics": "vgi.duckdb.standard.v1",
|
|
4
|
+
"kind": "snapshot",
|
|
5
|
+
"predicates": [
|
|
6
|
+
{
|
|
7
|
+
"id": "query:bare-boolean-column",
|
|
8
|
+
"revision": 0,
|
|
9
|
+
"mode": "required",
|
|
10
|
+
"source": "query",
|
|
11
|
+
"expression": {
|
|
12
|
+
"node": "column_ref",
|
|
13
|
+
"column_index": 0,
|
|
14
|
+
"column_name": "flag"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": "query:negated-boolean-column",
|
|
19
|
+
"revision": 0,
|
|
20
|
+
"mode": "required",
|
|
21
|
+
"source": "query",
|
|
22
|
+
"expression": {
|
|
23
|
+
"node": "not",
|
|
24
|
+
"expression": {
|
|
25
|
+
"node": "column_ref",
|
|
26
|
+
"column_index": 1,
|
|
27
|
+
"column_name": "other_flag"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
@@ -30,6 +30,11 @@
|
|
|
30
30
|
"document": "cases/positive/runtime-filter-snapshot.json",
|
|
31
31
|
"expected": "valid"
|
|
32
32
|
},
|
|
33
|
+
{
|
|
34
|
+
"id": "structural.boolean-column-predicate",
|
|
35
|
+
"document": "cases/positive/boolean-column-predicate.json",
|
|
36
|
+
"expected": "valid"
|
|
37
|
+
},
|
|
33
38
|
{
|
|
34
39
|
"id": "structural.and-too-few-children",
|
|
35
40
|
"document": "cases/negative/and-too-few-children.json",
|
|
@@ -6,7 +6,7 @@ from __future__ import annotations
|
|
|
6
6
|
|
|
7
7
|
import json
|
|
8
8
|
from collections.abc import Mapping
|
|
9
|
-
from typing import cast
|
|
9
|
+
from typing import Any, cast
|
|
10
10
|
|
|
11
11
|
import pyarrow as pa
|
|
12
12
|
import pytest
|
|
@@ -531,3 +531,168 @@ def test_unknown_arrow_extension_metadata_is_rejected() -> None:
|
|
|
531
531
|
_batch(_document([_predicate(_comparison())]), (extension_field, b"opaque")),
|
|
532
532
|
output_schema=pa.schema([("n", pa.int64())]),
|
|
533
533
|
)
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
# ---------------------------------------------------------------------------
|
|
537
|
+
# A boolean column is a predicate on its own
|
|
538
|
+
#
|
|
539
|
+
# `WHERE flag` / `WHERE NOT flag` is idiomatic SQL, and DuckDB pushes it down as
|
|
540
|
+
# a bare `column_ref` rather than rewriting it to `flag = true`. The schema
|
|
541
|
+
# admits that -- `coreExpression` lists `columnRef` first -- but the decoder's
|
|
542
|
+
# boolean gate used to enumerate node *kinds* instead of asking for the resolved
|
|
543
|
+
# *type*, so it refused every one of them: "predicate root must resolve to
|
|
544
|
+
# BOOLEAN", on a node whose type it had already resolved to BOOLEAN and stored.
|
|
545
|
+
# ---------------------------------------------------------------------------
|
|
546
|
+
|
|
547
|
+
_BOOL_FIELDS: list[pa.Field[Any]] = [pa.field("flag", pa.bool_()), pa.field("n", pa.int64())]
|
|
548
|
+
_BOOL_SCHEMA = pa.schema(_BOOL_FIELDS)
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
def _flag(index: int = 0) -> dict[str, object]:
|
|
552
|
+
return {"node": "column_ref", "column_index": index, "column_name": "flag"}
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
def test_bare_boolean_column_is_a_valid_predicate_root() -> None:
|
|
556
|
+
"""`WHERE flag` -- the column itself is the predicate."""
|
|
557
|
+
filters = deserialize_filters(
|
|
558
|
+
_batch(_document([_predicate(_flag())])),
|
|
559
|
+
output_schema=_BOOL_SCHEMA,
|
|
560
|
+
)
|
|
561
|
+
batch = pa.RecordBatch.from_pydict(
|
|
562
|
+
{"flag": [True, False, None, True], "n": [1, 2, 3, 4]},
|
|
563
|
+
schema=_BOOL_SCHEMA,
|
|
564
|
+
)
|
|
565
|
+
# evaluate() is the raw three-valued predicate: NULL stays NULL.
|
|
566
|
+
assert filters.evaluate(batch).to_pylist() == [True, False, None, True]
|
|
567
|
+
# apply() is what selects rows, and there a NULL predicate is not satisfied
|
|
568
|
+
# -- the same rows `flag = true` would keep, which is what makes the SQL
|
|
569
|
+
# rewrite below a projection rather than a change of meaning.
|
|
570
|
+
assert filters.apply(batch).to_pydict()["n"] == [1, 4]
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
def test_negated_boolean_column_is_a_valid_predicate_root() -> None:
|
|
574
|
+
"""`WHERE NOT flag` -- `not` over a bare column, which the gate also refused."""
|
|
575
|
+
filters = deserialize_filters(
|
|
576
|
+
_batch(_document([_predicate({"node": "not", "expression": _flag()})])),
|
|
577
|
+
output_schema=_BOOL_SCHEMA,
|
|
578
|
+
)
|
|
579
|
+
batch = pa.RecordBatch.from_pydict(
|
|
580
|
+
{"flag": [True, False, None, True], "n": [1, 2, 3, 4]},
|
|
581
|
+
schema=_BOOL_SCHEMA,
|
|
582
|
+
)
|
|
583
|
+
assert filters.evaluate(batch).to_pylist() == [False, True, None, False]
|
|
584
|
+
# NOT NULL is NULL, so row 3 is not kept -- exactly `flag = false`.
|
|
585
|
+
assert filters.apply(batch).to_pydict()["n"] == [2]
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
def test_boolean_column_predicates_render_as_sql() -> None:
|
|
589
|
+
"""They must reach SQL, not just the evaluator.
|
|
590
|
+
|
|
591
|
+
Left as a generic v2 expression a bare column renders no SQL at all, so a
|
|
592
|
+
SQL-backed worker loses pushdown on the commonest boolean predicate there
|
|
593
|
+
is -- and DuckDB does not re-apply what it pushed down, so that is a wrong
|
|
594
|
+
answer, not a slow one.
|
|
595
|
+
"""
|
|
596
|
+
positive = deserialize_filters(_batch(_document([_predicate(_flag())])), output_schema=_BOOL_SCHEMA)
|
|
597
|
+
where, params = positive.to_sql()
|
|
598
|
+
assert where == '"flag" = ?'
|
|
599
|
+
assert params == [True]
|
|
600
|
+
|
|
601
|
+
negative = deserialize_filters(
|
|
602
|
+
_batch(_document([_predicate({"node": "not", "expression": _flag()})])),
|
|
603
|
+
output_schema=_BOOL_SCHEMA,
|
|
604
|
+
)
|
|
605
|
+
where, params = negative.to_sql()
|
|
606
|
+
assert where == '"flag" = ?'
|
|
607
|
+
assert params == [False]
|
|
608
|
+
|
|
609
|
+
|
|
610
|
+
def test_boolean_column_inside_a_conjunction_still_pushes_down() -> None:
|
|
611
|
+
"""The shape that actually showed up: `WHERE other = x AND NOT flag`.
|
|
612
|
+
|
|
613
|
+
One unrenderable child used to cost the whole conjunction its pushdown.
|
|
614
|
+
"""
|
|
615
|
+
document = _document(
|
|
616
|
+
[
|
|
617
|
+
_predicate(
|
|
618
|
+
{
|
|
619
|
+
"node": "and",
|
|
620
|
+
"children": [
|
|
621
|
+
{
|
|
622
|
+
"node": "comparison",
|
|
623
|
+
"op": "gt",
|
|
624
|
+
"left": _column(name="n", index=1),
|
|
625
|
+
"right": {"node": "literal", "value_ref": 0},
|
|
626
|
+
},
|
|
627
|
+
{"node": "not", "expression": _flag()},
|
|
628
|
+
],
|
|
629
|
+
}
|
|
630
|
+
)
|
|
631
|
+
]
|
|
632
|
+
)
|
|
633
|
+
filters = deserialize_filters(
|
|
634
|
+
_batch(document, (pa.field("value_0", pa.int64()), 2)),
|
|
635
|
+
output_schema=_BOOL_SCHEMA,
|
|
636
|
+
)
|
|
637
|
+
where, params = filters.to_sql()
|
|
638
|
+
assert where == '("n" > ? AND "flag" = ?)'
|
|
639
|
+
assert params == [2, False]
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
def test_an_unresolved_column_is_not_assumed_boolean() -> None:
|
|
643
|
+
"""Without a bind schema the column's type is unknown -- refuse, don't guess."""
|
|
644
|
+
with pytest.raises(FilterDeserializationError, match="predicate root"):
|
|
645
|
+
deserialize_filters(_batch(_document([_predicate(_flag())])))
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
def test_a_non_boolean_column_is_still_refused() -> None:
|
|
649
|
+
"""`WHERE n` where n is BIGINT is not a predicate."""
|
|
650
|
+
with pytest.raises(FilterDeserializationError, match="predicate root"):
|
|
651
|
+
deserialize_filters(
|
|
652
|
+
_batch(_document([_predicate(_column(name="n", index=1))])),
|
|
653
|
+
output_schema=_BOOL_SCHEMA,
|
|
654
|
+
)
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
def test_an_unrenderable_filter_raises_rather_than_vanishing() -> None:
|
|
658
|
+
"""`to_sql()` must never quietly drop a predicate it cannot render.
|
|
659
|
+
|
|
660
|
+
DuckDB does not re-apply a filter it pushed into a table function, so the
|
|
661
|
+
worker's WHERE clause is the only thing standing between the caller and
|
|
662
|
+
rows the predicate excludes. A skipped filter is therefore a wrong answer,
|
|
663
|
+
not a slow one -- which is why this raises instead of degrading.
|
|
664
|
+
"""
|
|
665
|
+
from vgi.table_filter_pushdown import FilterSQLUnsupportedError
|
|
666
|
+
|
|
667
|
+
# `n + 1 > 2` -- arithmetic has no legacy leaf shape and no SQL rendering.
|
|
668
|
+
document = _document(
|
|
669
|
+
[
|
|
670
|
+
_predicate(
|
|
671
|
+
{
|
|
672
|
+
"node": "comparison",
|
|
673
|
+
"op": "gt",
|
|
674
|
+
"left": {
|
|
675
|
+
"node": "arithmetic",
|
|
676
|
+
"op": "add",
|
|
677
|
+
"left": _column(name="n", index=1),
|
|
678
|
+
"right": {"node": "literal", "value_ref": 0},
|
|
679
|
+
},
|
|
680
|
+
"right": {"node": "literal", "value_ref": 1},
|
|
681
|
+
}
|
|
682
|
+
)
|
|
683
|
+
]
|
|
684
|
+
)
|
|
685
|
+
filters = deserialize_filters(
|
|
686
|
+
_batch(
|
|
687
|
+
document,
|
|
688
|
+
(pa.field("value_0", pa.int64()), 1),
|
|
689
|
+
(pa.field("value_1", pa.int64()), 2),
|
|
690
|
+
),
|
|
691
|
+
output_schema=_BOOL_SCHEMA,
|
|
692
|
+
)
|
|
693
|
+
# It evaluates correctly -- there is simply no SQL for it.
|
|
694
|
+
batch = pa.RecordBatch.from_pydict({"flag": [True, True, True], "n": [0, 2, 5]}, schema=_BOOL_SCHEMA)
|
|
695
|
+
assert filters.apply(batch).to_pydict()["n"] == [2, 5]
|
|
696
|
+
|
|
697
|
+
with pytest.raises(FilterSQLUnsupportedError, match="no SQL rendering"):
|
|
698
|
+
filters.to_sql()
|
|
@@ -65,6 +65,7 @@ from vgi._test_fixtures.table.catalog_scans import (
|
|
|
65
65
|
ProjectsScanFunction,
|
|
66
66
|
)
|
|
67
67
|
from vgi._test_fixtures.table.filters import (
|
|
68
|
+
BoolFilterEchoFunction,
|
|
68
69
|
DictFilterEchoFunction,
|
|
69
70
|
DynamicFilterEchoFunction,
|
|
70
71
|
ExpressionFilterTestFunction,
|
|
@@ -216,6 +217,7 @@ __all__ = [
|
|
|
216
217
|
"ConstantColumnsFunction",
|
|
217
218
|
"CountryPartitionedSalesFunction",
|
|
218
219
|
"DepartmentsScanFunction",
|
|
220
|
+
"BoolFilterEchoFunction",
|
|
219
221
|
"DictFilterEchoFunction",
|
|
220
222
|
"DisjointRangePartitionedFunction",
|
|
221
223
|
"DoubleSequenceFunction",
|
|
@@ -191,6 +191,129 @@ class FilterEchoFunction(TableFunctionGenerator[FilterEchoFunctionArgs, FilterEc
|
|
|
191
191
|
state.remaining -= size
|
|
192
192
|
|
|
193
193
|
|
|
194
|
+
# ============================================================================
|
|
195
|
+
# BoolFilterEchoFunction — a table function with a BOOLEAN column, so the
|
|
196
|
+
# bare-column predicate shapes (`WHERE flag`, `WHERE NOT flag`) can be driven
|
|
197
|
+
# end to end.
|
|
198
|
+
#
|
|
199
|
+
# filter_echo cannot cover these: its schema has no boolean column, so the
|
|
200
|
+
# predicate cannot even be written. The table-in-out `echo` path cannot either
|
|
201
|
+
# — DuckDB does not hand it a bare boolean column as a pushed predicate, so a
|
|
202
|
+
# test written there passes whether or not the worker can decode one. It takes
|
|
203
|
+
# a TABLE FUNCTION with a boolean column to see the shape at all, which is why
|
|
204
|
+
# a decoder that refused every one of them ("predicate root must resolve to
|
|
205
|
+
# BOOLEAN", vgi-python < 0.36.2) went unnoticed by a filter-pushdown suite of
|
|
206
|
+
# 348 files including one dedicated to booleans.
|
|
207
|
+
#
|
|
208
|
+
# `pushed_filters` echoes the SQL rendering, so this covers both halves: the
|
|
209
|
+
# decode (the rows are auto-applied and must be right) and `to_sql()` (a shape
|
|
210
|
+
# that parses but renders nothing would show up here as "(none)").
|
|
211
|
+
# ============================================================================
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
@dataclass(slots=True, frozen=True)
|
|
215
|
+
class _BoolFilterEchoArgs:
|
|
216
|
+
"""Arguments for BoolFilterEchoFunction."""
|
|
217
|
+
|
|
218
|
+
count: Annotated[int, Arg(0, doc="Number of rows to generate", ge=0)]
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
@dataclass(kw_only=True)
|
|
222
|
+
class _BoolFilterEchoState(ArrowSerializableDataclass):
|
|
223
|
+
"""Remaining rows plus the echoed SQL rendering of the pushed filters."""
|
|
224
|
+
|
|
225
|
+
remaining: int
|
|
226
|
+
current_index: int = 0
|
|
227
|
+
filter_str: str = "(none)"
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
@init_single_worker
|
|
231
|
+
@bind_fixed_schema
|
|
232
|
+
@_cardinality_from_count
|
|
233
|
+
class BoolFilterEchoFunction(TableFunctionGenerator[_BoolFilterEchoArgs, _BoolFilterEchoState]):
|
|
234
|
+
"""Rows with a nullable BOOLEAN column, echoing the pushed-down filters.
|
|
235
|
+
|
|
236
|
+
SCHEMA
|
|
237
|
+
------
|
|
238
|
+
Output: {"n": int64, "flag": bool, "pushed_filters": string}
|
|
239
|
+
|
|
240
|
+
``flag`` cycles TRUE, FALSE, NULL so every predicate is exercised against
|
|
241
|
+
all three truth values -- the NULL row is what distinguishes ``WHERE flag``
|
|
242
|
+
from ``WHERE flag IS NOT FALSE``, and ``WHERE NOT flag`` from
|
|
243
|
+
``WHERE flag IS NOT TRUE``.
|
|
244
|
+
|
|
245
|
+
Attributes:
|
|
246
|
+
FIXED_SCHEMA: The fixed Arrow output schema this function always produces.
|
|
247
|
+
|
|
248
|
+
"""
|
|
249
|
+
|
|
250
|
+
class Meta:
|
|
251
|
+
"""Metadata for BoolFilterEchoFunction."""
|
|
252
|
+
|
|
253
|
+
name = "bool_filter_echo"
|
|
254
|
+
description = "Rows with a nullable BOOLEAN column, echoing pushed-down filters"
|
|
255
|
+
categories = ["generator", "diagnostic"]
|
|
256
|
+
filter_pushdown = True
|
|
257
|
+
auto_apply_filters = True
|
|
258
|
+
projection_pushdown = True
|
|
259
|
+
examples = [
|
|
260
|
+
FunctionExample(
|
|
261
|
+
sql="SELECT * FROM bool_filter_echo(6) WHERE flag",
|
|
262
|
+
description="A boolean column is a predicate on its own",
|
|
263
|
+
),
|
|
264
|
+
]
|
|
265
|
+
|
|
266
|
+
FIXED_SCHEMA: ClassVar[pa.Schema] = schema({"n": pa.int64(), "flag": pa.bool_(), "pushed_filters": pa.utf8()})
|
|
267
|
+
|
|
268
|
+
@classmethod
|
|
269
|
+
def initial_state(cls, params: ProcessParams[_BoolFilterEchoArgs]) -> _BoolFilterEchoState:
|
|
270
|
+
"""Create initial state, caching the SQL rendering of the pushed filters."""
|
|
271
|
+
assert params.init_call is not None
|
|
272
|
+
pf = params.init_call.pushdown_filters
|
|
273
|
+
filters = (
|
|
274
|
+
cls.pushdown_filters(
|
|
275
|
+
pf,
|
|
276
|
+
join_keys=params.init_call.join_keys,
|
|
277
|
+
output_schema=params.init_call.output_schema,
|
|
278
|
+
)
|
|
279
|
+
if pf is not None
|
|
280
|
+
else None
|
|
281
|
+
)
|
|
282
|
+
return _BoolFilterEchoState(
|
|
283
|
+
remaining=params.args.count,
|
|
284
|
+
filter_str=_format_pushed_filters(filters),
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
@classmethod
|
|
288
|
+
def process(
|
|
289
|
+
cls,
|
|
290
|
+
params: ProcessParams[_BoolFilterEchoArgs],
|
|
291
|
+
state: _BoolFilterEchoState,
|
|
292
|
+
out: OutputCollector,
|
|
293
|
+
) -> None:
|
|
294
|
+
"""Emit rows whose ``flag`` cycles TRUE, FALSE, NULL."""
|
|
295
|
+
if state.remaining <= 0:
|
|
296
|
+
out.finish()
|
|
297
|
+
return
|
|
298
|
+
|
|
299
|
+
n_values = list(range(state.current_index, state.current_index + state.remaining))
|
|
300
|
+
flags: list[bool | None] = [(True, False, None)[i % 3] for i in n_values]
|
|
301
|
+
|
|
302
|
+
out.emit(
|
|
303
|
+
pa.RecordBatch.from_pydict(
|
|
304
|
+
{
|
|
305
|
+
"n": n_values,
|
|
306
|
+
"flag": flags,
|
|
307
|
+
"pushed_filters": [state.filter_str] * len(n_values),
|
|
308
|
+
},
|
|
309
|
+
schema=params.output_schema,
|
|
310
|
+
)
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
state.current_index += state.remaining
|
|
314
|
+
state.remaining = 0
|
|
315
|
+
|
|
316
|
+
|
|
194
317
|
# ============================================================================
|
|
195
318
|
# ValuePruneFunction — exercises PushdownFilters.get_column_values('n'), the
|
|
196
319
|
# partition-pruning idiom (resolve the discrete value set up front, fetch only
|
|
@@ -140,6 +140,7 @@ from vgi._test_fixtures.table import (
|
|
|
140
140
|
RFF_SIMPLE_COLUMNS,
|
|
141
141
|
RFF_STRUCT_COLUMNS,
|
|
142
142
|
BatchIndexOverflowFunction,
|
|
143
|
+
BoolFilterEchoFunction,
|
|
143
144
|
BrokenMissingPartitionValuesFunction,
|
|
144
145
|
BrokenPartitionColumnAbsentFromBatchFunction,
|
|
145
146
|
BrokenPartitionMinNeqMaxFunction,
|
|
@@ -486,6 +487,7 @@ _EXAMPLE_CATALOG = Catalog(
|
|
|
486
487
|
# TableFunctionGenerator - generate output without input
|
|
487
488
|
ConstantColumnsFunction,
|
|
488
489
|
SlowCancellableFunction,
|
|
490
|
+
BoolFilterEchoFunction,
|
|
489
491
|
FilterEchoFunction,
|
|
490
492
|
FilterEchoPartitionedFunction,
|
|
491
493
|
FilterEchoTableScanFunction,
|
|
@@ -740,11 +740,24 @@ class _Parser:
|
|
|
740
740
|
|
|
741
741
|
@staticmethod
|
|
742
742
|
def _is_boolean(expression: FilterExpression) -> bool:
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
743
|
+
"""Whether *expression* resolves to BOOLEAN.
|
|
744
|
+
|
|
745
|
+
Ask the type, never the node kind. The two agree for every node whose
|
|
746
|
+
type is structurally fixed -- a comparison is BOOLEAN whatever its
|
|
747
|
+
operands -- and that is exactly why enumerating kinds looked sufficient.
|
|
748
|
+
It is not: ``column_ref``, ``field_ref``, ``cast`` and ``arithmetic``
|
|
749
|
+
are BOOLEAN or not depending on a type resolved from elsewhere (the
|
|
750
|
+
bind output schema, or a parent expression), and the schema admits all
|
|
751
|
+
four as a predicate root -- ``coreExpression`` lists ``columnRef``
|
|
752
|
+
first. Enumerating kinds rejected the lot, so the idiomatic
|
|
753
|
+
``WHERE flag`` / ``WHERE NOT flag`` -- which DuckDB pushes down as a
|
|
754
|
+
bare column reference rather than rewriting to ``flag = true`` -- was
|
|
755
|
+
refused as "predicate root must resolve to BOOLEAN" even though the
|
|
756
|
+
parser had already resolved the column to BOOLEAN and stored it on the
|
|
757
|
+
node.
|
|
758
|
+
"""
|
|
759
|
+
data_type = expression_type(expression)
|
|
760
|
+
return data_type is not None and pa.types.is_boolean(data_type)
|
|
748
761
|
|
|
749
762
|
def _payload(self, prefix: str, ref: object) -> tuple[pa.Field[Any], pa.Scalar[Any]]:
|
|
750
763
|
index = _uint(ref, f"{prefix}_ref")
|
|
@@ -63,6 +63,9 @@ from vgi.filter_v2 import (
|
|
|
63
63
|
from vgi.filter_v2 import (
|
|
64
64
|
Literal as V2Literal,
|
|
65
65
|
)
|
|
66
|
+
from vgi.filter_v2 import (
|
|
67
|
+
Not as V2Not,
|
|
68
|
+
)
|
|
66
69
|
from vgi.filter_v2 import (
|
|
67
70
|
RuntimeFilter as V2RuntimeFilter,
|
|
68
71
|
)
|
|
@@ -72,6 +75,9 @@ from vgi.filter_v2 import (
|
|
|
72
75
|
from vgi.filter_v2 import (
|
|
73
76
|
expression_columns as v2_expression_columns,
|
|
74
77
|
)
|
|
78
|
+
from vgi.filter_v2 import (
|
|
79
|
+
expression_type as v2_expression_type,
|
|
80
|
+
)
|
|
75
81
|
|
|
76
82
|
if TYPE_CHECKING:
|
|
77
83
|
from collections.abc import Callable, Iterator
|
|
@@ -207,6 +213,7 @@ __all__ = [
|
|
|
207
213
|
"OrFilter",
|
|
208
214
|
"StructFilter",
|
|
209
215
|
"ExpressionFilter",
|
|
216
|
+
"FilterSQLUnsupportedError",
|
|
210
217
|
"V2ExpressionFilter",
|
|
211
218
|
# Expression node classes
|
|
212
219
|
"ExpressionNode",
|
|
@@ -1638,6 +1645,22 @@ class PushdownFilters:
|
|
|
1638
1645
|
# =============================================================================
|
|
1639
1646
|
|
|
1640
1647
|
|
|
1648
|
+
class FilterSQLUnsupportedError(ValueError):
|
|
1649
|
+
"""A filter that `to_sql()` cannot render as a SQL fragment.
|
|
1650
|
+
|
|
1651
|
+
Raised rather than skipped, and that is the whole point: DuckDB does **not**
|
|
1652
|
+
re-apply a predicate it pushed into a table function, so a WHERE clause that
|
|
1653
|
+
silently omits one does not return the same rows more slowly -- it returns
|
|
1654
|
+
the wrong rows. Degrading quietly here would turn an unrenderable filter
|
|
1655
|
+
into a wrong answer with no error anywhere.
|
|
1656
|
+
|
|
1657
|
+
A worker that catches this has two honest options: evaluate the filters in
|
|
1658
|
+
memory instead (`PushdownFilters.apply()` / `evaluate()` handle every v2
|
|
1659
|
+
expression), or decline the scan. Subclasses `ValueError` so existing
|
|
1660
|
+
callers that catch the old error keep working.
|
|
1661
|
+
"""
|
|
1662
|
+
|
|
1663
|
+
|
|
1641
1664
|
def _filter_to_sql(
|
|
1642
1665
|
f: Filter,
|
|
1643
1666
|
quote: Callable[[str], str],
|
|
@@ -1713,8 +1736,19 @@ def _filter_to_sql(
|
|
|
1713
1736
|
# Constants are embedded directly in the SQL string.
|
|
1714
1737
|
return expr.to_sql(f.column_name), []
|
|
1715
1738
|
|
|
1739
|
+
case V2ExpressionFilter(expression=expression):
|
|
1740
|
+
# A v2 expression the legacy projection could not reduce to a leaf
|
|
1741
|
+
# shape (arithmetic, casts, extension calls, ...). It evaluates
|
|
1742
|
+
# correctly -- `V2ExpressionFilter.evaluate()` runs the v2 reference
|
|
1743
|
+
# evaluator -- there is simply no SQL rendering for it yet.
|
|
1744
|
+
raise FilterSQLUnsupportedError(
|
|
1745
|
+
f"filter on {f.column_name!r} is a v2 expression with no SQL rendering "
|
|
1746
|
+
f"({type(expression).__name__}); evaluate it with PushdownFilters.apply() "
|
|
1747
|
+
f"instead, or the scan will return rows the predicate excludes"
|
|
1748
|
+
)
|
|
1749
|
+
|
|
1716
1750
|
case _:
|
|
1717
|
-
raise
|
|
1751
|
+
raise FilterSQLUnsupportedError(f"Unknown filter type: {type(f)}")
|
|
1718
1752
|
|
|
1719
1753
|
|
|
1720
1754
|
# =============================================================================
|
|
@@ -1787,6 +1821,48 @@ def _pushdown_from_v2_state(state: V2FilterState) -> PushdownFilters:
|
|
|
1787
1821
|
)
|
|
1788
1822
|
|
|
1789
1823
|
|
|
1824
|
+
def _v2_boolean_column_view(expression: V2FilterExpression) -> Filter | None:
|
|
1825
|
+
"""Project ``WHERE flag`` / ``WHERE NOT flag`` onto the legacy equality leaf.
|
|
1826
|
+
|
|
1827
|
+
DuckDB pushes a predicate that *is* a boolean column down as a bare
|
|
1828
|
+
``column_ref``, not as ``flag = true``. Left as a generic v2 expression it
|
|
1829
|
+
becomes a `V2ExpressionFilter`, which evaluates fine but renders no SQL --
|
|
1830
|
+
so every SQL-backed worker loses pushdown on the most ordinary boolean
|
|
1831
|
+
predicate there is, and on the commonest shape of all, a conjunction with
|
|
1832
|
+
one, it loses pushdown for the whole conjunction.
|
|
1833
|
+
|
|
1834
|
+
The rewrite is exact rather than approximate, including under NULLs:
|
|
1835
|
+
``WHERE flag`` keeps only TRUE (a NULL predicate is not satisfied), and so
|
|
1836
|
+
does ``flag = true``; ``WHERE NOT flag`` keeps only FALSE, and so does
|
|
1837
|
+
``flag = false``. Three-valued logic makes the two pairs agree on every
|
|
1838
|
+
input, which is what lets this be a projection and not a semantic change.
|
|
1839
|
+
|
|
1840
|
+
Args:
|
|
1841
|
+
expression: A v2 expression that may be a bare boolean column or its
|
|
1842
|
+
negation.
|
|
1843
|
+
|
|
1844
|
+
Returns:
|
|
1845
|
+
The equivalent `ConstantFilter`, or None when *expression* is neither.
|
|
1846
|
+
|
|
1847
|
+
"""
|
|
1848
|
+
|
|
1849
|
+
def boolean_column(node: V2FilterExpression) -> V2ColumnRef | None:
|
|
1850
|
+
if not isinstance(node, V2ColumnRef):
|
|
1851
|
+
return None
|
|
1852
|
+
node_type = v2_expression_type(node)
|
|
1853
|
+
# An unresolved column (no bind schema) is not known to be boolean, and
|
|
1854
|
+
# guessing here would rewrite a non-boolean predicate into `= true`.
|
|
1855
|
+
if node_type is None or not pa.types.is_boolean(node_type):
|
|
1856
|
+
return None
|
|
1857
|
+
return node
|
|
1858
|
+
|
|
1859
|
+
if ref := boolean_column(expression):
|
|
1860
|
+
return ConstantFilter(ref.column_name, ref.column_index, ComparisonOp.EQ, pa.scalar(True))
|
|
1861
|
+
if isinstance(expression, V2Not) and (ref := boolean_column(expression.expression)):
|
|
1862
|
+
return ConstantFilter(ref.column_name, ref.column_index, ComparisonOp.EQ, pa.scalar(False))
|
|
1863
|
+
return None
|
|
1864
|
+
|
|
1865
|
+
|
|
1790
1866
|
def _v2_filter_view(expression: V2FilterExpression, context: EvaluationContext) -> Filter | None:
|
|
1791
1867
|
"""Project common v2 shapes into the longstanding convenience classes."""
|
|
1792
1868
|
if isinstance(expression, V2Comparison):
|
|
@@ -1802,6 +1878,8 @@ def _v2_filter_view(expression: V2FilterExpression, context: EvaluationContext)
|
|
|
1802
1878
|
}
|
|
1803
1879
|
if op := mapping.get(expression.op):
|
|
1804
1880
|
return ConstantFilter(operands[0].column_name, operands[0].column_index, op, operands[1].value)
|
|
1881
|
+
if boolean_leaf := _v2_boolean_column_view(expression):
|
|
1882
|
+
return boolean_leaf
|
|
1805
1883
|
if isinstance(expression, V2IsNull) and isinstance(expression.expression, V2ColumnRef):
|
|
1806
1884
|
ref = expression.expression
|
|
1807
1885
|
if expression.negated:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/cases/negative/unknown-node.json
RENAMED
|
File without changes
|
|
File without changes
|
{vgi_python-0.36.1 → vgi_python-0.36.2}/conformance/filter-v2/cases/positive/empty-snapshot.json
RENAMED
|
File without changes
|