Catch a layer query reading a column the source fetch does not request #98
Labels
No labels
blocked
claude-wip
map-report
map:is
map:se
needs-review
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
art/ismap#98
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A layer query can read a column the source fetch does not request, and nothing catches it until someone imports on a clean machine. This shipped once already, in #79.
What happened
#79gave Poland'splacesa built-up footprint, anchored with:The PRNG download 1 160 lines earlier asked the WFS for:
The server honours that list strictly, so
pl_prng_m1stages with three columns and the layer query dies:The column history explains how it got past review:
1d9cbf4(#29) originally fetchedNAZWAGLOWNA,SKALA_WYSWIETLANIA,RODZAJOBIEKTU,STATUSNAZWY,msGeometry.f27750e(#29) narrowed it to three columns — correct at the time, both dropped columns were unused.#79reintroduced a dependency onRODZAJOBIEKTUwithout restoring it toPROPERTYNAME.So the query was written against a database whose staging table predated the narrowing. It was verified honestly and the numbers were right; the config simply could not reproduce them. Fixed in
5514a61by putting the column back inPROPERTYNAME.Note this is not the stale-file problem —
fetch.gorecords the URL in the.fetchmetasidecar and re-downloads when it changes, and staging tables are rebuilt from the file on every run. Both of those work. The gap is that nothing connects what a query reads to what the fetch provides.Why it is worth a guard
The failure is invisible to review: the broken predicate and the unchanged URL are a thousand lines apart in the same file, and every local signal says fine. It only surfaces on a machine that fetches clean — which, for a project where the expensive sources are fetched once and kept, is rarely the machine doing the work. The same shape applies to any narrowing of a source's column set, not just WFS
PROPERTYNAME.Options, cheapest first
PREPAREevery query in a check mode. An-check-queriesflag that runsPREPAREon each staging and layer query against the live DB and discards it. Postgres resolves column references without executing, so this is near-free and catches unknown columns in every layer at once. Limitation: it validates against whatever is staged now, so it would not have caught this on the author's machine — but it catches it in CI or on any clean box, and it catches typos everywhere else.Static
PROPERTYNAMEcross-check. For a download whose URL carriesPROPERTYNAME=, parse the list and check it against the<table>.<column>references in queries whosestaging:includes the table loaded from that path. Narrow, but it is exactly this bug class and needs no database at all.Column-set assertion on staging. Let a staging entry declare the columns it must produce, and fail the build if the loaded file lacks one. More typing per source, but it turns a silent absence into a named error at the point of loading.
(1) plus (2) seems like the useful pair — (1) for breadth, (2) because it is the only one that would have failed on the author's box.
Immediate mitigation, no code: when narrowing a source's column list, grep the config for the removed column names before committing.
Options 1 and 2 sound like a reasonable pair.
Don't implement this issue until #129 lands because that issue will provide a nicer interface for implementing this.
Result is in #148 — #148; the review note is the PR description.