chtypes 2.0.0.dev10__tar.gz → 2.0.0.dev11__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.
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/CHANGELOG.md +12 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/PKG-INFO +2 -2
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/README.md +1 -1
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/pyproject.toml +1 -1
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/__init__.py +21 -1
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_abi2/_decls.py +26 -2
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_abi2/_errmap.py +1 -1
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_abi2/_vocab.py +92 -4
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_decode.py +51 -4
- chtypes-2.0.0.dev11/src/chtypes/_input.py +376 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/errors.py +3 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/library.py +93 -13
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/results.py +63 -9
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/abi2/test_public_library.py +111 -4
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/abi2/test_reader_rules.py +1 -1
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/api/test_decode.py +209 -18
- chtypes-2.0.0.dev11/tests/api/test_input.py +238 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/goldens_v1/data/stub-goldens.json +2 -2
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/goldens_v1/test_runner.py +5 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/uv.lock +1 -1
- chtypes-2.0.0.dev10/src/chtypes/_input.py +0 -185
- chtypes-2.0.0.dev10/tests/api/test_input.py +0 -104
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/.gitignore +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/LICENSE +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/__main__.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_abi2/__init__.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_abi2/_errors.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_abi2/_loader.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_advisory.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_codes.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ed25519.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_guard.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/__init__.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_channel.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_constants.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_dsse.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_ensure.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_errors.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_faults.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_goldens.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_hold.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_http.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_layout.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_lock.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_oci.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_prune.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_referrers.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_resolve.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_retired.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_revocation.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_ocifetch/_unpack.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/_setup.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/py.typed +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/src/chtypes/registry.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/abi2/__init__.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/abi2/_stub_tree.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/abi2/conftest.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/abi2/test_conformance.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/abi2/test_dev_fingerprint.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/abi2/test_goldens_runner_stub.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/abi2/test_loader.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/abi2/test_public_open.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/abi2/test_public_registry.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/abi2/test_public_server.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/abi2/test_public_setup_cases.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/abi2/test_registry_fetch.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/abi2/test_registry_flight.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/api/__init__.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/api/test_trusted_keys.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/api/test_vocab.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/cli/__init__.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/cli/conftest.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/cli/test_devchannel.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/cli/test_main.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/cli/test_resolve_prune.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/cli/test_revocation_cli.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/conftest.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/goldens_v1/__init__.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/__init__.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/_bundle_support.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/_registry_support.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/_sign_support.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/conftest.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_cache_roots.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_cache_strict.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_conformance.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_devchannel.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_dsse.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_ensure.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_goldens.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_http.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_layout.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_lock.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_oci.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_prodv2_smoke.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_prodv2channel.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_retired.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_revocation.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_seam_gate.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/ocifetch/test_unpack.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/test_abi_identity.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/test_cache_roots_api.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/test_devchannel_registry.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/test_ed25519.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/test_examples_tour.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/test_fetch_options.py +0 -0
- {chtypes-2.0.0.dev10 → chtypes-2.0.0.dev11}/tests/test_support_v2_gen.py +0 -0
|
@@ -8,6 +8,13 @@ The four bindings in this repository are released together and give one answer,
|
|
|
8
8
|
|
|
9
9
|
### Added
|
|
10
10
|
|
|
11
|
+
- `column_defaults` is covered by unit tests (ABI v2): the exact `insert_options` JSON for a UTF-8 value, a non-UTF-8 value (`value_b64`), an empty value (sent as `""`) and two entries in order, and the decode of a `default_override` cell (`Source.DEFAULT_OVERRIDE`, stored). The batches guide gains a usage section. No behavior changed.
|
|
12
|
+
- `CODE_DECLINED` (ABI v2, -2): the code a declined row, outcome or verdict carries, generated from the description and exported from `chtypes`, as `bindings-v1.md` section 3 promises.
|
|
13
|
+
- `CallError.reason` (ABI v2): the error's catalog id, read through `chs_error_reason` and passed through verbatim (ASCII, empty if none), on all four call classes.
|
|
14
|
+
- Spec batch 2, the options documents (ABI v2; moves the dev fingerprint): keyword-only `insertable_columns`, `column_defaults` (a sequence of `ColumnDefault`), `verdict_basis` (`VerdictBasis`: `INPUT`, `EXPORT`) and `defer_defaults` (`DeferDefaults`: `NONE`, `SERVER`) build `insert_options` for `Schema.row`, `Schema.rows`, `Schema.parse_block` and `Filter.rows`; `param_encoding` (`ParamEncoding`: `ESCAPED`, `RAW`) builds `filter_options` for `Schema.compile_filter`; `posture` (`Posture`: `CREATE`, `LOAD`) builds `schema_options` for `Library.compile_table`. `insert_options_extra`, `filter_options_extra` and `schema_options_extra` pass a member the binding has no name for through as JSON text, so the library, which refuses an unknown key (rule r1), is the only judge. A document with no member set is not sent. `Filter.rows` takes `columns` (`chs_filter_eval_body` takes the column list).
|
|
15
|
+
- Spec batch 2, a value that is not UTF-8 (ABI v2): a settings value, a query-parameter value, a `setup` default and a server profile's settings value is sent as `{"b64": ...}` (the content `json_object_byte_values`), where the binding used to refuse it, and `SchemaServer.settings` decodes the same form back (as `surrogateescape` text, the spelling the input side takes).
|
|
16
|
+
- Spec batch 2, the decline and refusal members (ABI v2): `RowResult`, `BatchResult` and `FilterResult` carry `reason` (the catalog id, present where the code is -2, `CHS_CODE_DECLINED`), `refused_at` (a `RefusalSite`: `CALL`, `BODY_READ`, `ROW`, `BODY_STEP`) and `refused_row`; `RowResult.verdict_reason`; `FilterRowError.reason`; `BatchResult.export_columns` and `BatchResult.export_declined_reason`.
|
|
17
|
+
- Spec batch 2, the schema description (ABI v2): `SchemaDescription.posture`, and `Column.default_support` (a `DefaultSupport`), `Column.default_support_reason` and `Column.reads`, reserved members a build reports when it implements them. `Source.DEFAULT_DEFERRED`, `Source.DEFAULT_OVERRIDE` (stored) and `DeclinedTier.SERVER_REFUSES` join the vocabularies.
|
|
11
18
|
- A fetch-only call (#492): `Registry.fetch(request) -> Resolved` resolves, fetches, verifies and installs the build a request names into the cache, as `chtypes fetch` does, and opens nothing: no library is loaded and the process setup is untouched, so it needs no `setup`. It honors the registry's fetch options (offline, the cache, and under the production channel the bases, the trust and the lock), and a concurrent `fetch` and open of one request share one fetch. The `Resolved` names the installed version, build, digests and library path; errors are the fetch codes' classes.
|
|
12
19
|
- `chtypes resolve <spelling> [--json]` (#493): what a line or version resolves to on every platform the registry offers, one `resolved <version> <platform> <build> <manifest>` line each, or with `--json` one JSON array of `{platform, version, build, manifest}` objects, each signed statement verified exactly as a fetch verifies it and no layer downloaded; `--offline` answers from the cache. The four CLIs print the same bytes, so one parser reads them (a CI cache key, for example).
|
|
13
20
|
- `chtypes prune [--line <line>] [--keep <n>] [--dry-run]` (#494): removes the installed builds of each line and platform that at least n newer installed builds supersede (n defaults to 1), each with its record, its blobs and its `index.json` entry; `--dry-run` prints exactly what would go. It never removes a build a running process holds: a registry now holds every build it opens or fetches, with a shared `flock` on the entry's `verified.json` until the process exits, and prune removes an entry only after taking the exclusive lock without waiting, reporting it `in-use` otherwise. It never touches a system directory, nor, on the dev channel, another fingerprint's builds. The rules are `docs/guides/fetch-v1.md` sections 1 and 3, and the `resolve-build-*` and `prune-*` conformance cases hold all four bindings to them.
|
|
@@ -27,6 +34,10 @@ The four bindings in this repository are released together and give one answer,
|
|
|
27
34
|
|
|
28
35
|
### Changed
|
|
29
36
|
|
|
37
|
+
- **Breaking (ABI v2 dev): `BatchResult.spans` is a tuple of `Span | None`**, one entry per `rows` entry and index-aligned with it: `row_spans` carries `null` for a row the export did not carry (a skipped row, or a row a filter cut), which reads as `None`. It was the exported rows' spans only.
|
|
38
|
+
- **Breaking (ABI v2 dev): `AtMergeEntry.row` is `AtMergeEntry.part_row`**, the document's `part_row`.
|
|
39
|
+
- A document's `code` can be -2 (`CHS_CODE_DECLINED`) for a row, batch, filter result or verdict this build declined, and every decline names its `reason`.
|
|
40
|
+
- The refusal of a settings, query-parameter, default or server-settings value that is not valid UTF-8 is gone (it is the `{"b64": ...}` form now); a key that is not valid UTF-8, a macro and a server timezone are still refused, as a `UsageError` naming the input.
|
|
30
41
|
- `chtypes list` and the tag listing name the published lines only (two-part, numeric order), as Go's always did; `chtypes resolve <line>` prints the exact version a line resolves to (#613).
|
|
31
42
|
- **Breaking: the public surface the parity gate carried as exceptions is resolved, before the v2 lock (#499, #500).** A convenience exists in every binding or in none (`docs/reference/bindings-v1.md` §1, principle 2). Migration, old → new:
|
|
32
43
|
- `chtypes.errors.internal` and `chtypes.errors.misuse` → private (#499): they were the binding's own construction helpers, never documented. Catch `InternalError` and `UsageError`, as before.
|
|
@@ -71,6 +82,7 @@ The four bindings in this repository are released together and give one answer,
|
|
|
71
82
|
|
|
72
83
|
### Removed
|
|
73
84
|
|
|
85
|
+
- **Breaking (ABI v2 dev): `RowResult.unsupported_settings`**: the row document no longer carries `unsupported_settings`; the batch's and the filter result's lists stay.
|
|
74
86
|
- `SchemaServer.filter_declined_settings` (a breaking change inside v2 dev, #588): the server member no longer carries the list. Read `SchemaDescription.filter_declined_settings`, whose `server`-layer entries are the profile's.
|
|
75
87
|
|
|
76
88
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: chtypes
|
|
3
|
-
Version: 2.0.0.
|
|
3
|
+
Version: 2.0.0.dev11
|
|
4
4
|
Summary: Python binding for the chtypes artifacts: ClickHouse's own type system, per version, behind the frozen chs_* C ABI
|
|
5
5
|
Project-URL: Homepage, https://github.com/wave-rf/chtypes
|
|
6
6
|
Project-URL: Repository, https://github.com/wave-rf/chtypes
|
|
@@ -96,7 +96,7 @@ A bad **row** is a verdict, not an exception: `outcome` becomes `Outcome.REJECTE
|
|
|
96
96
|
|
|
97
97
|
**`ctypes` releases the GIL for the whole of a foreign call**, so calls on compiled handles run in parallel across threads. The package takes no lock around a call; it keeps a close guard per handle and one setup guard.
|
|
98
98
|
|
|
99
|
-
**The INSERT column list is a keyword-only `columns`** on `schema.row`, `schema.rows` and `
|
|
99
|
+
**The INSERT column list is a keyword-only `columns`** on `schema.row`, `schema.rows`, `schema.parse_block` and `filter.rows`: `schema.row(Format.JSON_EACH_ROW, body, columns=["id", "e"])`. `None` or an empty sequence is the no-list shape; a list makes the data supply exactly those columns, with a listed `EPHEMERAL` value read and in scope for the DEFAULTs that reference it but never stored.
|
|
100
100
|
|
|
101
101
|
**Known gaps in 1.0** are listed, with workarounds, in [`docs/limitations.md`](https://github.com/wave-rf/chtypes/blob/main/docs/limitations.md#known-gaps-in-10).
|
|
102
102
|
|
|
@@ -77,7 +77,7 @@ A bad **row** is a verdict, not an exception: `outcome` becomes `Outcome.REJECTE
|
|
|
77
77
|
|
|
78
78
|
**`ctypes` releases the GIL for the whole of a foreign call**, so calls on compiled handles run in parallel across threads. The package takes no lock around a call; it keeps a close guard per handle and one setup guard.
|
|
79
79
|
|
|
80
|
-
**The INSERT column list is a keyword-only `columns`** on `schema.row`, `schema.rows` and `
|
|
80
|
+
**The INSERT column list is a keyword-only `columns`** on `schema.row`, `schema.rows`, `schema.parse_block` and `filter.rows`: `schema.row(Format.JSON_EACH_ROW, body, columns=["id", "e"])`. `None` or an empty sequence is the no-list shape; a list makes the data supply exactly those columns, with a listed `EPHEMERAL` value read and in scope for the DEFAULTs that reference it but never stored.
|
|
81
81
|
|
|
82
82
|
**Known gaps in 1.0** are listed, with workarounds, in [`docs/limitations.md`](https://github.com/wave-rf/chtypes/blob/main/docs/limitations.md#known-gaps-in-10).
|
|
83
83
|
|
|
@@ -47,22 +47,34 @@ from importlib.metadata import PackageNotFoundError as _PackageNotFound
|
|
|
47
47
|
from importlib.metadata import version as _package_version
|
|
48
48
|
|
|
49
49
|
from ._abi2._vocab import (
|
|
50
|
+
CODE_DECLINED,
|
|
50
51
|
EXPORT_NONE,
|
|
51
52
|
DeclinedLayer,
|
|
52
53
|
DeclinedTier,
|
|
53
54
|
DefaultKind,
|
|
55
|
+
DefaultSupport,
|
|
54
56
|
DiscoverQueryParam,
|
|
55
57
|
DocFlags,
|
|
56
58
|
FilterOutcome,
|
|
57
59
|
Format,
|
|
58
60
|
MergeReason,
|
|
59
61
|
Outcome,
|
|
62
|
+
Posture,
|
|
60
63
|
Reason,
|
|
64
|
+
RefusalSite,
|
|
61
65
|
Source,
|
|
62
66
|
Status,
|
|
63
67
|
Verdict,
|
|
64
68
|
)
|
|
65
|
-
from ._input import
|
|
69
|
+
from ._input import (
|
|
70
|
+
BytesIn,
|
|
71
|
+
ColumnDefault,
|
|
72
|
+
DeferDefaults,
|
|
73
|
+
ParamEncoding,
|
|
74
|
+
ServerProfile,
|
|
75
|
+
Settings,
|
|
76
|
+
VerdictBasis,
|
|
77
|
+
)
|
|
66
78
|
from ._setup import setup
|
|
67
79
|
from .errors import (
|
|
68
80
|
CODE_ARTIFACT_CORRUPT,
|
|
@@ -143,6 +155,7 @@ __all__ = [
|
|
|
143
155
|
"CODE_SOURCE_RETIRED",
|
|
144
156
|
"CODE_SOURCE_UNAUTHORIZED",
|
|
145
157
|
"CODE_SOURCE_UNREACHABLE",
|
|
158
|
+
"CODE_DECLINED",
|
|
146
159
|
"EXPORT_NONE",
|
|
147
160
|
"Advisory",
|
|
148
161
|
"ArtifactCorruptError",
|
|
@@ -163,11 +176,14 @@ __all__ = [
|
|
|
163
176
|
"Capabilities",
|
|
164
177
|
"ChtypesError",
|
|
165
178
|
"Column",
|
|
179
|
+
"ColumnDefault",
|
|
166
180
|
"Computed",
|
|
167
181
|
"DeclinedLayer",
|
|
168
182
|
"DeclinedSetting",
|
|
169
183
|
"DeclinedTier",
|
|
184
|
+
"DeferDefaults",
|
|
170
185
|
"DefaultKind",
|
|
186
|
+
"DefaultSupport",
|
|
171
187
|
"DiscoverQueryParam",
|
|
172
188
|
"DiscoveredColumn",
|
|
173
189
|
"Discovery",
|
|
@@ -187,8 +203,11 @@ __all__ = [
|
|
|
187
203
|
"Library",
|
|
188
204
|
"MergeReason",
|
|
189
205
|
"Outcome",
|
|
206
|
+
"ParamEncoding",
|
|
207
|
+
"Posture",
|
|
190
208
|
"Reason",
|
|
191
209
|
"Registry",
|
|
210
|
+
"RefusalSite",
|
|
192
211
|
"Resolved",
|
|
193
212
|
"Revocation",
|
|
194
213
|
"RowResult",
|
|
@@ -213,6 +232,7 @@ __all__ = [
|
|
|
213
232
|
"UsageError",
|
|
214
233
|
"Value",
|
|
215
234
|
"Verdict",
|
|
235
|
+
"VerdictBasis",
|
|
216
236
|
"cache_root",
|
|
217
237
|
"open_unverified",
|
|
218
238
|
"search_dirs",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# GENERATED by scripts/abi-v1/gen.py --major 2 from spec/abi-v2/abi.json (CHS_ABI_FINGERPRINT sha256:
|
|
1
|
+
# GENERATED by scripts/abi-v1/gen.py --major 2 from spec/abi-v2/abi.json (CHS_ABI_FINGERPRINT sha256:d53239933966e15a3c363e631a94fbba1231d84c4300337115d3ae5377bb41c2) — DO NOT EDIT # noqa: E501
|
|
2
2
|
"""The Python binding's generated ABI v2 layer: ctypes signatures, the handle
|
|
3
3
|
classes, the two-phase resolve functions and invoke_by_name(), the test-only
|
|
4
4
|
dispatcher the conformance suite drives from tests/fixtures/abi-v2/cases.json.
|
|
@@ -19,7 +19,7 @@ from dataclasses import dataclass, field
|
|
|
19
19
|
from . import _errmap
|
|
20
20
|
|
|
21
21
|
CHS_ABI_VERSION = 2
|
|
22
|
-
CHS_ABI_FINGERPRINT = "sha256:
|
|
22
|
+
CHS_ABI_FINGERPRINT = "sha256:d53239933966e15a3c363e631a94fbba1231d84c4300337115d3ae5377bb41c2"
|
|
23
23
|
|
|
24
24
|
# The description's stability: "unstable" while this generation is being
|
|
25
25
|
# designed, so CHS_ABI_FINGERPRINT moves with every change, and "locked" after
|
|
@@ -87,6 +87,7 @@ ALL_SYMBOLS: tuple[str, ...] = (
|
|
|
87
87
|
"chs_error_column",
|
|
88
88
|
"chs_error_free",
|
|
89
89
|
"chs_error_message",
|
|
90
|
+
"chs_error_reason",
|
|
90
91
|
"chs_error_status",
|
|
91
92
|
"chs_filter_create",
|
|
92
93
|
"chs_filter_eval_block",
|
|
@@ -248,6 +249,7 @@ _add("chs_error_ch_code", "scalar", "int32", _P("error", "handle", "chs_error"))
|
|
|
248
249
|
_add("chs_error_ch_name", "handle", "chs_buf", _P("error", "handle", "chs_error"))
|
|
249
250
|
_add("chs_error_message", "handle", "chs_buf", _P("error", "handle", "chs_error"))
|
|
250
251
|
_add("chs_error_column", "handle", "chs_buf", _P("error", "handle", "chs_error"))
|
|
252
|
+
_add("chs_error_reason", "handle", "chs_buf", _P("error", "handle", "chs_error"))
|
|
251
253
|
_add("chs_error_free", "void", None, _P("error", "handle", "chs_error", nullable=True))
|
|
252
254
|
_add(
|
|
253
255
|
"chs_live_handles",
|
|
@@ -371,6 +373,7 @@ _add(
|
|
|
371
373
|
_P("body", "bytes_in", None),
|
|
372
374
|
_P("settings", "bytes_in", None),
|
|
373
375
|
_P("columns", "bytes_in", None),
|
|
376
|
+
_P("options", "bytes_in", None),
|
|
374
377
|
_P("out", "out_handle", "chs_buf"),
|
|
375
378
|
_P("err", "out_error", "chs_error", nullable=True),
|
|
376
379
|
)
|
|
@@ -386,6 +389,7 @@ _add(
|
|
|
386
389
|
_P("filter", "handle", "chs_filter", nullable=True),
|
|
387
390
|
_P("export_format", "scalar", "int32"),
|
|
388
391
|
_P("doc_flags", "scalar", "uint32"),
|
|
392
|
+
_P("options", "bytes_in", None),
|
|
389
393
|
_P("out", "out_handle", "chs_buf"),
|
|
390
394
|
_P("out_export", "out_handle", "chs_buf", nullable=True),
|
|
391
395
|
_P("err", "out_error", "chs_error", nullable=True),
|
|
@@ -398,6 +402,7 @@ _add(
|
|
|
398
402
|
_P("expr", "bytes_in", None),
|
|
399
403
|
_P("query_params", "bytes_in", None),
|
|
400
404
|
_P("settings", "bytes_in", None),
|
|
405
|
+
_P("options", "bytes_in", None),
|
|
401
406
|
_P("out", "out_handle", "chs_filter"),
|
|
402
407
|
_P("err", "out_error", "chs_error", nullable=True),
|
|
403
408
|
)
|
|
@@ -410,6 +415,8 @@ _add(
|
|
|
410
415
|
_P("format", "enum", "chs_format"),
|
|
411
416
|
_P("body", "bytes_in", None),
|
|
412
417
|
_P("settings", "bytes_in", None),
|
|
418
|
+
_P("columns", "bytes_in", None),
|
|
419
|
+
_P("options", "bytes_in", None),
|
|
413
420
|
_P("out", "out_handle", "chs_buf"),
|
|
414
421
|
_P("err", "out_error", "chs_error", nullable=True),
|
|
415
422
|
)
|
|
@@ -422,6 +429,7 @@ _add(
|
|
|
422
429
|
_P("body", "bytes_in", None),
|
|
423
430
|
_P("settings", "bytes_in", None),
|
|
424
431
|
_P("columns", "bytes_in", None),
|
|
432
|
+
_P("options", "bytes_in", None),
|
|
425
433
|
_P("out", "out_handle", "chs_block"),
|
|
426
434
|
_P("err", "out_error", "chs_error", nullable=True),
|
|
427
435
|
)
|
|
@@ -563,6 +571,7 @@ class Api:
|
|
|
563
571
|
info.ch_name.decode("ascii", "replace") if info else "",
|
|
564
572
|
message,
|
|
565
573
|
info.column if info else b"",
|
|
574
|
+
reason=info.reason.decode("ascii", "replace") if info else "",
|
|
566
575
|
)
|
|
567
576
|
|
|
568
577
|
def live_handles(self) -> bytes:
|
|
@@ -801,6 +810,7 @@ class Api:
|
|
|
801
810
|
body: bytes | None,
|
|
802
811
|
settings: bytes | None,
|
|
803
812
|
columns: bytes | None,
|
|
813
|
+
options: bytes | None,
|
|
804
814
|
) -> bytes:
|
|
805
815
|
"""The generated call wrapper for chs_preview_row (thread class shared).
|
|
806
816
|
|
|
@@ -813,6 +823,7 @@ class Api:
|
|
|
813
823
|
*_bytes_in(body),
|
|
814
824
|
*_bytes_in(settings),
|
|
815
825
|
*_bytes_in(columns),
|
|
826
|
+
*_bytes_in(options),
|
|
816
827
|
ctypes.byref(out),
|
|
817
828
|
ctypes.byref(err),
|
|
818
829
|
)
|
|
@@ -829,6 +840,7 @@ class Api:
|
|
|
829
840
|
filter: FilterHandle | None,
|
|
830
841
|
export_format: int,
|
|
831
842
|
doc_flags: int,
|
|
843
|
+
options: bytes | None,
|
|
832
844
|
) -> tuple[bytes, bytes | None]:
|
|
833
845
|
"""The generated call wrapper for chs_preview_batch (thread class shared).
|
|
834
846
|
|
|
@@ -845,6 +857,7 @@ class Api:
|
|
|
845
857
|
None if filter is None else filter.value,
|
|
846
858
|
int(export_format),
|
|
847
859
|
int(doc_flags),
|
|
860
|
+
*_bytes_in(options),
|
|
848
861
|
ctypes.byref(out),
|
|
849
862
|
ctypes.byref(out_export),
|
|
850
863
|
ctypes.byref(err),
|
|
@@ -861,6 +874,7 @@ class Api:
|
|
|
861
874
|
expr: bytes | None,
|
|
862
875
|
query_params: bytes | None,
|
|
863
876
|
settings: bytes | None,
|
|
877
|
+
options: bytes | None,
|
|
864
878
|
) -> FilterHandle:
|
|
865
879
|
"""The generated call wrapper for chs_filter_create (thread class shared).
|
|
866
880
|
|
|
@@ -872,6 +886,7 @@ class Api:
|
|
|
872
886
|
*_bytes_in(expr),
|
|
873
887
|
*_bytes_in(query_params),
|
|
874
888
|
*_bytes_in(settings),
|
|
889
|
+
*_bytes_in(options),
|
|
875
890
|
ctypes.byref(out),
|
|
876
891
|
ctypes.byref(err),
|
|
877
892
|
)
|
|
@@ -884,6 +899,8 @@ class Api:
|
|
|
884
899
|
format: int,
|
|
885
900
|
body: bytes | None,
|
|
886
901
|
settings: bytes | None,
|
|
902
|
+
columns: bytes | None,
|
|
903
|
+
options: bytes | None,
|
|
887
904
|
) -> bytes:
|
|
888
905
|
"""The generated call wrapper for chs_filter_eval_body (thread class shared).
|
|
889
906
|
|
|
@@ -895,6 +912,8 @@ class Api:
|
|
|
895
912
|
int(format),
|
|
896
913
|
*_bytes_in(body),
|
|
897
914
|
*_bytes_in(settings),
|
|
915
|
+
*_bytes_in(columns),
|
|
916
|
+
*_bytes_in(options),
|
|
898
917
|
ctypes.byref(out),
|
|
899
918
|
ctypes.byref(err),
|
|
900
919
|
)
|
|
@@ -908,6 +927,7 @@ class Api:
|
|
|
908
927
|
body: bytes | None,
|
|
909
928
|
settings: bytes | None,
|
|
910
929
|
columns: bytes | None,
|
|
930
|
+
options: bytes | None,
|
|
911
931
|
) -> BlockHandle:
|
|
912
932
|
"""The generated call wrapper for chs_block_create (thread class shared).
|
|
913
933
|
|
|
@@ -920,6 +940,7 @@ class Api:
|
|
|
920
940
|
*_bytes_in(body),
|
|
921
941
|
*_bytes_in(settings),
|
|
922
942
|
*_bytes_in(columns),
|
|
943
|
+
*_bytes_in(options),
|
|
923
944
|
ctypes.byref(out),
|
|
924
945
|
ctypes.byref(err),
|
|
925
946
|
)
|
|
@@ -1007,6 +1028,7 @@ class ErrorInfo:
|
|
|
1007
1028
|
ch_name: bytes
|
|
1008
1029
|
message: bytes
|
|
1009
1030
|
column: bytes
|
|
1031
|
+
reason: bytes = b""
|
|
1010
1032
|
|
|
1011
1033
|
|
|
1012
1034
|
@dataclass
|
|
@@ -1068,6 +1090,7 @@ def _decode_error(api: Api, err_ptr: int) -> ErrorInfo:
|
|
|
1068
1090
|
ch_name = _read_buf(api, api._raw["chs_error_ch_name"](err_ptr))
|
|
1069
1091
|
message = _read_buf(api, api._raw["chs_error_message"](err_ptr))
|
|
1070
1092
|
column = _read_buf(api, api._raw["chs_error_column"](err_ptr))
|
|
1093
|
+
reason = _read_buf(api, api._raw["chs_error_reason"](err_ptr))
|
|
1071
1094
|
api._raw["chs_error_free"](err_ptr)
|
|
1072
1095
|
return ErrorInfo(
|
|
1073
1096
|
status=STATUS_BY_VALUE.get(status_val, f"UNKNOWN:{status_val}"),
|
|
@@ -1075,6 +1098,7 @@ def _decode_error(api: Api, err_ptr: int) -> ErrorInfo:
|
|
|
1075
1098
|
ch_name=ch_name,
|
|
1076
1099
|
message=message,
|
|
1077
1100
|
column=column,
|
|
1101
|
+
reason=reason,
|
|
1078
1102
|
)
|
|
1079
1103
|
|
|
1080
1104
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# GENERATED by scripts/abi-v1/gen.py --major 2 from spec/abi-v2/abi.json (CHS_ABI_FINGERPRINT sha256:
|
|
1
|
+
# GENERATED by scripts/abi-v1/gen.py --major 2 from spec/abi-v2/abi.json (CHS_ABI_FINGERPRINT sha256:d53239933966e15a3c363e631a94fbba1231d84c4300337115d3ae5377bb41c2) — DO NOT EDIT # noqa: E501
|
|
2
2
|
"""spec/abi-v2/sdk.json's error-mapping tables, as references to the
|
|
3
3
|
public classes (python/src/chtypes/errors.py, re-exported by
|
|
4
4
|
python/src/chtypes/_abi2/_errors.py). Only the MAPPING is generated: the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# GENERATED by scripts/abi-v1/gen.py --major 2 from spec/abi-v2/abi.json (CHS_ABI_FINGERPRINT sha256:
|
|
1
|
+
# GENERATED by scripts/abi-v1/gen.py --major 2 from spec/abi-v2/abi.json (CHS_ABI_FINGERPRINT sha256:d53239933966e15a3c363e631a94fbba1231d84c4300337115d3ae5377bb41c2) — DO NOT EDIT # noqa: E501
|
|
2
2
|
"""The Python binding's generated vocabularies, from spec/abi-v2/abi.json: the C
|
|
3
3
|
enums (`Format`, `Status`), the document vocabularies (`Outcome`, `FilterOutcome`,
|
|
4
4
|
`Verdict`, `DefaultKind`, `MergeReason`, `DeclinedTier`, `DeclinedLayer`, `Reason`,
|
|
@@ -256,6 +256,7 @@ class DeclinedTier(StrEnum):
|
|
|
256
256
|
PREDICATE = "predicate"
|
|
257
257
|
PREDICATE_UNFLIPPED = "predicate-unflipped"
|
|
258
258
|
RESULT_CONTENT = "result-content"
|
|
259
|
+
SERVER_REFUSES = "server-refuses"
|
|
259
260
|
|
|
260
261
|
@classmethod
|
|
261
262
|
def _missing_(cls, value: object) -> DeclinedTier | None:
|
|
@@ -299,6 +300,83 @@ class DeclinedLayer(StrEnum):
|
|
|
299
300
|
return cls(text)
|
|
300
301
|
|
|
301
302
|
|
|
303
|
+
class Posture(StrEnum):
|
|
304
|
+
"""How a schema's statement was compiled: `create`, as a server's CREATE TABLE,
|
|
305
|
+
or `load`, as a server loads the stored definition of a table it holds."""
|
|
306
|
+
|
|
307
|
+
CREATE = "create"
|
|
308
|
+
LOAD = "load"
|
|
309
|
+
|
|
310
|
+
@classmethod
|
|
311
|
+
def _missing_(cls, value: object) -> Posture | None:
|
|
312
|
+
return _unknown_str(cls, value)
|
|
313
|
+
|
|
314
|
+
@property
|
|
315
|
+
def known(self) -> bool:
|
|
316
|
+
"""Whether the description lists this value: False for exactly the unknown(n)
|
|
317
|
+
member an unlisted value reads as (rule r3)."""
|
|
318
|
+
return type(self)._value2member_map_.get(self._value_) is self
|
|
319
|
+
|
|
320
|
+
@classmethod
|
|
321
|
+
def of(cls, text: str) -> Posture:
|
|
322
|
+
"""Map a document's spelling. One the description does not list is kept as
|
|
323
|
+
this vocabulary's unknown(n) member, carrying it (rule r3)."""
|
|
324
|
+
return cls(text)
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
class RefusalSite(StrEnum):
|
|
328
|
+
"""Where a batch or filter document's refusal sits: `call` (the call, its settings or its
|
|
329
|
+
column list), `body_read` (the body outside any row: a header, the framing), `row` (one
|
|
330
|
+
row, `refused_row`) or `body_step` (a whole-body step)."""
|
|
331
|
+
|
|
332
|
+
CALL = "call"
|
|
333
|
+
BODY_READ = "body_read"
|
|
334
|
+
ROW = "row"
|
|
335
|
+
BODY_STEP = "body_step"
|
|
336
|
+
|
|
337
|
+
@classmethod
|
|
338
|
+
def _missing_(cls, value: object) -> RefusalSite | None:
|
|
339
|
+
return _unknown_str(cls, value)
|
|
340
|
+
|
|
341
|
+
@property
|
|
342
|
+
def known(self) -> bool:
|
|
343
|
+
"""Whether the description lists this value: False for exactly the unknown(n)
|
|
344
|
+
member an unlisted value reads as (rule r3)."""
|
|
345
|
+
return type(self)._value2member_map_.get(self._value_) is self
|
|
346
|
+
|
|
347
|
+
@classmethod
|
|
348
|
+
def of(cls, text: str) -> RefusalSite:
|
|
349
|
+
"""Map a document's spelling. One the description does not list is kept as
|
|
350
|
+
this vocabulary's unknown(n) member, carrying it (rule r3)."""
|
|
351
|
+
return cls(text)
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
class DefaultSupport(StrEnum):
|
|
355
|
+
"""What this build does with a column's DEFAULT, as `schema_description` reports it per
|
|
356
|
+
column: `computed`, `generated`, `deferred` or `declined` (with a reason)."""
|
|
357
|
+
|
|
358
|
+
COMPUTED = "computed"
|
|
359
|
+
GENERATED = "generated"
|
|
360
|
+
DEFERRED = "deferred"
|
|
361
|
+
DECLINED = "declined"
|
|
362
|
+
|
|
363
|
+
@classmethod
|
|
364
|
+
def _missing_(cls, value: object) -> DefaultSupport | None:
|
|
365
|
+
return _unknown_str(cls, value)
|
|
366
|
+
|
|
367
|
+
@property
|
|
368
|
+
def known(self) -> bool:
|
|
369
|
+
"""Whether the description lists this value: False for exactly the unknown(n)
|
|
370
|
+
member an unlisted value reads as (rule r3)."""
|
|
371
|
+
return type(self)._value2member_map_.get(self._value_) is self
|
|
372
|
+
|
|
373
|
+
@classmethod
|
|
374
|
+
def of(cls, text: str) -> DefaultSupport:
|
|
375
|
+
"""Map a document's spelling. One the description does not list is kept as
|
|
376
|
+
this vocabulary's unknown(n) member, carrying it (rule r3)."""
|
|
377
|
+
return cls(text)
|
|
378
|
+
|
|
379
|
+
|
|
302
380
|
class DiscoverQueryParam(StrEnum):
|
|
303
381
|
"""A query parameter of the SQL `discover_query` returns, which the caller binds
|
|
304
382
|
when it runs the query."""
|
|
@@ -409,6 +487,8 @@ class Source:
|
|
|
409
487
|
DEFAULT_EXPR_UNSUPPORTED: Final = "default_expr_unsupported"
|
|
410
488
|
DEFAULT_VOLATILE_UNRESOLVED: Final = "default_volatile_unresolved"
|
|
411
489
|
DEFAULT_PENDING: Final = "default_pending"
|
|
490
|
+
DEFAULT_DEFERRED: Final = "default_deferred"
|
|
491
|
+
DEFAULT_OVERRIDE: Final = "default_override"
|
|
412
492
|
|
|
413
493
|
@staticmethod
|
|
414
494
|
def known(source: str) -> bool:
|
|
@@ -417,9 +497,8 @@ class Source:
|
|
|
417
497
|
|
|
418
498
|
@staticmethod
|
|
419
499
|
def is_stored(source: str) -> bool:
|
|
420
|
-
"""The description's `is_stored` fact for `source
|
|
421
|
-
|
|
422
|
-
until it does, an unlisted source is not stored."""
|
|
500
|
+
"""The description's `is_stored` fact for `source`; an unknown(n) source
|
|
501
|
+
reports its fallback's (`skipped`), as rule r3 says."""
|
|
423
502
|
return _SOURCE_IS_STORED.get(source, False)
|
|
424
503
|
|
|
425
504
|
|
|
@@ -435,6 +514,8 @@ _SOURCE_IS_STORED: Final[dict[str, bool]] = {
|
|
|
435
514
|
"default_expr_unsupported": False,
|
|
436
515
|
"default_volatile_unresolved": False,
|
|
437
516
|
"default_pending": False,
|
|
517
|
+
"default_deferred": False,
|
|
518
|
+
"default_override": True,
|
|
438
519
|
}
|
|
439
520
|
|
|
440
521
|
|
|
@@ -450,6 +531,10 @@ class DocFlags(IntFlag):
|
|
|
450
531
|
# `chs_preview_batch`'s `export_format` for no export (`CHS_EXPORT_NONE`).
|
|
451
532
|
EXPORT_NONE: Final = -1
|
|
452
533
|
|
|
534
|
+
# The code a declined row, outcome or verdict carries (`CHS_CODE_DECLINED`), outside
|
|
535
|
+
# ClickHouse's code table.
|
|
536
|
+
CODE_DECLINED: Final = -2
|
|
537
|
+
|
|
453
538
|
# Every enum the description defines, by its own name, and the Python type that
|
|
454
539
|
# spells it: rule r3's tests reach every one from here, so a new enum is covered
|
|
455
540
|
# without a hand-kept list.
|
|
@@ -463,10 +548,13 @@ DESCRIBED_VOCABULARIES: Final[dict[str, type]] = {
|
|
|
463
548
|
"batch_outcome": Outcome,
|
|
464
549
|
"filter_outcome": FilterOutcome,
|
|
465
550
|
"filter_verdict": Verdict,
|
|
551
|
+
"refusal_site": RefusalSite,
|
|
466
552
|
"discover_query_param": DiscoverQueryParam,
|
|
467
553
|
"default_kind": DefaultKind,
|
|
554
|
+
"default_support": DefaultSupport,
|
|
468
555
|
"declined_tier": DeclinedTier,
|
|
469
556
|
"declined_layer": DeclinedLayer,
|
|
557
|
+
"posture": Posture,
|
|
470
558
|
}
|
|
471
559
|
|
|
472
560
|
|
|
@@ -32,10 +32,13 @@ from ._abi2._vocab import (
|
|
|
32
32
|
DeclinedLayer,
|
|
33
33
|
DeclinedTier,
|
|
34
34
|
DefaultKind,
|
|
35
|
+
DefaultSupport,
|
|
35
36
|
FilterOutcome,
|
|
36
37
|
MergeReason,
|
|
37
38
|
Outcome,
|
|
39
|
+
Posture,
|
|
38
40
|
Reason,
|
|
41
|
+
RefusalSite,
|
|
39
42
|
Source,
|
|
40
43
|
Verdict,
|
|
41
44
|
)
|
|
@@ -291,6 +294,20 @@ def _spans(obj: Mapping[str, Any], key: str, where: str) -> tuple[Span, ...]:
|
|
|
291
294
|
return _objects(obj, key, where, _span)
|
|
292
295
|
|
|
293
296
|
|
|
297
|
+
def _row_spans(obj: Mapping[str, Any], key: str, where: str) -> tuple[Span | None, ...]:
|
|
298
|
+
"""`row_spans`: one entry per row, a span or null for a row not exported."""
|
|
299
|
+
out: list[Span | None] = []
|
|
300
|
+
for i, item in enumerate(_list(obj, key, where)):
|
|
301
|
+
out.append(None if item is None else _span(_obj(item, where, key), f"{where}.{key}[{i}]"))
|
|
302
|
+
return tuple(out)
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
def _refused_at(obj: Mapping[str, Any], where: str) -> RefusalSite | None:
|
|
306
|
+
# An unlisted site is its unknown(n): kept, never a failure (rule r3).
|
|
307
|
+
value = _opt_text(obj, "refused_at", where)
|
|
308
|
+
return None if value is None else RefusalSite.of(value)
|
|
309
|
+
|
|
310
|
+
|
|
294
311
|
def _value(obj: dict[str, Any], where: str) -> Value:
|
|
295
312
|
# An unlisted src is its unknown(n): kept, never a failure (rule r3), and
|
|
296
313
|
# not stored until the description says what one reports. An ABSENT src is
|
|
@@ -353,7 +370,7 @@ def _int_list(obj: Mapping[str, Any], key: str, where: str) -> tuple[int, ...] |
|
|
|
353
370
|
def _at_merge(obj: dict[str, Any], where: str) -> AtMergeEntry:
|
|
354
371
|
# An unlisted reason is its unknown(n): kept, never a failure (rule r3).
|
|
355
372
|
return AtMergeEntry(
|
|
356
|
-
|
|
373
|
+
part_row=_int(obj, "part_row", where),
|
|
357
374
|
reason=MergeReason.of(_text(obj, "reason", where)),
|
|
358
375
|
column=_bytes_or_none(obj, "column", where),
|
|
359
376
|
stored=_bytes_or_none(obj, "stored", where),
|
|
@@ -386,14 +403,17 @@ def decode_row(obj: Mapping[str, Any], where: str = "row") -> RowResult:
|
|
|
386
403
|
outcome=Outcome.of(_text(obj, "outcome", where)),
|
|
387
404
|
err_code=_int(obj, "code", where),
|
|
388
405
|
err_msg=_bytes(obj, "err", where),
|
|
406
|
+
reason=_opt_text(obj, "reason", where),
|
|
407
|
+
refused_at=_refused_at(obj, where),
|
|
408
|
+
refused_row=_opt_u64(obj, "refused_row", where),
|
|
389
409
|
columns=columns,
|
|
390
410
|
values=tuple(v for v in columns if v.is_stored),
|
|
391
411
|
transformed=_objects(obj, "transformed", where, _transform),
|
|
392
412
|
unknown_fields=_name_list(obj, "unknown_fields", where),
|
|
393
|
-
unsupported_settings=_name_list(obj, "unsupported_settings", where),
|
|
394
413
|
computed=_objects(obj, "computed", where, _computed),
|
|
395
414
|
verdict=None if verdict is None else Verdict.of(verdict),
|
|
396
415
|
verdict_code=_int(obj, "verdict_code", where),
|
|
416
|
+
verdict_reason=_opt_text(obj, "verdict_reason", where),
|
|
397
417
|
verdict_err=_bytes(obj, "verdict_err", where),
|
|
398
418
|
partition_id=partition,
|
|
399
419
|
input_span=_opt_span(obj, "input_span", where),
|
|
@@ -427,7 +447,10 @@ def decode_batch(raw: bytes, export: bytes | None) -> BatchResult:
|
|
|
427
447
|
obj = _obj(strict_loads(raw, where), where)
|
|
428
448
|
framing = obj.get("framing")
|
|
429
449
|
engine_rows = None if obj.get("engine_rows") is None else _engine_rows(obj, where)
|
|
430
|
-
spans = None if obj.get("row_spans") is None else
|
|
450
|
+
spans = None if obj.get("row_spans") is None else _row_spans(obj, "row_spans", where)
|
|
451
|
+
export_columns = (
|
|
452
|
+
None if obj.get("export_columns") is None else _name_list(obj, "export_columns", where)
|
|
453
|
+
)
|
|
431
454
|
export_declined = _bytes(obj, "export_declined", where)
|
|
432
455
|
if export_declined:
|
|
433
456
|
# A declined export has no payload and no spans, whatever buffer the call
|
|
@@ -439,6 +462,9 @@ def decode_batch(raw: bytes, export: bytes | None) -> BatchResult:
|
|
|
439
462
|
outcome=Outcome.of(_text(obj, "outcome", where)),
|
|
440
463
|
err_code=_int(obj, "code", where),
|
|
441
464
|
err_msg=_bytes(obj, "err", where),
|
|
465
|
+
reason=_opt_text(obj, "reason", where),
|
|
466
|
+
refused_at=_refused_at(obj, where),
|
|
467
|
+
refused_row=_opt_u64(obj, "refused_row", where),
|
|
442
468
|
rows=_objects(obj, "rows", where, decode_row),
|
|
443
469
|
rows_read=_u64(obj, "rows_read", where),
|
|
444
470
|
rows_skipped=_u64(obj, "rows_skipped", where),
|
|
@@ -446,7 +472,9 @@ def decode_batch(raw: bytes, export: bytes | None) -> BatchResult:
|
|
|
446
472
|
engine_rows=engine_rows,
|
|
447
473
|
payload=export,
|
|
448
474
|
spans=spans,
|
|
475
|
+
export_columns=export_columns,
|
|
449
476
|
export_declined=export_declined,
|
|
477
|
+
export_declined_reason=_opt_text(obj, "export_declined_reason", where),
|
|
450
478
|
rows_passed=_u64(obj, "rows_passed", where),
|
|
451
479
|
rows_cut=_u64(obj, "rows_cut", where),
|
|
452
480
|
partition_count=_opt_u64(obj, "partition_count", where),
|
|
@@ -467,6 +495,7 @@ def _filter_row_error(obj: dict[str, Any], where: str) -> FilterRowError:
|
|
|
467
495
|
return FilterRowError(
|
|
468
496
|
row=_int(obj, "row", where),
|
|
469
497
|
code=_int(obj, "code", where),
|
|
498
|
+
reason=_opt_text(obj, "reason", where),
|
|
470
499
|
msg=_bytes(obj, "err", where),
|
|
471
500
|
)
|
|
472
501
|
|
|
@@ -479,6 +508,9 @@ def decode_filter_result(raw: bytes) -> FilterResult:
|
|
|
479
508
|
outcome=FilterOutcome.of(_text(obj, "outcome", where)),
|
|
480
509
|
err_code=_int(obj, "code", where),
|
|
481
510
|
err_msg=_bytes(obj, "err", where),
|
|
511
|
+
reason=_opt_text(obj, "reason", where),
|
|
512
|
+
refused_at=_refused_at(obj, where),
|
|
513
|
+
refused_row=_opt_u64(obj, "refused_row", where),
|
|
482
514
|
rows_read=_u64(obj, "rows_read", where),
|
|
483
515
|
unsupported_settings=_name_list(obj, "unsupported_settings", where),
|
|
484
516
|
verdicts=tuple(Verdict.of(c) for c in verdicts),
|
|
@@ -487,12 +519,17 @@ def decode_filter_result(raw: bytes) -> FilterResult:
|
|
|
487
519
|
|
|
488
520
|
|
|
489
521
|
def _column(obj: dict[str, Any], where: str) -> Column:
|
|
490
|
-
# An unlisted default_kind is its unknown(n): kept, never a
|
|
522
|
+
# An unlisted default_kind or default_support is its unknown(n): kept, never a
|
|
523
|
+
# failure (rule r3).
|
|
524
|
+
support = _opt_text(obj, "default_support", where)
|
|
491
525
|
return Column(
|
|
492
526
|
name=_name(obj, "name", where),
|
|
493
527
|
type=_bytes(obj, "type", where),
|
|
494
528
|
default_kind=DefaultKind.of(_text(obj, "default_kind", where)),
|
|
495
529
|
default_expr=_bytes(obj, "default_expression", where),
|
|
530
|
+
default_support=None if support is None else DefaultSupport.of(support),
|
|
531
|
+
default_support_reason=_opt_text(obj, "default_support_reason", where),
|
|
532
|
+
reads=None if obj.get("reads") is None else _name_list(obj, "reads", where),
|
|
496
533
|
)
|
|
497
534
|
|
|
498
535
|
|
|
@@ -506,6 +543,14 @@ def _string_map(obj: Mapping[str, Any], key: str, where: str) -> dict[str, str]
|
|
|
506
543
|
inner = _obj(value, where, key)
|
|
507
544
|
out: dict[str, str] = {}
|
|
508
545
|
for name, item in inner.items():
|
|
546
|
+
if isinstance(item, dict):
|
|
547
|
+
# The object form of a value that was not UTF-8: its bytes, spelled
|
|
548
|
+
# with surrogateescape (the spelling the input side takes back).
|
|
549
|
+
if set(item) != {"b64"}:
|
|
550
|
+
raise _wrong(f"{where}.{key}", name, "a string or a b64 object", item)
|
|
551
|
+
item = _decode_b64(item["b64"], f"{where}.{key}", name).decode(
|
|
552
|
+
"utf-8", "surrogateescape"
|
|
553
|
+
)
|
|
509
554
|
if not isinstance(item, str):
|
|
510
555
|
raise _wrong(f"{where}.{key}", name, "a string", item)
|
|
511
556
|
out[name] = item
|
|
@@ -543,6 +588,7 @@ def decode_schema_description(raw: bytes) -> SchemaDescription:
|
|
|
543
588
|
# decodes exactly as it did before servers existed.
|
|
544
589
|
server = obj.get("server")
|
|
545
590
|
replicated = obj.get("replicated")
|
|
591
|
+
posture = _opt_text(obj, "posture", where)
|
|
546
592
|
return SchemaDescription(
|
|
547
593
|
columns=_objects(obj, "columns", where, _column),
|
|
548
594
|
server=None
|
|
@@ -557,6 +603,7 @@ def decode_schema_description(raw: bytes) -> SchemaDescription:
|
|
|
557
603
|
filter_declined_settings=_objects(
|
|
558
604
|
obj, "filter_declined_settings", where, _declined_setting
|
|
559
605
|
),
|
|
606
|
+
posture=None if posture is None else Posture.of(posture),
|
|
560
607
|
)
|
|
561
608
|
|
|
562
609
|
|