Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

152 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@saralsql/tsql-parser

High-fidelity fault-tolerant parser and semantic analysis engine for Microsoft SQL Server T-SQL.

Built specifically for:

  • Language Servers (LSP)
  • editor tooling
  • diagnostics
  • autocomplete
  • lineage tracking
  • enterprise SQL static analysis
  • SQLCMD preprocessing

Why SaralSQL?

Most SQL parsers are designed for query transformation or simple AST extraction.

SaralSQL is built specifically for real SQL Server tooling workloads involving:

  • massive stored procedures
  • mixed DDL + DML batches
  • temp tables and TVPs
  • incomplete SQL during live editing
  • legacy SQL Server edge cases
  • semantic diagnostics and lineage

The parser is optimized for:

  • SQL Server grammar fidelity
  • fault-tolerant parsing
  • editor-safe recovery
  • semantic enrichment
  • high-complexity enterprise SQL

Production Validation

SaralSQL has been validated against real enterprise SQL Server codebases.

Verified against

  • βœ… 600 modern enterprise stored procedures
  • βœ… 1,790 legacy production stored procedures
  • βœ… recursive CTE-heavy workloads
  • βœ… temp-table-heavy ETL systems
  • βœ… TVP-driven workflows
  • βœ… large mixed DDL/DML deployment scripts
  • βœ… complex MERGE and OUTPUT patterns

Stability Goal

The parser is designed to:

  • never crash on malformed SQL
  • preserve partial AST state
  • continue semantic analysis after localized syntax damage

This is critical for editor and LSP scenarios.


Installation

npm install @saralsql/tsql-parser

Quick Start

import { analyze } from '@saralsql/tsql-parser';

const sql = `
SELECT Id, Name
FROM Users
WHERE Id = @Id;
`;

const result = analyze(sql);

console.log(result.diagnostics);
console.log(result.lineage);

Primary API

Use analyze(sql) for the full parser and semantic pipeline.

import { analyze } from '@saralsql/tsql-parser';

const result = analyze(sql);

Analyze Result

Field Description
ast Parsed AST
issues Recoverable parser issues
scope Scope graph for variables, parameters, aliases, CTEs, temp tables, and table variables
diagnostics Semantic and safety diagnostics
lineage Column lineage edges plus source exposure, ambiguity metadata, and mutation target metadata
columns Column resolution analysis including ambiguity candidates and correlation flags where available
typeMembers Built-in and referenced SQL Server type-member catalog (for property/method completions and typing)

AST Example

Sample SQL (used in all follow-on examples)

DECLARE @T TABLE (
  StoreId INT,
  GeoPoint GEOGRAPHY,
  StoreName VARCHAR(100)
);

SELECT
  t.StoreId,
  GeoPoint.Lat AS Latitude
FROM @T t
WHERE StoreId = 1;
{
  "type": "Program",
  "start": 0,
  "end": 167,
  "body": [
    {
      "type": "DeclareStatement",
      "variables": [
        {
          "name": "@T",
          "dataType": "TABLE",
          "columns": [
            { "name": "StoreId", "dataType": "INT" },
            { "name": "GeoPoint", "dataType": "GEOGRAPHY" },
            { "name": "StoreName", "dataType": "VARCHAR(100)" }
          ]
        }
      ],
      "start": 0,
      "end": 88
    },
    {
      "type": "SelectStatement",
      "columns": [
        {
          "type": "Column",
          "expression": {
            "type": "Identifier",
            "name": "t.StoreId",
            "parts": ["t", "StoreId"]
          },
          "outputName": "StoreId"
        },
        {
          "type": "Column",
          "expression": {
            "type": "Identifier",
            "name": "GeoPoint.Lat",
            "parts": ["GeoPoint", "Lat"]
          },
          "alias": "Latitude",
          "outputName": "Latitude"
        }
      ],
      "from": [{ "type": "TableReference", "table": { "type": "Identifier", "name": "@T" }, "alias": "t" }],
      "where": {
        "type": "BinaryExpression",
        "left": {
          "type": "Identifier",
          "name": "StoreId",
          "parts": ["StoreId"]
        },
        "operator": "=",
        "right": { "type": "Literal", "value": 1, "variant": "number" }
      }
    }
  ]
}

Top-Level Type Members (from analyze(...))

{
  "typeMembers": {
    "builtIn": {
      "GEOGRAPHY": [
        { "name": "Lat", "kind": "property", "returnType": "FLOAT", "returnKind": "scalar" },
        { "name": "Long", "kind": "property", "returnType": "FLOAT", "returnKind": "scalar" }
      ]
    },
    "referenced": {
      "GEOGRAPHY": [
        { "name": "Lat", "kind": "property", "returnType": "FLOAT", "returnKind": "scalar" },
        { "name": "Long", "kind": "property", "returnType": "FLOAT", "returnKind": "scalar" }
      ]
    }
  }
}

Column Resolution Decision Contract

analyze(sql).columns.resolutions[] includes a parser-native decision object for identifier ownership and ambiguity. For LSP ergonomics, the same decision fields are also surfaced at top-level on each resolution item: owner, scopeDepth, ambiguityCandidates, decisionReason. Using the sample SQL above (both selected columns):

[
  {
    "location": { "name": "t.StoreId" },
    "inputs": [{ "name": "@T.StoreId", "resolution": "resolved" }],
    "owner": "@T",
    "scopeDepth": 0,
    "decisionReason": "qualified_reference",
    "decision": {
      "owner": "@T",
      "scopeDepth": 0,
      "decisionReason": "qualified_reference"
    }
  },
  {
    "location": { "name": "GeoPoint.Lat" },
    "inputs": [{ "name": "GeoPoint.Lat", "resolution": "unresolved" }],
    "owner": "@T",
    "scopeDepth": 0,
    "decisionReason": "qualified_reference",
    "decision": {
      "owner": "@T",
      "scopeDepth": 0,
      "decisionReason": "qualified_reference"
    }
  }
]

decisionReason values:

  • qualified_reference
  • single_scope_owner
  • single_candidate_promotion
  • ambiguous_candidates
  • unresolved_external
  • non_column

This is intended as parser truth for local ownership/ambiguity so LSP clients do not need to re-run scope-walk heuristics.

Property Access Semantic Contract

analyze(sql).columns.propertyAccesses[] surfaces explicit member/property-access semantics for identifier chains. Using the sample SQL above:

{
  "location": { "name": "GeoPoint.Lat", "start": 22, "end": 34 },
  "baseExpr": "GeoPoint",
  "member": "Lat",
  "resolutionMode": "local_typed_member",
  "owner": "@T",
  "dataType": "GEOGRAPHY",
  "memberType": "FLOAT"
}

resolutionMode values:

  • local_typed_member
  • local_untyped_member
  • shape_member

This helps LSP clients classify base.member access without misclassifying all dotted identifiers as table-qualified columns.

Parser-native built-in member coverage is intentionally focused on common enterprise usage:

  • GEOGRAPHY (core): Lat, Long, STSrid, STDistance, STIntersects, STContains, STWithin, STBuffer, STAsText, ToString
  • GEOMETRY (core): STSrid, STDistance, STIntersects, STContains, STWithin, STBuffer, STArea, STLength, STAsText, ToString
  • XML (core): value, query, exist, nodes, modify
  • hierarchyid (core): GetAncestor, GetDescendant, GetLevel, IsDescendantOf, ToString

Scope Symbol Column Metadata

Scope symbols for local tabular shapes now expose structured column metadata.

  • columns: string[] (legacy compatibility)
  • localColumns: Array<{ rawName, normalizedName, dataType?, location? }> (canonical)

This applies to:

  • declared table variables (DECLARE @T TABLE (...))
  • local temp/typed table symbols created in-file
  • TVP-backed and table-variable aliases where local shape is known

Using the sample SQL above, scope.root.resolve('@T'):

{
  "sql": "DECLARE @T TABLE ( StoreId INT, GeoPoint GEOGRAPHY, StoreName VARCHAR(100) )",
  "name": "@T",
  "kind": "Table",
  "columns": ["StoreId", "GeoPoint", "StoreName"],
  "localColumns": [
    {
      "rawName": "StoreId",
      "normalizedName": "storeid",
      "dataType": "INT"
    },
    {
      "rawName": "GeoPoint",
      "normalizedName": "geopoint",
      "dataType": "GEOGRAPHY",
      "typeMembers": [
        { "name": "Lat", "kind": "property", "returnType": "FLOAT" },
        { "name": "Long", "kind": "property", "returnType": "FLOAT" },
        { "name": "STAsText", "kind": "method", "returnType": "NVARCHAR(MAX)" }
      ]
    },
    {
      "rawName": "StoreName",
      "normalizedName": "storename",
      "dataType": "VARCHAR(100)"
    }
  ]
}

Coverage Scorecard

Everyday TSQL coverage: 92-94%

Full T-SQL grammer coverage: ~78%
Strongest areas: expressions, SELECT grammar, procedural T-SQL, error recovery
Largest gaps: Azure-native DDL, advanced DDL/storage syntax, DCL, linked-server constructs

DQL / SELECT

~92%

Excellent coverage for core and advanced query grammar.

DML

~88%

Strong support for INSERT, UPDATE, DELETE, MERGE, and OUTPUT.

Expressions

~95%

Near-complete expression parser with precedence handling.

Procedural T-SQL

~90%

Strong coverage for control flow, cursors, transactions, and error handling.

DDL

~62%

Useful practical coverage, but not full SQL Server DDL depth.

Azure SQL

~30%

JSON support is strong; Azure-native DDL is limited.

Error Recovery

~91%

Systematic recovery boundaries for editor resilience.

Overall

~78%

Strong everyday SQL Server parser coverage.


Grammar Coverage

SaralSQL focuses heavily on real-world SQL Server grammar used in enterprise stored procedures, ETL systems, and editor tooling.

Legend:
🟩 Full Β Β  🟨 Partial Β Β  πŸŸ₯ Missing

Estimated implementation coverage:
~78% Full Β· major day-to-day T-SQL covered Β· Azure-native DDL still limited

Known issue: a few constructs marked πŸŸ₯ Missing below don't fail cleanly β€” they parse without a PARSE_* issue but produce structurally wrong AST instead of being rejected (e.g. EXEC ... AT linked_server absorbs AT/the server name as bogus call arguments; EXECUTE AS USER = '...' misreads AS as the procedure name; a MASKED WITH (...) column attribute gets merged into the preceding column's data type and then hallucinates an extra column named WITH). Most unsupported constructs fail loudly and recoverably as intended (OPENROWSET, TABLESAMPLE, GROUPING SETS, etc.) β€” these three are tracked as a separate class of bug, not just missing coverage.


DML β€” Queries

SELECT column list🟩 Full
SELECT DISTINCT🟩 Full
TOP / TOP PERCENT🟩 Full
TOP WITH TIES🟩 Full
SELECT INTO🟩 Full
FROM🟩 Full
WHERE🟩 Full
GROUP BY🟩 Full
HAVING🟩 Full
ORDER BY🟩 Full
OFFSET / FETCH NEXT🟩 Full
FOR JSON / FOR XML🟩 Full
UNION / EXCEPT / INTERSECT🟩 Full
OPTION query hints🟩 Full
GROUPING SETS / ROLLUP / CUBEπŸŸ₯ Missing
TABLESAMPLEπŸŸ₯ Missing

DML β€” Write

INSERT VALUES🟩 Full
INSERT SELECT🟩 Full
INSERT column list🟩 Full
INSERT OUTPUT🟩 Full
INSERT DEFAULT VALUES🟨 Partial
INSERT EXECπŸŸ₯ Missing
UPDATE SET🟩 Full
UPDATE FROM / WHERE🟩 Full
UPDATE TOP🟩 Full
UPDATE OUTPUT🟩 Full
UPDATE STATISTICS🟩 Full
DELETE FROM / WHERE🟩 Full
DELETE TOP🟩 Full
DELETE OUTPUT🟩 Full
MERGE all WHEN clauses🟩 Full
MERGE OUTPUT / OPTION🟩 Full
TRUNCATE TABLE🟩 Full

Joins & Table References

INNER JOIN🟩 Full
LEFT / RIGHT / FULL JOIN🟩 Full
CROSS JOIN🟩 Full
CROSS APPLY🟩 Full
OUTER APPLY🟩 Full
Hash / Merge / Loop join hints🟩 Full
Table hints WITH (...)🟩 Full
Subquery / derived table🟩 Full
Table-valued functions🟩 Full
OPENJSON WITH🟩 Full
PIVOT / UNPIVOT🟩 Full
Parenthesized join groups🟩 Full
Four-part names🟩 Full
Temp tables # / ##🟩 Full
OPENROWSETπŸŸ₯ Missing
OPENQUERY / OPENDATASOURCEπŸŸ₯ Missing

Expressions

Arithmetic operators🟩 Full
Bitwise operators🟩 Full
Comparison operators🟩 Full
AND / OR / NOT🟩 Full
IS NULL / IS NOT NULL🟩 Full
LIKE / NOT LIKE🟩 Full
LIKE ESCAPEπŸŸ₯ Missing
IN / NOT IN🟩 Full
BETWEEN / NOT BETWEEN🟩 Full
EXISTS / NOT EXISTS🟩 Full
CASE searched + simple🟩 Full
CAST / TRY_CAST🟩 Full
CONVERT with style🟩 Full
PARSE / TRY_PARSE🟩 Full
Function calls🟩 Full
Aggregate DISTINCT🟩 Full
WITHIN GROUP🟩 Full
Variables and system variables🟩 Full
COLLATE🟨 Partial
IIF / CHOOSE🟨 Partial
AT TIME ZONEπŸŸ₯ Missing

Window Functions

OVER (...)🟩 Full
PARTITION BY🟩 Full
ORDER BY in OVER🟩 Full
ROWS frame🟩 Full
RANGE frame🟩 Full
UNBOUNDED PRECEDING🟩 Full
UNBOUNDED FOLLOWING🟩 Full
CURRENT ROW🟩 Full
N PRECEDING / N FOLLOWING🟩 Full
BETWEEN ... AND frame🟩 Full

Subqueries, CTEs & Set Operators

Scalar subquery🟩 Full
Derived table subquery🟩 Full
WITH ... AS CTE🟩 Full
Multiple CTEs🟩 Full
CTE before DML🟩 Full
Recursive CTE syntax🟨 Partial
UNION / UNION ALL🟩 Full
EXCEPT🟩 Full
INTERSECT🟩 Full
Nested set operators🟩 Full
Parenthesized set queries🟩 Full

DDL & Maintenance

CREATE TABLE🟩 Full
Column data types🟩 Full
NULL / NOT NULL🟩 Full
PRIMARY KEY🟩 Full
FOREIGN KEY🟩 Full
FK ON DELETE / ON UPDATE actions🟩 Full
UNIQUE / CHECK / DEFAULT🟩 Full
IDENTITY🟩 Full
Computed columns🟩 Full
PERSISTED computed columns🟩 Full
Named constraints🟩 Full
CREATE PROCEDURE🟩 Full
CREATE FUNCTION🟩 Full
CREATE VIEW🟩 Full
CREATE TYPE AS TABLE🟩 Full
CREATE INDEX🟩 Full
ALTER INDEX🟩 Full
UPDATE STATISTICS🟩 Full
DROP IF EXISTS🟩 Full
ALTER TABLE advanced actions🟨 Partial
CREATE TRIGGER🟨 Partial
Advanced storage options🟨 Partial
CREATE TABLE AS SELECTπŸŸ₯ Missing
Columnstore indexesπŸŸ₯ Missing
GRANT / REVOKE / DENYπŸŸ₯ Missing

Procedural T-SQL

DECLARE variables🟩 Full
DECLARE table variables🟩 Full
SET @var = expr🟩 Full
SET session options🟩 Full
PRINT🟩 Full
RETURN🟩 Full
IF / ELSE🟩 Full
BEGIN / END🟩 Full
WHILE🟩 Full
BREAK / CONTINUE🟩 Full
GOTO / labels🟩 Full
WAITFOR🟩 Full
TRY / CATCH🟩 Full
THROW🟩 Full
RAISERROR🟩 Full
Transactions🟩 Full
Cursors🟩 Full
EXEC procedure🟩 Full
EXEC named parameters🟩 Full
EXEC output parameters🟩 Full
EXEC dynamic string🟨 Partial
sp_executesql🟨 Partial
EXEC AT linked_serverπŸŸ₯ Missing
EXECUTE ASπŸŸ₯ Missing

Azure SQL / Synapse

OPENJSON WITH schema🟩 Full
FOR JSON AUTO / PATH🟩 Full
JSON_VALUE / JSON_QUERY / JSON_MODIFY🟨 Partial
ISJSON🟨 Partial
Temporal table DDLπŸŸ₯ Missing
FOR SYSTEM_TIME query syntaxπŸŸ₯ Missing
SYSTEM_VERSIONING = ONπŸŸ₯ Missing
CREATE EXTERNAL TABLEπŸŸ₯ Missing
CREATE EXTERNAL DATA SOURCEπŸŸ₯ Missing
Columnstore indexesπŸŸ₯ Missing
Dynamic data maskingπŸŸ₯ Missing
Row-level securityπŸŸ₯ Missing
Ledger table syntaxπŸŸ₯ Missing

Semantic Features

Variable scope🟩 Full
Parameter scope🟩 Full
Alias scope🟩 Full
CTE scope🟩 Full
Temp table scope🟩 Full
Table variable scope🟩 Full
PIVOT / UNPIVOT output scope🟩 Full
Declaration extraction🟩 Full
Dependency extraction🟩 Full
Document symbols🟩 Full
Completions🟩 Full
Diagnostics🟩 Full
Column lineage🟩 Full
Workspace-wide schema catalogπŸŸ₯ Missing
Database-backed wildcard expansionπŸŸ₯ Missing
Runtime type validationπŸŸ₯ Missing

Prioritized Coverage Gaps

P1 β€” High Impact

GROUP BY ROLLUP / CUBE / GROUPING SETS
Temporal query syntax: FOR SYSTEM_TIME
AT TIME ZONE expression
COLUMNSTORE INDEX

P2 β€” Important

GRANT / REVOKE / DENY
Double-quoted identifiers
EXEC AT linked_server
EXECUTE AS USER / LOGIN / CALLER
OPENQUERY / OPENDATASOURCE

Current Diagnostics

SaralSQL focuses on high-signal diagnostics suitable for editors and code review. Codes follow a CATEGORY### convention so editors and CI can filter/suppress by id.

Variables & Parameters

  • VAR001 undeclared variable
  • VAR002 declared but unused variable
  • VAR003 declared but unused parameter
  • VAR004 variable read before it is ever assigned a value (no initializer, no preceding SET)
  • VAR005 invalid schema-qualified table-variable reference (e.g. dbo.@TableVar)

Columns

  • COL001 unknown column on a resolvable table/alias shape
  • NAM001 unbracketed keyword-like column name (e.g. an unbracketed column named ORDER)

DML Safety

  • DML001 UPDATE without a WHERE clause
  • DML002 DELETE without a WHERE clause
  • DML003 INSERT without an explicit column list
  • DML004 UPDATE target table uses WITH (NOLOCK)
  • SEL001 SELECT *
  • SEL002 SELECT * inside a view
  • LOG001 self-comparison such as u.Id = u.Id

Hints & Query Options

  • JOIN001 join hint usage (HASH / MERGE / LOOP)
  • HINT001 table hint usage (NOLOCK, READPAST, INDEX(...), TABLOCK, etc.)
  • OPT001 OPTION clause query-hint guidance (RECOMPILE, MAXDOP, FORCE_ORDER, etc.)
  • CUR001 cursor usage

DDL & Structure

  • DDL001 missing comma before a table-level constraint
  • DDL002 unnamed PRIMARY KEY / UNIQUE constraint
  • DDL003 unnamed DEFAULT constraint
  • DDL004 CREATE/ALTER PROCEDURE, FUNCTION, VIEW, or TRIGGER is not the first statement in its batch

Duplicates

  • DUP001 duplicate variable/parameter declared in the same scope
  • DUP002 duplicate CTE name within a WITH clause
  • DUP003 duplicate SELECT output alias

Diagnostics are intentionally selective. The goal is to remain useful in enterprise SQL without overwhelming users with low-value warnings.


Fault Tolerance Example

Input SQL:

SELECT *
FROM Users
WHERE

Expected behavior:

  • partial AST is preserved
  • parser issue is recorded
  • scope graph remains usable where possible
  • completion context can still be produced
  • analysis continues for valid sections

This is a core design requirement for editor and LSP scenarios.


Diagnostics Example

Input:

UPDATE u
SET u.Name = 'Bad Update'
FROM Users u WITH(NOLOCK)
WHERE u.Id = u.Id

Diagnostics:

