Skip to content

Make the engine's own checks fire, and version core 0.7.0 - #28

Merged
rahulmahadik merged 4 commits into
mainfrom
develop
Aug 15, 2026
Merged

Make the engine's own checks fire, and version core 0.7.0#28
rahulmahadik merged 4 commits into
mainfrom
develop

Conversation

@rahulmahadik

Copy link
Copy Markdown
Owner

Four commits: the engine and connector work, the two hand-versioned surfaces, and the version bumps.

Why this cut exists

Five catalog and semantic checks were silently dead on Oracle. Every one of them fails open by
design, so a check that stops parsing a statement is indistinguishable from a check that found
nothing, and no suite goes red. A top-N question makes the model write FETCH FIRST n ROWS ONLY,
which the parser those checks use cannot read, so the column floor, the table floor, the fan-out
floor, the ungrouped-aggregate lint and the ambiguous-column floor all went quiet, and a query
selecting a column no table has reached the database. The MongoDB no-op check had the same hole for
shell-form JSON, which is what a small model writes.

checks-alive.test.ts and ChecksAliveTest.kt now give every check a query it must flag on every
dialect. Reverting the fix fails fifteen of them.

Versions

Package Version
@asksql/core 0.7.0
@asksql/oracle 0.3.0
@asksql/server 0.6.1
@asksql/react 0.3.2
@asksql/postgres 0.3.1
@asksql/duckdb 0.3.1
VS Code extension 0.7.2
JetBrains plugin 0.5.3

Behaviour a user can see change

  • Oracle: a plain trailing LIMIT n is translated to FETCH FIRST n ROWS ONLY instead of being
    refused. Offset and placeholder forms are still refused.
  • MongoDB: a relationship question is answered in prose, matching the SQL engines, rather than
    returning documents.
  • JetBrains: an INTEGER column and every MongoDB integer show as 1, not 1.0, in the grid, the
    copy buffer and exported CSV.

Verification

Check Result
TypeScript, every package 2854 passed
Kotlin unit 730 passed
Kotlin integration 112 passed (run alone)
Real databases 18/18 on Postgres, MySQL, SQLite, DuckDB, Oracle, MongoDB
Hostile identifiers 26/26
Graduated matrix, easy to hard, 6 engines 70/70
Cloud providers (Groq, NVIDIA) 6/6 on each of 3 models
Packaged consumer, browser e2e passed
pnpm verify exit 0

Not verified: no human has driven the JetBrains or VS Code UIs, and the Anthropic, OpenAI, Google
and Azure providers were not exercised.

Every catalog and semantic check returns "nothing found" on anything it cannot
parse, so a check that stops reading a statement is indistinguishable from one
that found nothing, and no suite goes red. Five were dead on Oracle: a top-N
question makes the model write FETCH FIRST n ROWS ONLY, which the parser these
checks use cannot read, so the column floor, the table floor, the fan-out floor,
the ungrouped-aggregate lint and the ambiguous-column floor all went quiet, and a
query selecting a column no table has reached the database. The MongoDB no-op
check had the same hole for shell-form JSON, which is what a small model writes.

Each now reads the statement the way the guard does, and a new test gives every
check a query it must flag on every dialect. Removing the fix fails fifteen of
them, so one going quiet again fails the suite rather than shipping.

A correction now names where the column actually lives. Told only that a column
does not exist, a model renames the alias and fails the same way; told which
table has it and the join that reaches it, it fixes the query. Measured on a 7B
model against Oracle: none of three recovered before, three of three after.

Structure questions are answered with SQL written here rather than guessed. "How
many rows are in each table", "which tables have no primary key" and "what tables
are in this database" read each engine's own catalog with every name quoted,
because a model that has never seen information_schema invents columns on it. A
relationship question is answered from the foreign keys instead of returning rows
of a join, on documents as well as SQL, and a question about nothing in the
database is declined in one sentence.

Oracle no longer refuses the one thing a small model cannot stop doing: a plain
trailing LIMIT n becomes FETCH FIRST n ROWS ONLY, which is the same query, while
the forms with no equivalent are still refused. An account holding grants on
another owner's tables can now name that schema instead of seeing an empty
database, and CURRVAL is allowed, since it reports the current value without
advancing anything.

Database error text is redacted before it reaches a model, a scoped caller can no
longer tell an existing connection from a missing one by the status code, a
composite foreign key keeps its column order, and values from the DuckDB drivers
arrive as values rather than as their storage.
Clearing the panel during a question left the button reading "Cancel" with
nothing to cancel, and refused the next question because the panel still
believed it was busy.

The result store measured a result by sampling its first rows and pricing any
object at a flat 32 bytes, so a result holding large JSON or BLOB cells was
counted as if every cell were tiny and the store could hold far more memory than
its budget allowed. It now samples across the result and measures a large value
up to a bound, which costs less than sizing a megabyte cell exactly.

The extension also carries the core changes it imports: structure questions
answered from the catalog, relationship questions answered in prose, the Oracle
LIMIT translation, and error text redacted before it reaches a model.

An unused settings interface goes with it, since nothing has ever referenced it.
Swing reads a string that opens with <html> as markup, and a result cell, a
schema tree label and a chart tooltip all come from the database. A value like
"<html><img src=http://...>" in a table the plugin displayed would fetch that URL
from inside the IDE. All three now render as text.

The "suggest a fix" prompt carried raw driver error text, which quotes the
offending row, so cell values reached the model. They are redacted first, the
same way the TypeScript engine does it.

A whole number is shown without a decimal the database never had: an INTEGER
column and every MongoDB integer rendered as "1.0" in the grid, the copy buffer
and exported CSV. One formatter now serves all of them, and INTEGER travels as a
number so it sorts and charts as one.

The plugin also gains the engine work from this cut: structure questions answered
from the catalog, relationship questions answered in prose on documents as well
as SQL, the fan-out floor that reports a SUM inflated by a join, and the Oracle
LIMIT translation. A failed schema read is no longer cached as an empty database
for five minutes, a transient rate limit is reported as one rather than as a
billing problem, and a mid-stream provider error is surfaced instead of being
returned as a truncated answer.
core and oracle take a minor: core gains public routing predicates and the mongo
pipeline helpers, oracle a schema option for an account that reads another
owner's tables. server, react, postgres and duckdb take a patch.
@rahulmahadik
rahulmahadik merged commit 99f9165 into main Aug 15, 2026
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant