Prove, don't guess: why an AI SQL assistant should read your real schema instead of hallucinating it
Why LLMs invent table and column names, how grounding in a real schema and query plans yields correct SQL, and how to spot an assistant that checks.
Ask a language model to write a query against “the orders table” and it will happily oblige — with a column called order_date, a foreign key to customers, and a status field that reads 'completed'. Confident, plausible, and quite possibly wrong. Your table might call that column created_at, your foreign key might point at accounts, and your status enum might use 3 instead of a word.
This is the core problem with using AI to write SQL: a model that hasn’t seen your database is guessing at its structure. Sometimes it guesses right. When it doesn’t, you get a query that looks correct, runs without complaint against the model’s imagination, and fails — or worse, silently returns the wrong rows — against your real database.
The fix is a principle worth naming: prove, don’t guess. An AI SQL assistant should base its answers on your actual schema, real values, and query plans — not on what a table “probably” looks like.
Disclosure: I work on SQL Sage, which I’ll use later as a concrete example. The principle below holds regardless of which tool you use.
Why do LLMs hallucinate table and column names?
Because a language model generates text by predicting what is statistically likely, not by looking anything up. When you ask it for SQL, it draws on patterns from the enormous amount of code it was trained on. Across that training data, an orders table very commonly has an order_date column, so the model predicts order_date. That is a reasonable prior. It is not a fact about your database.
The model has no connection to your schema unless something gives it one. Left to itself, it fills the gaps with the most common pattern it has seen. The industry term for this is hallucination: the model produces output that is fluent and confident but not grounded in any real source. For prose, a hallucination is an embarrassing wrong fact. For SQL, it’s a query that references a column that doesn’t exist, joins on the wrong key, or assumes a data type your column doesn’t have.
The failure is particularly sneaky because SQL hallucinations are plausible. The model isn’t inventing nonsense — it’s inventing something that would be reasonable in a generic database. That makes the mistakes hard to spot by eye, because they look exactly like correct SQL for some database, just not yours.
What does it mean to “ground” an LLM in a database schema?
Grounding means giving the model the real facts before it answers, so its output is constrained by your database instead of by statistical guesswork.
For SQL, the facts that matter are:
- The schema — actual table names, column names, data types, keys, and relationships, read from the live database.
- Real values where they matter — for example, the distinct values a status column actually holds, so the model writes
WHERE status = 'shipped'only if'shipped'is a value that exists. - Query plans — how the database says it will execute a query, which exposes whether a join or filter behaves the way the model assumed.
When the model has these, it is no longer predicting your schema; it is reading it. The difference shows up immediately. A grounded assistant writes created_at because your column is called created_at, not because order_date is a common name. It joins on the key that actually exists. It uses the enum values your data actually contains. The guesswork is replaced by lookup.
This is the same idea as retrieval-augmented generation (RAG) in other domains: don’t ask the model to recall a fact it may not have — give it the fact and ask it to reason. For databases, the “retrieval” is introspection of the live schema and, when needed, the real distribution of values and the execution plan.
Why does grounding produce more correct SQL?
Because most SQL errors from AI aren’t logic errors — they’re reference errors. The model understood what you wanted; it just addressed it to the wrong names. Give it the right names and a whole class of mistakes disappears.
Grounding helps at three levels:
- Identifiers. Correct table and column names, spelled and cased as they exist, mean the query references things that are really there.
- Types and values. Knowing a column is an
integerenum, not a text status, changes theWHEREclause the model writes. Knowing the real set of values prevents filtering on a string that never appears. - Behavior. A query plan reveals whether a join fans out rows, whether an index is used, whether a filter is applied where you think. The model can read the plan and correct a query that is syntactically fine but semantically wrong.
None of this makes the model infallible — you should still read what it produces. But it moves the assistant from “confidently guessing” to “checking against reality,” and that is the difference between SQL you have to verify from scratch and SQL you can trust enough to review quickly.
How can you tell whether an AI assistant is guessing or checking?
You can’t always see inside the tool, but you can ask pointed questions and watch the behavior:
- Does it connect to your actual database, or just a chat box? If the tool never reads your schema, it is guessing by definition. There is no other source for it to use.
- Does it use your real table and column names, or generic ones? Paste a request about a table with an unusual name. A grounded assistant uses your name; a guessing one reaches for a textbook default.
- Does it know your enum and status values? Ask for a filter on a status column. If it invents
'active'when your data uses'A', it never looked. - Can it reason about a query plan? An assistant that can read how the database will execute a query is working from facts, not patterns.
- What exactly does it send to the model? A well-designed tool is explicit that it sends the schema and the SQL, and treats row data as a deliberate opt-in rather than a silent default. That boundary — what should and shouldn’t reach the model — is a sign the tool thought about where its facts come from.
SQL Sage is built around “prove, don’t guess.” It reads the real schema, real values, and query plans from your database and bases its answers on them rather than assuming structure. It works as an add-in for SSMS and a plugin for DBeaver (the DBeaver plugin is Windows-only and supports PostgreSQL, MySQL, MariaDB, Oracle, SQL Server, and SQLite). It sends the schema and SQL to the model — never your rows, unless you opt in — stays read-only by default, and is keyless: it talks to your own Claude or ChatGPT account, with no vendor in the data path.
The takeaway
An AI SQL assistant is only as good as what it knows about your database. A model on its own knows nothing about yours — it knows the average of every database it was trained on, which is exactly why it hallucinates table names that sound right and aren’t.
The principle that fixes this is simple: prove, don’t guess. Ground the model in the real schema, the real values, and the real query plans. When you evaluate a tool, that’s the question underneath all the others — is it reading your database, or imagining it?