QueryForge v0.0.4 — let your users ask your database anything, safely #1
awsaman-ai
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Every text-to-SQL tool has the same hole in it: you cannot check what comes back.
You ask a model for SQL, and it hands you a statement that is only probably right. It may have invented a column. It may have quietly widened a filter. It may have dropped the one condition that kept a user inside their own tenant. Short of reading every query by hand — or running it and finding out — you have no way to know which.
QueryForge closes that hole by never letting the model near a query string.
How
The model fills in a form. Not prose, not SQL — a typed Query AST, constrained to a vocabulary your JSON config registers. Everything after that is ordinary deterministic Go you can test offline:
Everything that has to be guaranteed lives on the right-hand side, where it can be proven rather than prompted.
What that actually buys you
returnable: falseis enforced on the default projection too, not only on an explicitselect.A OR Bbecomesscope AND (A OR B)— and the model is never told the column exists.Try it without installing anything
The config builder runs entirely in your browser — every option the loader knows, as a form, validated live against the same rules, with the finished JSON a click away. No server, no upload, no analytics, and it works offline once loaded.
Then:
Core is standard library only. Apache-2.0. Read-only by design: every output is a
SELECTor afind, and the library never connects to your database — it hands you the query, running it stays yours.📖 Docs · 🧩 Configuration reference · 📦 pkg.go.dev
Where it is today
v0.0.4. Postgres SQL and MongoDB ship now. A backend is a generator over the AST, so adding one touches neither the planner, nor the validator, nor the prompt — that seam is the whole point of the design.
Models are a config change, never a code change: any OpenAI-compatible endpoint (Gemini, Groq, local Ollama) or the native Anthropic Messages API, with an ordered fallback chain so a rate limit on one provider transparently falls through to the next.
129 tests, all offline — the engine is exercised through a stub provider, so the suite needs no API key and burns no quota. CI runs them on Go 1.25 and 1.26 with the race detector, plus golangci-lint.
What I'd rather say out loud
It only answers what your config anticipated. This is not a replacement for a data analyst, and it will not explore a schema it was never told about. It is a way to put a natural-language filter box in front of your users and still be able to sleep.
And the bugs are public.
bugs.csvis in the repo with every defect found during adversarial QA and how it was fixed — including areturnable: falseleak on the default projection, and a genuinely nasty one where enabling JSON mode on a provider made its output less parseable, not more.What would help most
I'd rather hear about the awkward cases than the easy ones.
Questions of any size are welcome in Q&A; nothing is too basic. If you'd rather open an issue, that works too.
All reactions