Back to Blog

sqljev: TypeSafe Jev's jev() for SQL Server, Postgres, Snowflake, BigQuery and DuckDB, on Jev or Open-Weight Laya

Prateek SinghSeptember 30, 202610 min read65 views
sqljev: TypeSafe Jev's jev() for SQL Server, Postgres, Snowflake, BigQuery and DuckDB, on Jev or Open-Weight Laya

SQL cannot say 'the customer threatens to cancel'. sqljev adds jev(), jev_prob() and jev_choice() to SQL Server, PostgreSQL, MySQL, Snowflake, Databricks, BigQuery, Redshift and DuckDB, and answers them with Laya, an open-weight decision model that runs on your hardware, returns calibrated probabilities instead of text, and can be fine-tuned on your own tables. 140,000 decisions in 271 seconds on one laptop GPU; re-running all 13 queries, 0.9 seconds. Apache 2.0, version 0.1.0.

There is a whole class of questions SQL cannot ask. Not "tickets created this week"; SQL is good at that. "Tickets where the customer threatens to cancel." "Contracts that mention a price guarantee." "Adverse-event reports that describe liver injury." You cannot say those with =, LIKE or a regex, so they get exported to a notebook, judged by a model there, and the answers never make it back into the database where the rest of the question lives.

sqljev, which I released on 26 September as version 0.1.0, puts that judgment back inside the query. It adds jev(), jev_prob() and jev_choice() to SQL Server, PostgreSQL, MySQL, Snowflake, Databricks, BigQuery, Redshift and DuckDB, and answers them with an open-weight model running on your own hardware.

databases, one function name
8
SQL Server, PostgreSQL, MySQL, Snowflake, Databricks, BigQuery, Redshift, DuckDB, plus any SQLAlchemy URL from the CLI
140,000 decisions, one laptop GPU
271 s
516 decisions a second through real SQL, base model, no training
re-run all 13 queries
0.9 s
every answer from the cache; only changed rows are judged again
per token, on your hardware
$0
open weights, Apache 2.0, row data never leaves your network

Benchmark: 100,000 synthetic rows with exact labels across 10 tables, 13 questions, one plain SQL query each through DuckDB, base Laya English checkpoint, RTX 4090 Laptop GPU that another model was sharing. From the sqljev README, reproducible with bench/run.py.

-- Snowflake / Databricks / DuckDB / BigQuery / Redshift: the row goes in as JSON
SELECT * FROM tickets t WHERE jev(OBJECT_CONSTRUCT(t.*), 'the customer threatens to cancel');

SELECT subject, jev_prob(to_json(t), 'the customer is angry') AS p
FROM tickets t ORDER BY p DESC LIMIT 20;

SELECT jev_choice(to_json(t), 'which team should handle this?',
                  ['billing', 'technical', 'security', 'sales']) AS team, count(*)
FROM tickets t GROUP BY team;

-- SQL Server / Azure SQL
EXEC jev.judge N'dbo.tickets', N'the customer is angry';
SELECT * FROM dbo.tickets AS t
WHERE jev.prob((SELECT t.* FOR JSON PATH, WITHOUT_ARRAY_WRAPPER), N'the customer is angry') >= 0.5;

jev() is an ordinary boolean function, so it composes with everything else in SQL: AND created_at > ..., joins, GROUP BY, LIMIT. Keep arithmetic, dates and exact matches in SQL; let the model judge meaning.

The model does not write; it decides

This is not an LLM generating text and hoping it parses. Every row is judged by a decision model: given a row and a typed question (yes/no, a choice from options, a score on ordered levels), it returns a calibrated probability in a single forward pass. No prompt engineering, no JSON to repair, no temperature. By default that model is Laya, from Convai Innovations, Apache 2.0, open weights, about 33 ms per decision on a T4 and about 7 ms per decision batched. Row data never leaves your network and there is no per-token bill. TypeSafe's hosted Jev is one setting away if you want its stronger zero-shot accuracy and can send rows out.

The idea comes from pg-jev, a PostgreSQL extension that does this on Jev, and parts of sqljev are ported from it under its licence. sqljev takes the same idea to every other database and swaps in an open model you can train.

One question, many rows, very little work

A SQL condition is one question asked of a great many rows, and the engine is built around that fact rather than around chat.

  • Rows go in as compact JSON, NULL columns dropped; pass only the columns the judgment needs.
  • Every database already batches UDF calls. Snowflake, BigQuery, Redshift, Spark and DuckDB hand over hundreds to thousands of rows per call; SQL Server's jev.judge sends 500 at a time. Each batch is one engine call.
  • De-duplicate, then cache. Identical rows are judged once. Answers are cached by row content and question, so re-running, changing the threshold or sorting by probability is free, and only changed rows are judged again.
  • Shared forward passes. Misses are packed into one forward pass, 64 rows by default, sorted by length to minimise padding. On CPU that is 0.19 s a row batched against 0.35 s one at a time.
  • Streaming when it pays. --where ... --limit N judges rows in order with bounded read-ahead and stops after the first N matches.

The result, on the built-in benchmark: 140,000 decisions in 271 seconds, 516 a second, through real SQL on an RTX 4090 Laptop GPU that another model was sharing. Re-running all 13 queries took 0.9 seconds, every answer from the cache. With an instant stand-in model, sqljev's own overhead measured about 98,000 decisions a second; the model is the only cost.

What the base model gets right, and where it does not

Ten synthetic but realistic tables with exact labels, 100,000 rows, 13 questions, one plain SQL query each, the base Laya English checkpoint with no training. Reproducible with python -m sqljev.demo and bench/run.py.

Base Laya, no training: accuracy (amber) against always-guess-the-majority (grey), 13 questions, 100,000 rows RTX 4090 Laptop GPU, shared · one plain SQL query per question through DuckDB · red labels: under 10 points above the baseline, where fine-tuning pays 0%25%50%75%100% Contract clause: which type? (5) 99.5% Job post: fully remote? 92.2% Support ticket: is the customer angry? 89.4% Advisor email: guarantees returns? 86.5% Support ticket: which team? 85.4% Job post: how senior? (3) 85.3% Expense: which category? (5) 85.1% Product review: reports a defect? 85.0% Product review: sentiment (3) 82.8% Adverse event: was it serious? 69.9% Two records: same company? (join) 68.5% Adverse event: which body system? (5) 68.0% Rental listing: pets allowed? 59.5%
Accuracy against the always-guess-the-majority baseline. Base Laya English checkpoint, no training, RTX 4090 Laptop GPU shared with another model. From the sqljev README.

Read the red rows honestly. "Was the adverse event serious?" is 69.9% against a 65.0% baseline; "pets allowed?" is 59.5% against 54.6%. Those are the questions where the model has to learn your definition: what counts as serious in pharmacovigilance, what a pet-policy sentence means. That is exactly where the second half of the project comes in.

Laya (default)Jev (hosted)
Licence, weightsApache 2.0, open weightsproprietary API
Where it runsyour server, GPU or CPUTypeSafe's cloud
Cost$0 per token$0.042 per 1M input tokens
Latency~33 ms per decision (T4)~250 ms per request
Zero-shot accuracy, typed decisions0.362 (base checkpoint)0.727
Fine-tuned accuracy, typed decisions0.766not fine-tunable
Wide option sets (Banking77)0.4250.870
Laya against the hosted Jev, from Laya's published benchmarks, as the README reports them. Laya's strength is the last row but one: it can be trained on your data, and SQL tables are full of labels.

Fine-tune it on your own tables, in four commands

Zero-shot Laya is not Jev; the table says so. What Laya has that Jev does not is that you can train it, and a table with a label column is a training set. sqljev ships the whole loop, and the label column is never shown to the model: the state and the question are built by the same code the runtime uses, so the checkpoint learns exactly what it will be asked.

# 1. labelled rows -> train/test; the label column is never shown to the model
sqljev dataset "$DB_URL" "SELECT subject, body, team FROM tickets WHERE team IS NOT NULL" \
    --label team --choice "which team should handle this?" --test-fraction 0.2 -o tickets.jsonl
# 2. how does the base model do on YOUR rows?
sqljev eval tickets.test.jsonl
# 3. fine-tune on one GPU (a free Colab T4 is enough; --train-layers 12 under ~10 GB)
sqljev finetune tickets.train.jsonl --out checkpoints/tickets --epochs 3
# 4. measure again on the same held-out rows, publish, point every database at it
sqljev eval tickets.test.jsonl --model checkpoints/tickets --min-accuracy 0.85
HF_TOKEN=... sqljev publish checkpoints/tickets --repo your-org/laya-tickets
SQLJEV_MODEL=your-org/laya-tickets sqljev gateway --host 0.0.0.0

Measured on the built-in pharma demo, "the adverse event was serious", 3,000 training rows and 1,000 held out: 69.4% to 100% after two minutes of training on the same laptop GPU. The README says the next part in the same breath, and so will I: the demo reports come from templates and are easy to learn. Expect a smaller jump on real data, and measure it the same way, with sqljev eval on held-out rows before you trust a threshold. There is a Colab notebook that does the whole loop on a free T4 if you would rather not open a terminal.

Eight databases, one set of names

functionreturnsuse
jev(row, condition)booleana WHERE predicate; threshold 0.5 by default
jev_prob(row, condition)float 0..1ORDER BY it: most urgent incidents, likeliest leads
jev_choice(row, question, options)textroute: which team, which category
jev_score(row, question, levels)floatprobability-weighted position on ordered levels
jev_eval(row, question, kind, options)jsonthe full answer: probabilities and confidence
The same names everywhere; SQL Server uses the jev. schema. Full list, including jev_score_norm and jev_confidence, in the README.

How it reaches each database is different, and each has an install script in the repository. SQL Server 2025 and Azure SQL call a small gateway through sp_invoke_external_rest_endpoint; SQL Server 2016 to 2022 fill the same answer table from outside with one command. PostgreSQL and MySQL need no extension and no superuser. Snowflake can run Laya inside your account on Snowpark Container Services, so rows never leave it. Databricks registers pandas UDFs on every executor; BigQuery uses remote functions on Cloud Run; Redshift uses a Lambda; DuckDB registers Arrow UDFs in-process. The gateway also speaks Jev's own API, so pg-jev on a self-hosted Postgres can run on Laya too.

pip install "sqljev[laya,db]"        # engine + Laya + SQLAlchemy CLI, Python 3.10+
sqljev query "sqlite:///support.db" "SELECT * FROM tickets" --where "the customer is angry" --limit 10
# downloads Laya once (~1.7 GB), judges the rows on your machine, prints the angry tickets with their probability

Caveats, from the README

  • Limit before you judge. Databases compute the SELECT list before ORDER BY ... LIMIT, so a jev_prob() next to a LIMIT 100 judges every row. Limit in a subquery first; put cheap predicates first in WHERE.
  • No index can answer a plain-language condition. Every row that reaches jev() is judged, once. Filter with cheap SQL first.
  • Laya reads 512 tokens in English, 1,024 multilingual, up to 8,192 with max_len. Wide rows are cut off; send the columns that matter.
  • Measure before you trust a threshold. Answers can change between checkpoints; pin model when results feed reports.

sqljev is Apache 2.0 and independent: not affiliated with TypeSafe or with Convai Innovations, and version 0.1.0 as of today. pip install sqljev, the site has copy-paste setup per database, and if you run the benchmark on your own tables I would like to see the numbers, the weak rows most of all.

FAQ: plain-English conditions in SQL

Can you write a WHERE clause in plain English?

With sqljev, yes: jev(row, 'the customer threatens to cancel') is an ordinary boolean function, so it composes with AND, joins, GROUP BY and LIMIT. It works on SQL Server, PostgreSQL, MySQL, Snowflake, Databricks, BigQuery, Redshift, DuckDB and any SQLAlchemy database from the CLI.

How is this different from an LLM writing SQL for me?

Text-to-SQL writes the query; sqljev evaluates a condition SQL cannot express at all. The model does not generate text: Laya is a decision model that returns a calibrated probability for a typed question (yes/no, choice, score) in one forward pass, about 33 ms on a T4.

Does my data leave the database?

Not by default. Laya is open weights under Apache 2.0 and runs in-process or in a gateway you host; on Snowflake it can run inside your account on Snowpark Container Services. Only the hosted Jev backend sends rows to a third party, and it is off unless you turn it on.

How accurate is it without training?

