Skip to content

Commit 0be5352

Browse files
authored
Implement Phase 1: Complete SELECT statement support (#6)
1 parent fcf6adf commit 0be5352

45 files changed

Lines changed: 4487 additions & 446 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

PLAN.md

Lines changed: 353 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,353 @@
1+
# Plan to Unskip All Query Tests
2+
3+
## Overview
4+
5+
This plan outlines the strategy to unskip all 1,011 currently skipped query tests in the T-SQL parser. The tests are organized in `/home/user/teesql/parser/testdata/` with each test containing:
6+
- `metadata.json` - Skip flag (`{"skip": true}` or `{"skip": false}`)
7+
- `query.sql` - T-SQL query to parse
8+
- `ast.json` - Expected AST output
9+
10+
### Current Status
11+
- **Total tests:** 1,023
12+
- **Skipped tests:** 1,011 (98.9%)
13+
- **Active tests:** 12 (1.1%)
14+
15+
### Currently Implemented Features
16+
- SELECT statements (basic: columns, FROM, aliases)
17+
- PRINT statements
18+
- THROW statements
19+
- ALTER TABLE DROP INDEX
20+
- DROP DATABASE SCOPED CREDENTIAL
21+
- REVERT statements
22+
23+
---
24+
25+
## Phase 1: Complete SELECT Statement Support
26+
27+
**Goal:** Unskip `SelectStatementTests` and related baseline tests
28+
29+
### 1.1 Core SELECT Enhancements
30+
- [ ] **TOP clause** - `SELECT TOP 10 ...`, `TOP (n) PERCENT WITH TIES`
31+
- [ ] **INTO clause** - `SELECT ... INTO table FROM ...`
32+
- [ ] **Column aliases** - `AS alias`, `[column name]` without AS
33+
- [ ] **Bracketed identifiers** - `[schema].[table].[column]`
34+
35+
### 1.2 WHERE Clause
36+
- [ ] **Comparison operators** - `=`, `<>`, `<`, `>`, `<=`, `>=`
37+
- [ ] **Boolean operators** - `AND`, `OR`, `NOT`
38+
- [ ] **IN expressions** - `col IN (1, 2, 3)`
39+
- [ ] **BETWEEN expressions** - `col BETWEEN 1 AND 10`
40+
- [ ] **LIKE expressions** - `col LIKE 'pattern%'`
41+
- [ ] **IS NULL / IS NOT NULL**
42+
43+
### 1.3 GROUP BY and HAVING
44+
- [ ] **Basic GROUP BY** - `GROUP BY col1, col2`
45+
- [ ] **GROUP BY ALL**
46+
- [ ] **WITH ROLLUP / WITH CUBE**
47+
- [ ] **HAVING clause**
48+
49+
### 1.4 ORDER BY
50+
- [ ] **ORDER BY clause** - `ORDER BY col ASC/DESC`
51+
- [ ] **Multiple columns**
52+
- [ ] **Ordinal references** - `ORDER BY 1, 2`
53+
54+
### 1.5 JOINs
55+
- [ ] **INNER JOIN**
56+
- [ ] **LEFT/RIGHT/FULL OUTER JOIN**
57+
- [ ] **CROSS JOIN**
58+
- [ ] **JOIN hints** (LOOP, HASH, MERGE)
59+
60+
### 1.6 Set Operations
61+
- [ ] **UNION / UNION ALL**
62+
- [ ] **EXCEPT**
63+
- [ ] **INTERSECT**
64+
65+
### 1.7 Subqueries
66+
- [ ] **Scalar subqueries** - `(SELECT ...)`
67+
- [ ] **Table subqueries** - `FROM (SELECT ...) AS t`
68+
- [ ] **EXISTS / NOT EXISTS**
69+
70+
### 1.8 Tests to Unskip
71+
- `SelectStatementTests``SelectStatementTests/metadata.json`
72+
- `Baselines*_SelectStatementTests` variants
73+
74+
---
75+
76+
## Phase 2: Expression Support
77+
78+
**Goal:** Support all expression types used across tests
79+
80+
### 2.1 Literals
81+
- [ ] **Numeric literals** - integers, decimals, floats
82+
- [ ] **Binary literals** - `0x...`
83+
- [ ] **National strings** - `N'...'`
84+
- [ ] **GUID literals** - `{guid'...'}`
85+
- [ ] **Date/time literals**
86+
- [ ] **NULL literal**
87+
88+
### 2.2 Arithmetic Expressions
89+
- [ ] **Multiplication / Division** - `*`, `/`, `%`
90+
- [ ] **Unary minus/plus**
91+
- [ ] **Bitwise operators** - `&`, `|`, `^`, `~`
92+
93+
### 2.3 Function Calls
94+
- [ ] **Scalar functions** - `GETDATE()`, `ISNULL()`, etc.
95+
- [ ] **Aggregate functions** - `COUNT()`, `SUM()`, `AVG()`, `MIN()`, `MAX()`
96+
- [ ] **Window functions** - `ROW_NUMBER() OVER(...)`
97+
- [ ] **CAST / CONVERT**
98+
- [ ] **CASE expressions**
99+
100+
### 2.4 Special Expressions
101+
- [ ] **COALESCE**
102+
- [ ] **NULLIF**
103+
- [ ] **IIF**
104+
- [ ] **Collation expressions**
105+
106+
---
107+
108+
## Phase 3: DML Statements
109+
110+
### 3.1 INSERT Statement
111+
- [ ] **INSERT INTO ... VALUES**
112+
- [ ] **INSERT INTO ... SELECT**
113+
- [ ] **INSERT INTO ... EXEC**
114+
- [ ] **DEFAULT VALUES**
115+
- [ ] **OUTPUT clause**
116+
117+
**Tests:** `InsertStatementTests`, related baselines
118+
119+
### 3.2 UPDATE Statement
120+
- [ ] **UPDATE ... SET**
121+
- [ ] **UPDATE with FROM clause**
122+
- [ ] **UPDATE with JOINs**
123+
- [ ] **OUTPUT clause**
124+
125+
**Tests:** `UpdateStatementTests`, related baselines
126+
127+
### 3.3 DELETE Statement
128+
- [ ] **DELETE FROM**
129+
- [ ] **DELETE with JOINs**
130+
- [ ] **OUTPUT clause**
131+
- [ ] **TRUNCATE TABLE**
132+
133+
**Tests:** `DeleteStatementTests`, `TruncateTableStatementTests`, related baselines
134+
135+
### 3.4 MERGE Statement
136+
- [ ] **MERGE ... USING ... ON**
137+
- [ ] **WHEN MATCHED / NOT MATCHED**
138+
- [ ] **OUTPUT clause**
139+
140+
**Tests:** `MergeStatementTests*`
141+
142+
---
143+
144+
## Phase 4: DDL Statements - Tables and Indexes
145+
146+
### 4.1 CREATE TABLE
147+
- [ ] **Column definitions**
148+
- [ ] **Data types** (all SQL Server types)
149+
- [ ] **Constraints** (PRIMARY KEY, FOREIGN KEY, UNIQUE, CHECK, DEFAULT)
150+
- [ ] **Computed columns**
151+
- [ ] **Temporal tables**
152+
- [ ] **Partitioning**
153+
154+
**Tests:** `CreateTableTests*`
155+
156+
### 4.2 ALTER TABLE
157+
- [ ] **ADD column**
158+
- [ ] **ALTER COLUMN**
159+
- [ ] **DROP COLUMN**
160+
- [ ] **ADD/DROP CONSTRAINT**
161+
162+
**Tests:** `AlterTableStatementTests*`
163+
164+
### 4.3 CREATE/ALTER/DROP INDEX
165+
- [ ] **Clustered/Nonclustered indexes**
166+
- [ ] **INCLUDE columns**
167+
- [ ] **WHERE clause (filtered)**
168+
- [ ] **Index options**
169+
170+
**Tests:** `CreateIndexStatementTests*`, `AlterIndexStatementTests*`
171+
172+
---
173+
174+
## Phase 5: Programmability
175+
176+
### 5.1 Variables and Control Flow
177+
- [ ] **DECLARE** - variables, table variables
178+
- [ ] **SET** - variable assignment
179+
- [ ] **IF...ELSE**
180+
- [ ] **WHILE**
181+
- [ ] **BEGIN...END blocks**
182+
- [ ] **TRY...CATCH**
183+
- [ ] **GOTO/LABEL**
184+
- [ ] **RETURN**
185+
- [ ] **WAITFOR**
186+
187+
**Tests:** `DeclareStatementTests`, `SetStatementTests`, `IfStatementTests`, `WhileStatementTests`, `TryCatchStatementTests`, etc.
188+
189+
### 5.2 Stored Procedures
190+
- [ ] **CREATE/ALTER PROCEDURE**
191+
- [ ] **EXECUTE/EXEC**
192+
- [ ] **Parameters (IN, OUT, DEFAULT)**
193+
- [ ] **WITH options** (RECOMPILE, ENCRYPTION, etc.)
194+
195+
**Tests:** `CreateProcedureStatementTests*`, `AlterProcedureStatementTests*`, `ExecuteStatementTests*`
196+
197+
### 5.3 Functions
198+
- [ ] **CREATE/ALTER FUNCTION**
199+
- [ ] **Scalar functions**
200+
- [ ] **Table-valued functions**
201+
- [ ] **Inline table-valued functions**
202+
203+
**Tests:** `CreateFunctionStatementTests*`, `AlterFunctionStatementTests*`
204+
205+
### 5.4 Triggers
206+
- [ ] **CREATE/ALTER TRIGGER**
207+
- [ ] **DML triggers**
208+
- [ ] **DDL triggers**
209+
- [ ] **Logon triggers**
210+
211+
**Tests:** `CreateTriggerStatementTests*`, `AlterTriggerStatementTests*`
212+
213+
---
214+
215+
## Phase 6: DDL Statements - Schema Objects
216+
217+
### 6.1 Views
218+
- [ ] **CREATE/ALTER VIEW**
219+
- [ ] **WITH CHECK OPTION**
220+
- [ ] **WITH SCHEMABINDING**
221+
222+
**Tests:** `CreateViewStatementTests*`, `AlterViewStatementTests*`
223+
224+
### 6.2 Schemas and Users
225+
- [ ] **CREATE/ALTER SCHEMA**
226+
- [ ] **CREATE/ALTER USER**
227+
- [ ] **CREATE/ALTER LOGIN**
228+
- [ ] **CREATE/ALTER ROLE**
229+
230+
**Tests:** `CreateSchemaStatementTests*`, `CreateUserStatementTests*`, etc.
231+
232+
### 6.3 Other DDL Objects
233+
- [ ] **Sequences**
234+
- [ ] **Synonyms**
235+
- [ ] **Types** (user-defined types)
236+
- [ ] **Assemblies**
237+
- [ ] **Certificates and Keys**
238+
- [ ] **Credentials**
239+
240+
---
241+
242+
## Phase 7: Database Management
243+
244+
### 7.1 Database Statements
245+
- [ ] **CREATE/ALTER DATABASE**
246+
- [ ] **DROP DATABASE**
247+
- [ ] **USE database**
248+
- [ ] **Database options**
249+
250+
**Tests:** `AlterCreateDatabaseStatementTests*`, `AlterDatabaseOptionsTests*`
251+
252+
### 7.2 Backup and Restore
253+
- [ ] **BACKUP DATABASE/LOG**
254+
- [ ] **RESTORE DATABASE/LOG**
255+
256+
**Tests:** `BackupStatementTests*`, `RestoreStatementTests*`
257+
258+
### 7.3 Server-level
259+
- [ ] **Server configuration**
260+
- [ ] **Endpoints**
261+
- [ ] **Linked servers**
262+
263+
---
264+
265+
## Phase 8: Advanced Features
266+
267+
### 8.1 Common Table Expressions (CTEs)
268+
- [ ] **WITH ... AS (SELECT ...)**
269+
- [ ] **Recursive CTEs**
270+
271+
**Tests:** `CTEStatementTests*`
272+
273+
### 8.2 XML Features
274+
- [ ] **FOR XML**
275+
- [ ] **OPENXML**
276+
- [ ] **XML methods** (query, value, nodes, etc.)
277+
278+
**Tests:** `ForXmlTests*`, `OpenXmlStatementTests*`
279+
280+
### 8.3 JSON Features (SQL 2016+)
281+
- [ ] **FOR JSON**
282+
- [ ] **OPENJSON**
283+
- [ ] **JSON functions**
284+
285+
**Tests:** `JsonFunctionTests*`
286+
287+
### 8.4 Fulltext Search
288+
- [ ] **CONTAINS**
289+
- [ ] **FREETEXT**
290+
- [ ] **Fulltext indexes**
291+
292+
**Tests:** `ContainsStatementTests*`, `FulltextTests*`
293+
294+
### 8.5 Spatial Data
295+
- [ ] **Geometry/Geography types**
296+
- [ ] **Spatial methods**
297+
298+
---
299+
300+
## Phase 9: Baseline Tests
301+
302+
Once statement types are implemented, unskip corresponding baseline tests:
303+
- `Baselines80_*` - SQL Server 2000
304+
- `Baselines90_*` - SQL Server 2005
305+
- `Baselines100_*` - SQL Server 2008
306+
- `Baselines110_*` - SQL Server 2012
307+
- `Baselines120_*` - SQL Server 2014
308+
- `Baselines130_*` - SQL Server 2016
309+
- `Baselines140_*` - SQL Server 2017
310+
- `Baselines150_*` - SQL Server 2019
311+
- `Baselines160_*` - SQL Server 2022
312+
- `Baselines170_*` - Future versions
313+
- `BaselinesCommon_*` - Common tests
314+
315+
---
316+
317+
## Implementation Strategy
318+
319+
### For Each Feature:
320+
321+
1. **Analyze test files** - Read the `query.sql` and `ast.json` for relevant tests
322+
2. **Implement lexer tokens** - Add any new tokens to `/parser/lexer.go`
323+
3. **Add AST types** - Create new files in `/ast/` for new node types
324+
4. **Implement parser** - Add parsing logic to `/parser/parser.go`
325+
5. **Add JSON marshaling** - Add `*ToJSON` functions in parser
326+
6. **Run tests** - Execute `go test ./parser/...`
327+
7. **Unskip tests** - Change `"skip": true` to `"skip": false` in `metadata.json`
328+
8. **Commit** - Commit changes with descriptive message
329+
330+
### Priority Order:
331+
332+
1. **High Priority** - Complete SELECT support (enables many baseline tests)
333+
2. **Medium Priority** - DML statements (INSERT, UPDATE, DELETE)
334+
3. **Medium Priority** - Control flow (IF, WHILE, TRY/CATCH)
335+
4. **Lower Priority** - Complex DDL (stored procedures, functions)
336+
5. **Lowest Priority** - Advanced features (XML, JSON, Fulltext)
337+
338+
---
339+
340+
## Success Metrics
341+
342+
- [ ] All 1,023 tests pass without skipping
343+
- [ ] All statement types properly generate matching AST JSON
344+
- [ ] No regressions in currently passing tests
345+
346+
---
347+
348+
## Notes
349+
350+
- Tests are organized in `testdata/` with related baselines prefixed by version
351+
- The parser uses a hand-written recursive descent approach
352+
- AST JSON format follows the Microsoft SqlScriptDOM conventions
353+
- Some tests may require version-specific behavior

ast/begin_end_block_statement.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package ast
2+
3+
// BeginEndBlockStatement represents a BEGIN...END block.
4+
type BeginEndBlockStatement struct {
5+
StatementList *StatementList `json:"StatementList,omitempty"`
6+
}
7+
8+
func (b *BeginEndBlockStatement) node() {}
9+
func (b *BeginEndBlockStatement) statement() {}
10+
11+
// StatementList is a list of statements.
12+
type StatementList struct {
13+
Statements []Statement `json:"Statements,omitempty"`
14+
}

ast/binary_query_expression.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package ast
2+
3+
// BinaryQueryExpression represents UNION, EXCEPT, or INTERSECT queries.
4+
type BinaryQueryExpression struct {
5+
BinaryQueryExpressionType string `json:"BinaryQueryExpressionType,omitempty"`
6+
All bool `json:"All"`
7+
FirstQueryExpression QueryExpression `json:"FirstQueryExpression,omitempty"`
8+
SecondQueryExpression QueryExpression `json:"SecondQueryExpression,omitempty"`
9+
OrderByClause *OrderByClause `json:"OrderByClause,omitempty"`
10+
}
11+
12+
func (*BinaryQueryExpression) node() {}
13+
func (*BinaryQueryExpression) queryExpression() {}

ast/break_statement.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package ast
2+
3+
// BreakStatement represents a BREAK statement.
4+
type BreakStatement struct{}
5+
6+
func (b *BreakStatement) node() {}
7+
func (b *BreakStatement) statement() {}

ast/continue_statement.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package ast
2+
3+
// ContinueStatement represents a CONTINUE statement.
4+
type ContinueStatement struct{}
5+
6+
func (c *ContinueStatement) node() {}
7+
func (c *ContinueStatement) statement() {}

0 commit comments

Comments
 (0)