rowtype-yoga / rowtype-yoga/purescript-yoga-postgres
Expose the set of columns a query references (for dead-column analysis)
Nobody has claimed this yet.
- Dominant language
- PureScript
- Stars
- 1
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
What I'm after
A way to recover, from a finished Q, the set of columns the query references across all clauses — so a consumer can compute dead = schema.columns ∖ reached (dead-column / unused-column analysis).
I'm building this on top of yoga-postgres in notothenia (schema cartography). The dual already works for free: drop a column from the schema type and any query that reached it fails to compile at its call site, straight out of ResolveColumn. This issue is about the other direction — "which columns does no query touch?"
The gap
A finished Q tables result params stage = Q { sql, values } doesn't retain the reference set (line refs against 35e8250):
- The clause symbols (
select @"…",where_ @"…") are reflected into the runtimesqlstring and discarded at the type level. result(ParseSelect) is keyed by output alias — projection reach only, and lossy underAS.params(ParseWhere) is keyed by param name ($x) typed to the compared column — the column identity is gone.
So the referenced-column set isn't recoverable from the public type, even though the parser plainly computes it while resolving.
The keystone
Every column reference in every clause funnels through a single class — ResolveColumn word tables typ (Schema.purs:689) — after the keyword/function/param/literal exclusions have fired (SELECT via ParseSelectGo/ParseSelectHandleAS; WHERE via the FlushWhereWord* chain, first ResolveColumn at :1639; ORDER/GROUP/HAVING likewise). Anything hung at that point inherits the classification for free and stays correct as the parser grows.
Two designs (full writeup + line citations + edge cases)
📄 https://github.com/afcondon/notothenia/blob/main/docs/rung3-reach-ask-yoga.md
In short:
- Option A (my recommendation) — add a
reached :: Row Typeparameter toQ, fed at theResolveColumnchokepoint, canonically keyed"<table>.<column>". Correct-by-construction (reuses your own exclusions); cost is a kind change toQ(putreachedlast so inferred call sites are unaffected and only explicitQannotations gain a param) and threading an accumulator through theParse*Go/FlushWhereWordchains. - Option B — retain the clause symbols on
Qand add a standaloneReferencedColumns clauses tables :: Row Typecollector that re-walks them reusing the existingSkipSpaces/ExtractWord/SplitOnDot/ResolveColumnprimitives. Smaller blast radius on the parser chains, but it has to re-derive token classification, which risks drifting from the real parser (aggregates,AS, functions).
Edge cases I'd want your call on: SELECT * / selectAll, aggregate args (count(id)), AS aliases (record the underlying column, not the alias), JOIN ON columns, and "<table>.<column>" as the canonical key.
Offer
Happy to write the PR for whichever option you prefer — you own the parser and know its delicate spots, so I'd rather get your read on the approach first. Also genuinely open to "this belongs in your layer, not yoga's" if that's your call.
(Discussions are off on this repo, so I filed it as an issue — feel free to convert if you turn them on.)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read docs/rung3-reach-ask-yoga.md first, then inspect Schema.purs at ResolveColumn and the ParseSelectGo, ParseSelectHandleAS, and FlushWhereWord chains. Get a maintainer decision between the two designs and the listed edge cases before starting. Done means the chosen approach exposes the referenced-column set while preserving the parser's existing classification behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- sql
- Domain
- databases
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100