MSSQL spike: candidate B guard using the ANTLR4 T-SQL grammar #316

Closed
opened 2026-11-10 08:18:37 +00:00 by david · 1 comment
Owner

Summary

Implement candidate B of the read-only guard: the ANTLR4 T-SQL grammar from antlr/grammars-v4 with the antlr4 JS runtime, allowing exactly one SELECT or WITH ... SELECT.

Background

The MSSQL extension's only write block is a T-SQL parser allowlist; it fails closed. This candidate is expected to cover more T-SQL but produces large generated code. This code lives only in extensions/mssql/spike/ (not registered in package.json, no tools). If the dependency check found the grammar has no usable JS/TS target, record that failure in the result note and score this candidate as "not viable" rather than skipping silently.

Depends on: #315

Documentation Required

Vendored under these folders (on main). Read before starting; if absent on your branch, fetch the URLs.

Implementation Details

  1. Download TSqlLexer.g4 and TSqlParser.g4 into extensions/mssql/spike/grammar/ (record the commit SHA and licence). Generate the JS parser with the ANTLR tool (needs Java at build time only; commit the generated output or a generation script, and note the choice in the spike). Remove or replace any Java-specific actions if present.
  2. Create extensions/mssql/spike/candidate-b.mjs exporting validateSql(sql) -> { allowed: boolean, reason?: string }, with the same rules as candidate A: reject on any syntax error (install an error listener that records errors on both lexer and parser), require the whole input consumed (EOF), exactly one statement, statement type is a SELECT query (or WITH + select), reject SELECT INTO, EXEC/EXECUTE, and OPENROWSET/OPENQUERY/OPENDATASOURCE anywhere in the parse tree. Walk the parse tree with a visitor or listener.
  3. Install the runtime with npm install --no-save antlr4; leave root package.json unchanged.

Acceptance Criteria

  • Grammar files and their source commit/licence are recorded in the spike folder.
  • candidate-b.mjs exports validateSql with the signature above.
  • Syntax errors, trailing tokens and multiple statements are rejected.
  • Non-select statements, SELECT INTO, EXEC and the three OPEN* functions are rejected.
  • Root package.json is unchanged.

Test Plan

Run node -e on SELECT 1 (allowed), DELETE FROM t (rejected), SELECT 1; SELECT 2 (rejected), EXEC sp_who (rejected), malformed SQL (rejected). Full scoring comes in the runner issue.

## Summary Implement candidate B of the read-only guard: the ANTLR4 T-SQL grammar from `antlr/grammars-v4` with the `antlr4` JS runtime, allowing exactly one `SELECT` or `WITH ... SELECT`. ## Background The MSSQL extension's only write block is a T-SQL parser allowlist; it fails closed. This candidate is expected to cover more T-SQL but produces large generated code. This code lives only in `extensions/mssql/spike/` (not registered in `package.json`, no tools). If the dependency check found the grammar has no usable JS/TS target, record that failure in the result note and score this candidate as "not viable" rather than skipping silently. **Depends on:** #315 ## Documentation Required Vendored under these folders (on `main`). Read before starting; if absent on your branch, fetch the URLs. - `docs/reference/antlr4/` — https://raw.githubusercontent.com/antlr/antlr4/dev/doc/javascript-target.md : ANTLR4 JavaScript target: installing the `antlr4` runtime, generating a JS/TS parser, lexer/parser/visitor usage. - `docs/reference/grammars-v4-tsql/` — https://raw.githubusercontent.com/antlr/grammars-v4/master/sql/tsql/README.md : notes on the T-SQL grammar. The grammar files `TSqlLexer.g4` and `TSqlParser.g4` are NOT vendored (about 200 KB); download them from https://github.com/antlr/grammars-v4/tree/master/sql/tsql into the spike folder. ## Implementation Details 1. Download `TSqlLexer.g4` and `TSqlParser.g4` into `extensions/mssql/spike/grammar/` (record the commit SHA and licence). Generate the JS parser with the ANTLR tool (needs Java at build time only; commit the generated output or a generation script, and note the choice in the spike). Remove or replace any Java-specific actions if present. 2. Create `extensions/mssql/spike/candidate-b.mjs` exporting `validateSql(sql) -> { allowed: boolean, reason?: string }`, with the same rules as candidate A: reject on any syntax error (install an error listener that records errors on both lexer and parser), require the whole input consumed (EOF), exactly one statement, statement type is a `SELECT` query (or `WITH` + select), reject `SELECT INTO`, `EXEC`/`EXECUTE`, and `OPENROWSET`/`OPENQUERY`/`OPENDATASOURCE` anywhere in the parse tree. Walk the parse tree with a visitor or listener. 3. Install the runtime with `npm install --no-save antlr4`; leave root `package.json` unchanged. ## Acceptance Criteria - [ ] Grammar files and their source commit/licence are recorded in the spike folder. - [ ] `candidate-b.mjs` exports `validateSql` with the signature above. - [ ] Syntax errors, trailing tokens and multiple statements are rejected. - [ ] Non-select statements, `SELECT INTO`, `EXEC` and the three `OPEN*` functions are rejected. - [ ] Root `package.json` is unchanged. ## Test Plan Run `node -e` on `SELECT 1` (allowed), `DELETE FROM t` (rejected), `SELECT 1; SELECT 2` (rejected), `EXEC sp_who` (rejected), malformed SQL (rejected). Full scoring comes in the runner issue.
david closed this issue 2026-11-10 23:06:51 +00:00
Author
Owner

pi-loop opened and merged a pull request for this issue: #338

pi-loop opened and merged a pull request for this issue: https://git.excelera.net/david/pi-extensions-and-skills/pulls/338
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
david/pi-extensions-and-skills#316
No description provided.