ID |
|
|---|---|
Status |
Backlog |
Bucket |
dx |
Priority |
5 |
Theme |
tooling |
Created |
2026-08-20 |
Updated |
2026-08-20 |
The meta_ family states its rows as VALUES views, which take no constraints
The meta_ family is the schema describing itself: the family roster, the placement of the relations
no prefix covers, and the census that closes both against what the store actually declares. Two of
its three relations are authored rosters, and both are stated as CREATE VIEW ... AS VALUES (...).
A view takes no constraints. No primary key, no NOT NULL, no CHECK, and column types inferred
from the literals rather than declared, which is why meta_prefixless_relation writes
CAST(NULL AS VARCHAR) to obtain a nullable column. For a roster that other code joins against and
that build gates read, those are the constraints one would most want.
This item asks whether the family should be tables with constraints, populated by INSERT in the
same DDL file, and converts them if the answer is yes.
What the current form buys, stated fairly
The DDL header makes the claim: the rows are "authored as constant rows stated as views, so the description is versioned with the DDL it describes and can never be refreshed apart from it".
That is a real property and it is stronger than it first looks. A view’s rows are not data, they are
part of the definition, so nothing can UPDATE or DELETE them, no run can half-populate them, and
there is no question of whether a load step ran. The description cannot drift from the file because
there is no separate thing to drift.
A table populated by an INSERT in the same file keeps most of that. The rows still ship with the
DDL, the store’s boot executes the file’s statements in order, and a fresh store therefore always
has them. What it gives up is only the guarantee against runtime mutation, and the store’s writers
are all enumerated: none of them touches meta_. So the loss is a hypothetical, and the gain is a
key, three `NOT NULL`s and declared types.
Why it is being asked now
R742 adds a fourth meta_ relation, meta_materialize, a registry pairing a view with the table its
rows are materialized into. Its reason column has to be NOT NULL: the registry is where that item
moves "why this is not simply a view" from a per-table comment, and a registration that cannot say it
is not a registration. Under the current family form there is no way to require it, and the first
draft of R742 proposed a build gate instead, which is the wrong instrument and a clean symptom of the
missing constraint.
R742 therefore lands meta_materialize as a constrained table and leaves the older three alone,
recording the divergence as a tracked simplification rather than silently forking the family. This
item is what converges it.
What conversion touches
-
meta_familyandmeta_prefixless_relationbecome tables with keys,NOT NULLwhere the column is required, and anINSERTcarrying the rows they state today.meta_prefixless_relationloses itsCAST(NULL AS VARCHAR)in favour of a declared nullable column. -
meta_relation_familystays a view. It is not a roster; it is the census that joins the rosters againstINFORMATION_SCHEMA.TABLES, and a census must be evaluated rather than stored. -
FactSchemaGateTest.everyRelationLeadsWithItsPartitionDimensionwalks every base relation carrying a primary key and expectsgraph_nameunless the name matchessql_,jvm_,java_or an enumeratedstore_case. A keyedmeta_table falls into theelseand is reported. The gate needs ameta_arm expecting the relation’s own key, which is in keeping with its own javadoc thatstore_"answers the question per relation rather than per prefix". R742 opens this hole with the first keyedmeta_relation; this item either inherits the arm it added or adds it. -
The DDL header’s
meta_charter, which states theVALUESrationale quoted above and would need to state the new one. -
Nothing in Java, if jOOQ’s generated types are unchanged in name. Worth confirming rather than assuming: codegen reads a live store, and a view and a table both generate a
TableImpl, but a table additionally generates key metadata and may render column types differently where the view’s were inferred.
What would make the answer no
Worth stating so the item can be closed rather than lingering. If a meta_ roster ever needs to be
read before its INSERT could have run, the view form is not a preference but a requirement. The
store’s boot executes statements in file order and the meta_ block is at the tail, so nothing today
is in that position; a future relation that participates in the boot itself might be.
The other honest no is churn: three relations, a gate arm, a header paragraph and a codegen check, against a benefit that is real but not urgent for the two existing rosters, whose rows are short, stable and reviewed in the diff. That is why this is filed rather than folded into R742.