Good on clear yes/no conditions, weaker on fine-grained choices. On the 13-question, 100,000-row benchmark the base model ranged from 99.5% on contract clause type to 59.5% on pet policies. Laya's published zero-shot figure on typed decisions is 0.362 against 0.727 for the hosted Jev; fine-tuned, Laya reaches 0.766, and Jev cannot be fine-tuned.

How much does it cost per row?

Nothing per token. Answers are cached by row content and question, so re-running a query, changing the threshold or sorting by probability costs nothing, and only rows that changed are judged again. With an instant stand-in model, sqljev's own overhead measured about 98,000 decisions a second.

References & Citations

  • sqljev README, CHANGELOG and release v0.1.0, 26 September 2026; bench/run.py; singhpratech.github.io/sqljev; sqljev 0.1.0 on PyPI (Python ≥ 3.10). Source of every benchmark number: 100,000 synthetic rows, 13 questions, base Laya English checkpoint, RTX 4090 Laptop GPU shared with another model; the fine-tune figure is the built-in pharma demo, 3,000 training rows, 1,000 held out.
  • Laya, Convai Innovations, Apache 2.0: a non-autoregressive decision model returning typed decisions in one forward pass; the Laya-vs-Jev table is the README's summary of Laya's published benchmarks.
  • pg-jev, PostgreSQL licence: the extension that does this inside PostgreSQL on TypeSafe's Jev; sqljev credits and partly ports it (see NOTICE).
  • TypeSafe Jev documentation, for the hosted backend.

Subscribe to new posts from theaivibe.org

No spam — just new posts. One-click unsubscribe.
Share this article

Related Posts

pankhllm: The LLM Gateway That Learns to Skip the LLM, Without Replacing the Stack You Already Run
Data Engineering10 min read

pankhllm: The LLM Gateway That Learns to Skip the LLM, Without Replacing the Stack You Already Run

Most of an agent's LLM calls are not writing anything. They are decisions: which tool, which skill, which parameters, made thousands of times a day by a model paid in seconds and tokens. pankhllm sits where your app already calls an LLM, learns those decisions from its own traffic, and starts making them in 0.2 ms on a CPU with a 262 KB model. What it is not sure about still goes to your LLM. On the same 14 questions: a 12B planner 1,743 ms, Laya 49 ms, pankhllm's own model 4 ms, all 14 correct. Here is what it is, what it is not, and where it stops.

76 views
Read
Your Apple Silicon GPU Loses to One CPU Core Until a Million Rows. I Measured 111 Operations, Then Rebuilt ArrowMetal 0.2.0 Around the Answer
Data Engineering19 min read

Your Apple Silicon GPU Loses to One CPU Core Until a Million Rows. I Measured 111 Operations, Then Rebuilt ArrowMetal 0.2.0 Around the Answer

Every GPU data library benchmarks itself at 50 million rows. Your dataframe has 80,000. On an Apple M4 Max, summing 1,000 integers takes the GPU 112 microseconds and Polars less than one: the GPU is more than 100 times behind. I built one of these libraries, so I measured the row count where the GPU overtakes the fastest CPU code for 111 operations: the median needs 10,000,000 rows against a multi-core library, about a million against one core, and sixteen never get there. So ArrowMetal 0.2.0 refuses the GPU below the line, byte-identical, and around that router it grew GPU readers for CSV, JSON, nested Parquet, Delta Lake and Iceberg, a Polars engine and a DuckDB optimizer extension.

77 views
Read
DuckDB on the Apple Silicon GPU: Plain SQL, 19 of 22 TPC-H Queries on the Mac's Own GPU, and a Rule That Says Never Slower
Data Engineering15 min read

DuckDB on the Apple Silicon GPU: Plain SQL, 19 of 22 TPC-H Queries on the Mac's Own GPU, and a Rule That Says Never Slower

DuckDB has no GPU backend of its own, and the GPU engines built for it need an NVIDIA card. gpudb 0.7 is my Apache-2.0 DuckDB extension for the GPU already inside your Mac, and for CUDA too. You write plain DuckDB SQL; the GPU takes a statement only where it has been measured faster than DuckDB on your own machine. On an Apple M4 Max, 19 of 22 TPC-H SF10 queries run on the Metal GPU at 1.06x to 48x with zero rows differing. The one row below parity is printed, not dropped.

92 views
Read