a definition

semantic SQL

/səˈman.tɪk ˌɛs.kjuːˈɛl/ · noun

SQL in which predicates and expressions operate on the meaning of data rather than its characters — machine-learning models exposed as ordinary typed SQL functions, so filtering, ranking, classifying, and extracting by meaning compose with joins, groups, and everything else the relational algebra already does.

SELECT * FROM tickets
WHERE means(body, 'angry about billing');

That WHERE clause is the whole idea. The rest of this page is detail.

Why the term exists

Databases match characters. Questions are about meaning.

Fifty years of SQL gives you exact equality, ranges, and pattern matching over characters. But most of the questions people actually bring to their data are semantic: which of these are complaints? which notes mention a safety issue? which two records are the same customer?

Character SQL

SELECT * FROM tickets
WHERE body ILIKE '%angry%'
   OR body ILIKE '%mad%'
   OR body ILIKE '%upset%';  -- …

misses“this is the third timeI’ve been overcharged”

false hit“I was angry until support sorted it — five stars”

Semantic SQL

SELECT * FROM tickets
WHERE means(body, 'angry about billing');

catchesfury that never uses an anger word

skipspraise that happens to contain one

How it works

Models become functions. Functions return SQL types.

Underneath, three kinds of machinery answer the call — and the crucial move is that each returns a plain, typed SQL value, so the planner, the optimizer, and your GROUP BY never know anything unusual happened.

Encoder models

Embeddings, cross-encoders, NLI, sentiment, OCR, forecasting. Small, fast, cheap enough to run over whole tables. They answer how similar / does this entail / which label — and they do the bulk of semantic work.

LLM steps

For judgment that needs actual reading: extract this invoice to my schema, is this evidence for that claim, rewrite with PII redacted. Prompt-engineered once, exposed as a function forever.

Deterministic gates

Code between the model and your column: parse the output, apply the threshold, coerce the type, refuse the garbage. The reason a semantic predicate can safely return a bool.

And because operators return ordinary types, they compose like SQL, not like an API:

SELECT clover_classify(body, '["bug","billing","feature request"]') AS topic,
       count(*),
       avg(clover_sentiment_score(body))
FROM tickets
WHERE created_at > now() - interval '30 days'
GROUP BY 1
ORDER BY 2 DESC;

Disambiguation

What semantic SQL is not.

The term gets conflated with three neighbors. All three are real and useful; none of them is this.

Not text-to-SQL

Text-to-SQL turns a natural-language question into a query. Semantic SQL is a query you wrote — versioned, reviewed, deterministic in shape — where some operators understand meaning. One generates code; the other extends the language.

Not (just) vector search

Nearest-neighbor similarity is one primitive — the adjective. Semantic SQL also needs verbs: entail, classify, extract, repair, judge. A pgvector column is an ingredient; a semantic SQL surface is the cuisine.

Not RAG

RAG retrieves context so a chatbot can answer one question. Semantic SQL answers set-oriented questions — filter 40,000 rows by meaning, group by inferred category, join on entity identity — with no chat loop anywhere.

The hard question

“But models aren’t deterministic.”

Correct — and SQL has absorbed messier things than this (floats, collations, time zones). The discipline that makes it safe: pin model versions so answers are reproducible; cache so the same input never pays or drifts twice; receipt every call with the exact model that produced it, so any answer can be audited later; gate free-text output through deterministic code before it becomes a typed value; and test operators like functions, because that’s what they are. Treat a semantic operator like a tiny, versioned ML deployment — because it is one — and it behaves like SQL.

A working implementation

This site ships one.

RVBBIT implements semantic SQL as a Postgres extension — 49 operators across encoder, composite, and LLM cascades, hosted or self-hosted, with receipts on every call. Runnable in about five lines:
-- any Postgres 18 (tarball: rvbbit.ai/existing-postgres)
CREATE EXTENSION pg_rvbbit;  SELECT rvbbit.migrate();
\! curl -fsSL https://rvbbit.ai/clover-install.sql | psql
SELECT rvbbit.set_secret('RVBBIT_CLOVER_KEY', 'rvb_…');  -- free key: rvbbit.ai/free

SELECT means('this blanket is cozy wool', 'warm bedding');   -- t

Quickstart · the operator reference · free key