[
  {
    "code": "DML004",
    "severity": "error",
    "message": "UPDATE target table must not use WITH (NOLOCK)"
  },
  {
    "code": "LOG001",
    "severity": "warning",
    "message": "Condition compares 'u.Id' to itself"
  }
]

Column Lineage Example

Input:

INSERT INTO dbo.InvoiceSummary (
    CustomerId,
    InvoiceMonth,
    TotalAmount
)
SELECT
    i.CustomerId,
    i.InvoiceMonth,
    i.Subtotal + i.TaxAmount
FROM dbo.Invoices i;

analyze(sql).lineage.edges (each edge is { from: LineageNode, to: LineageNode, location }; from/to fields shown here, trimmed of location and resolution for brevity):

[
  {
    "from": { "kind": "column", "name": "dbo.Invoices.CustomerId", "source": "dbo.Invoices" },
    "to": { "kind": "result", "name": "dbo.InvoiceSummary.CustomerId" }
  },
  {
    "from": { "kind": "column", "name": "dbo.Invoices.InvoiceMonth", "source": "dbo.Invoices" },
    "to": { "kind": "result", "name": "dbo.InvoiceSummary.InvoiceMonth" }
  },
  {
    "from": { "kind": "column", "name": "dbo.Invoices.Subtotal", "source": "dbo.Invoices" },
    "to": { "kind": "result", "name": "dbo.InvoiceSummary.TotalAmount" }
  },
  {
    "from": { "kind": "column", "name": "dbo.Invoices.TaxAmount", "source": "dbo.Invoices" },
    "to": { "kind": "result", "name": "dbo.InvoiceSummary.TotalAmount" }
  }
]

Note that the multi-term expression (i.Subtotal + i.TaxAmount) correctly produces two separate edges into the same target column, since both source columns contribute to it.


Lineage Metadata Example

analyze(sql).lineage also provides source exposure, ambiguity metadata, and mutation target metadata.

{
  "sources": [
    {
      "name": "a",
      "alias": "a",
      "kind": "derived_subquery",
      "projection": [
        { "name": "SomeName" }
      ]
    }
  ],
  "ambiguities": [
    {
      "name": "Id",
      "candidates": ["Employee", "Department"]
    }
  ],
  "mutations": [
    {
      "statement": "UPDATE",
      "targetName": "e",
      "resolvedSourceName": "Employee"
    }
  ]
}

SQLCMD Preprocessing

SaralSQL natively supports SQLCMD directives (:setvar, :r) and variable expansions ($(Var)).

All AST node coordinates and diagnostic offsets are automatically mapped back to the raw, unexpanded text, ensuring perfect LSP integration.

import { analyze, SqlCmdOptions } from '@saralsql/tsql-parser';

const sql = `
:setvar TableName "Users"

SELECT Id, Name
FROM $(TableName)
WHERE Id = @Id;
`;

const options: SqlCmdOptions = { 
  initialVariables: { 
    Environment: 'PROD' 
  } 
};

const result = analyze(sql, options);

Architecture

Lexer
β†’ Parser
β†’ ScopeBuilder
β†’ LineageBuilder
β†’ ColumnAnalyzer
β†’ DiagnosticEngine

Design Principles

Parse once
Enrich in layers
Reuse semantic graph
Avoid duplicate logic
Recover locally
Keep editor tooling alive

Non-goals

SaralSQL is intentionally a single-document analysis engine.

It does not currently provide:

  • cross-file schema catalogs
  • workspace-wide symbol resolution
  • metadata-backed wildcard expansion
  • live database-backed type validation
  • execution-plan validation

Those belong in:

  • the host LSP
  • external metadata services
  • workspace analysis layers

Roadmap

Near Term

  • broader corpus validation
  • richer diagnostics
  • automated code fixes
  • improved DDL coverage
  • Azure SQL grammar expansion

Medium Term

  • schema-aware resolution
  • wildcard expansion
  • FK-aware navigation
  • metadata catalogs
  • standards enforcement packs

Long Term

  • semantic autocomplete
  • rename symbol
  • find references
  • impact analysis
  • safe refactors
  • AI-assisted SQL correction

Contributing

Useful bug reports should include:

  • isolated SQL sample
  • expected behavior
  • current parser output
  • parser issue or diagnostic output
  • package version

License

MIT

Built by Saral Simon Stalin

About

TSQL Parser in Type Script

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages