Tables and Columns as Workspace Outputs
Show the whole prompt
Read https://intentius.io/chant/lexicons/sql/workspace-outputs/.
In this chant workspace, add a link in `chant.workspace.json` from the member I name to each table or column it reads in the sql member, by its output name such as `public.orders.customer_id`.
Run `npx chant workspace check` and `npx chant workspace graph`, fix each link it reports missing or unresolved, and open a pull request with the declaration.
Never deploy to a real cloud account or shared environment (with `chant run`, `chant components` or a platform's own CLI), approve (a pull request review, `chant approve` or `chant run approve`), override a policy denial (`chant approve policy-override`), or merge; never cut or publish a release (`chant release cut --yes` or `chant release publish`), push or delete a `ci/*` tag (`chant ci tick` pushes them), or change the value of an existing flag; never touch `.chant/allowed_signers` or `chant/lifecycle`.Optional: hand this page to your coding agent
Read https://intentius.io/chant/lexicons/sql/workspace-outputs/.In this chant workspace, add a link in `chant.workspace.json` from the member I name to each table or column it reads in the sql member, by its output name such as `public.orders.customer_id`.Run `npx chant workspace check` and `npx chant workspace graph`, fix each link it reports missing or unresolved, and open a pull request with the declaration.Never deploy to a real cloud account or shared environment (with `chant run`, `chant components` or a platform's own CLI), approve (a pull request review, `chant approve` or `chant run approve`), override a policy denial (`chant approve policy-override`), or merge; never cut or publish a release (`chant release cut --yes` or `chant release publish`), push or delete a `ci/*` tag (`chant ci tick` pushes them), or change the value of an existing flag; never touch `.chant/allowed_signers` or `chant/lifecycle`.In a chant workspace, a member that declares sql tables exposes each table and view, and each of their columns, as an output. Another member links to one the way it links to any output, and chant workspace check fails when the column is gone. Nobody writes output(...) for these. They were added in #3931.
Output names
Section titled “Output names”| Dialect | Table or view | Column |
|---|---|---|
| Postgres | <schema>.<table> | <schema>.<table>.<column> |
| ClickHouse | <database>.<table> | <database>.<table>.<column> |
An unqualified Postgres name is in public, and an unqualified ClickHouse name in default.
Names are written unquoted, in the case the dialect keeps:
- Postgres folds an unquoted identifier to lower case and keeps a quoted one as written.
CREATE TABLE OrdersandCREATE TABLE ordersare bothpublic.orders, whileCREATE TABLE "Orders"ispublic.Orders, a different output. A quoted name appears in the output without its quotes. - ClickHouse is case-sensitive, so a name is kept as written, quoted or not.
A link that differs from an output only in case is told the name it probably meant, since links match exactly.
The names come from the declarations in source, never from a profile’s, environment’s or tenant’s rendering. A member that renames its database or schema per environment at deploy time exposes the same outputs everywhere.
Views and materialized views are outputs, named like tables. Their columns are outputs too:
- a declared column list,
CREATE VIEW totals (customer_id, total) AS ..., gives the columns; - otherwise each item of the select list gives one, by its alias or the column it reads (
SELECT customer_id, sum(amount) AS totalgivescustomer_idandtotal); - a
*, or an expression with no alias, can’t be named without a server. The view’s columns are then incomplete, and a link to one is reported as unresolved rather than missing.
A worked example
Section titled “A worked example”A workspace with a Postgres member db and an app that reads orders.customer_id:
{ "name": "shop", "schema": 1, "members": [ { "name": "db", "dir": "db", "kind": "chant" }, { "name": "app", "dir": "app", "kind": "other", "because": "the service that reads the database", "links": [{ "member": "db", "output": "public.orders.customer_id" }] } ]}import { table } from "@intentius/chant-lexicon-sql/postgres";
export const orders = table` CREATE TABLE orders ( id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, customer_id bigint NOT NULL, amount numeric(12, 2) NOT NULL )`;db exposes public.orders, public.orders.id, public.orders.customer_id and public.orders.amount, and the link resolves. Drop customer_id and the check fails, naming the consumer:
WSP093 app's link to db output public.orders.customer_id does not resolve: db has no output public.orders.customer_id; its outputs: public.orders, public.orders.amount, public.orders.idRename it and leave a rename hint, and the message says where it went:
buyer_id bigint NOT NULL, -- previously: customer_iddb has no output public.orders.customer_id; it was renamed to public.orders.buyer_id, so link to that insteadThe same workspace with a ClickHouse member links to analytics.events.user_id for a table declared as ${analytics}.events.
How they are read
Section titled “How they are read”chant workspace check never runs a member’s code. It folds the member’s TypeScript the way chant build does under its sandbox: a file whose table and view templates are plain text and interpolations of other declarations folds to the same tables a build makes. The member’s plain .sql files are read too.
A file that imports the sql lexicon and does not fold, such as one that reads process.env to choose a table’s name, is not run. Its tables are a gap: the member’s outputs are marked incomplete, and a link to a name the check did not find is unresolved (WSP094, info) rather than missing. Under chant workspace check --at, the revision’s files are not on disk to fold, so a sql member’s outputs are a gap there too.
chant workspace graph lists the outputs in its exports, from each member’s chant graph --format ir, with a renamed output’s old names in previously.