You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 3c72132
Browse filesBrowse the repository at this point in the historyBrowse files
Time travel served a foo_v_N variant's constraint records under foo, still
owned by foo_v_N, so ConstraintContract refused the table and AT (VERSION ..)
on any versioned table with records failed (blocked 0.45.1). Variant records
are now re-owned to the served name (self-referencing foreign keys too), and
statistics / required filters carry through versions (the base's, restricted
to the variant's columns, when the variant declares none).
Serving (every path goes through TableInfoSerializer.served, plus provider
catalog_contents tables via MetadataCollections.merge):
- Nullability is rewritten, not checked: a field is served non-nullable
exactly when a NOT_NULL/PRIMARY_KEY record names it (ordinary STRUCTs
recursed, row id and logical-type storage untouched).
- The extension's ATTACH rules are applied with table, constraint id and path
in the message: one-component schema paths, duplicate declared names,
a second PRIMARY KEY, unresolvable or nested non-NOT_NULL paths, FK shape
(same schema, MATCH SIMPLE, NO_ACTION/RESTRICT), FK targets resolved across
the catalog, the numeric-comparison CHECK grammar, size limits.
- Generated columns: VIRTUAL, nullable, BOOLEAN/signed int/VARCHAR and the
extension's scalar grammar; legacy generated_expression is translated.
New public CatalogColumns.virtualGenerated(..).
API:
- CatalogProfiles: public encode/decode/select/negotiate/clientOffer helpers.
- CatalogInterface#catalogCapabilities(attachId, request) and
ExtraCatalog#withCapabilities; hosted CREATE TABLE forwards constraint
definitions when create+enforce+read were selected. NOT NULL / logical-type
refusals moved into InMemoryCatalog (which still enforces nothing).
- viewCreate: the 9-arg default delegates to the 6-arg, which delegates to a
restored @deprecated 5-arg (v0.44), so an override at any level is reached.
- MacroInfo.of(Macro); registerMacro refuses expression defaults at startup.
- Legacy CatalogTable constraint builders are @deprecated; ConstraintRecord
builder refuses multi-component schemas, nested non-NOT_NULL paths and
cross-schema FKs early; ConstraintRecord.decodeAll for clients.
- examples/docs pin bumped to 0.45.1.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/catalog_publication.md
+14Lines changed: 14 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,3 +23,17 @@ RPC 0.33.2 includes the scalar `DICT_INT16_UTF8` record fix required by macro an
23
23
constraint metadata. Release qualification disables the composite source override
24
24
and resolves that published dependency from Maven Central. No local repository
25
25
fallback is part of the SDK build.
26
+
27
+
## Constraints, nullability, generated columns and macros (vgi.v3)
28
+
29
+
Constraints are canonical `ConstraintInfo` records the worker attests: build them with `ConstraintRecord.builder(schema, table, id)` (`notNull`, `primaryKey`, `unique`, `check`, `foreignKey`), state `ENFORCED` + `ALL_ROWS`, and attach them with `CatalogTable.Builder#constraints(records, revision)`. The pre-v3 `primaryKey`/`unique`/`check`/`foreignKeys` builders are `@Deprecated` and refused when the table is served. Every catalog path (main, auxiliary, hosted) advertises `vgi.constraint.records.read.v1` + `vgi.expression.duckdb.scalar.v1` and selects what the client offers automatically.
30
+
31
+
Before serving a table the framework applies the rules DuckDB applies at ATTACH and refuses, naming the table, constraint id and column path: records owned by another table or a multi-component schema path, duplicate ids or declared names (case-insensitive), a second PRIMARY KEY, column paths that do not resolve (nested paths only on NOT_NULL, through ordinary STRUCTs), foreign keys to another schema, with an action other than NO_ACTION/RESTRICT or whose referenced key the catalog does not declare, and CHECK expressions outside the one-numeric-comparison grammar (`budget >= 0`: unqualified signed-integer/float columns and numeric literals).
32
+
33
+
Nullability needs no author work: the served Arrow schema is rewritten so a field is non-nullable exactly when a NOT_NULL/PRIMARY_KEY record names it (descending through ordinary STRUCTs; the row-id column and logical-type storage are untouched). A non-nullable field no record names is served nullable.
34
+
35
+
Generated columns: `CatalogColumns.virtualGenerated(name, type, sql, schemaPath)` builds a VIRTUAL column (nullable; BOOLEAN, signed integer or VARCHAR; the extension's deterministic scalar grammar, no division or float literals). Legacy `generated_expression` metadata is translated to that form when served.
36
+
37
+
Capabilities: `CatalogProfiles` encodes, decodes and negotiates profiles (`negotiate`, `select`, `clientOffer`, `defaultClientOffer`). A hosted catalog that enforces constraints on its own write paths selects `vgi.constraint.create.v1` + `vgi.constraint.enforce.v1` from `CatalogInterface#catalogCapabilities`; only then does `CREATE TABLE` with constraint definitions reach its `tableCreate`. Auxiliary catalogs use `ExtraCatalog#withCapabilities`. `InMemoryCatalog` stores no rows and enforces nothing, so it refuses constrained, NOT NULL, logical-type and generated columns on `CREATE TABLE`.
38
+
39
+
Macros: hosted catalogs build `MacroInfo` from a `Macro` descriptor with `MacroInfo.of(macro)`. Parameter defaults are literal values only (`NULL`, booleans, numbers, `'strings'`); an expression default such as `current_date` is refused by `registerMacro` at startup.
0 commit comments