Repository: tomarrell/lbadd
Pull request #83 (2020-03-18 08:46:50)

Implements more statements
This PR completes the implementation of many statements, as specified in #66.


Patch:
diff --git a/internal/parser/ast/statement.go b/internal/parser/ast/statement.go
index 6c61153..c3a00fb 100644
--- a/internal/parser/ast/statement.go
+++ b/internal/parser/ast/statement.go
@@ -604,9 +604,10 @@ type (
 		LeftParen      token.Token
 		BaseWindowName token.Token
 		Partition      token.Token
-		By             token.Token
+		By1            token.Token
 		Expr           []*Expr
 		Order          token.Token
+		By2            token.Token
 		OrderingTerm   []*OrderingTerm
 		FrameSpec      *FrameSpec
 		RightParen     token.Token
diff --git a/internal/parser/simple_parser_rules.go b/internal/parser/simple_parser_rules.go
index 7d8d12e..1da21f7 100644
--- a/internal/parser/simple_parser_rules.go
+++ b/internal/parser/simple_parser_rules.go
@@ -30,7 +30,7 @@ func (p *simpleParser) parseSQLStatement(r reporter) (stmt *ast.SQLStmt) {
 	}
 
 	// according to the grammar, these are the tokens that initiate a statement
-	p.searchNext(r, token.StatementSeparator, token.EOF, token.KeywordAlter, token.KeywordAnalyze, token.KeywordAttach, token.KeywordBegin, token.KeywordCommit, token.KeywordCreate, token.KeywordDelete, token.KeywordDetach, token.KeywordDrop, token.KeywordEnd, token.KeywordInsert, token.KeywordPragma, token.KeywordReindex, token.KeywordRelease, token.KeywordRollback, token.KeywordSavepoint, token.KeywordSelect, token.KeywordUpdate, token.KeywordVacuum)
+	p.searchNext(r, token.StatementSeparator, token.EOF, token.KeywordAlter, token.KeywordAnalyze, token.KeywordAttach, token.KeywordBegin, token.KeywordCommit, token.KeywordCreate, token.KeywordDelete, token.KeywordDetach, token.KeywordDrop, token.KeywordEnd, token.KeywordInsert, token.KeywordPragma, token.KeywordReindex, token.KeywordRelease, token.KeywordRollback, token.KeywordSavepoint, token.KeywordSelect, token.KeywordUpdate, token.KeywordWith, token.KeywordVacuum)
 
 	next, ok := p.unsafeLowLevelLookahead()
 	if !ok {
@@ -52,6 +52,8 @@ func (p *simpleParser) parseSQLStatement(r reporter) (stmt *ast.SQLStmt) {
 		stmt.CommitStmt = p.parseCommitStmt(r)
 	case token.KeywordCreate:
 		p.parseCreateStmt(stmt, r)
+	case token.KeywordDelete:
+		stmt.DeleteStmt = p.parseDeleteStmt(r)
 	case token.KeywordDetach:
 		stmt.DetachStmt = p.parseDetachDatabaseStmt(r)
 	case token.KeywordEnd:
@@ -60,6 +62,8 @@ func (p *simpleParser) parseSQLStatement(r reporter) (stmt *ast.SQLStmt) {
 		stmt.RollbackStmt = p.parseRollbackStmt(r)
 	case token.KeywordVacuum:
 		stmt.VacuumStmt = p.parseVacuumStmt(r)
+	case token.KeywordWith:
+		stmt.DeleteStmt = p.parseDeleteStmt(r)
 	case token.StatementSeparator:
 		r.incompleteStatement()
 		p.consumeToken()
@@ -87,7 +91,7 @@ func (p *simpleParser) parseSQLStatement(r reporter) (stmt *ast.SQLStmt) {
 			return
 		}
 	}
-	if next.Type() == token.EOF {
+	if next.Type() == token.EOF || next.Type() == token.StatementSeparator {
 		p.consumeToken()
 		return
 	}
@@ -786,7 +790,7 @@ func (p *simpleParser) parseAnalyzeStmt(r reporter) (stmt *ast.AnalyzeStmt) {
 
 	// optionalLookahead is used, because ANALYZE alone is a valid statement
 	next, ok = p.optionalLookahead(r)
-	if !ok || next.Type() == token.EOF {
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
 		return
 	}
 	if next.Type() == token.Literal {
@@ -835,7 +839,7 @@ func (p *simpleParser) parseBeginStmt(r reporter) (stmt *ast.BeginStmt) {
 	p.consumeToken()
 
 	next, ok = p.optionalLookahead(r)
-	if !ok || next.Type() == token.EOF {
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
 		return
 	}
 	switch next.Type() {
@@ -851,7 +855,7 @@ func (p *simpleParser) parseBeginStmt(r reporter) (stmt *ast.BeginStmt) {
 	}
 
 	next, ok = p.optionalLookahead(r)
-	if !ok || next.Type() == token.EOF {
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
 		return
 	}
 	if next.Type() == token.KeywordTransaction {
@@ -878,7 +882,7 @@ func (p *simpleParser) parseCommitStmt(r reporter) (stmt *ast.CommitStmt) {
 	p.consumeToken()
 
 	next, ok = p.optionalLookahead(r)
-	if !ok || next.Type() == token.EOF {
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
 		return
 	}
 	if next.Type() == token.KeywordTransaction {
@@ -901,7 +905,7 @@ func (p *simpleParser) parseRollbackStmt(r reporter) (stmt *ast.RollbackStmt) {
 	p.consumeToken()
 
 	next, ok = p.optionalLookahead(r)
-	if !ok || next.Type() == token.EOF {
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
 		return
 	}
 	if next.Type() == token.KeywordTransaction {
@@ -913,7 +917,7 @@ func (p *simpleParser) parseRollbackStmt(r reporter) (stmt *ast.RollbackStmt) {
 	// check whether TO also exists. Out of TRANSACTION and TO, each not
 	// existing and existing, we have the following logic.
 	next, ok = p.optionalLookahead(r)
-	if !ok || next.Type() == token.EOF {
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
 		return
 	}
 	if next.Type() == token.KeywordTo {
@@ -1131,7 +1135,7 @@ func (p *simpleParser) parseCreateIndexStmt(createToken token.Token, r reporter)
 	}
 
 	next, ok = p.optionalLookahead(r)
-	if !ok || next.Type() == token.EOF {
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
 		return
 	}
 	if next.Type() == token.KeywordWhere {
@@ -1156,7 +1160,7 @@ func (p *simpleParser) parseIndexedColumn(r reporter) (stmt *ast.IndexedColumn)
 	}
 
 	next, ok = p.optionalLookahead(r)
-	if !ok || next.Type() == token.EOF {
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
 		return
 	}
 	if next.Type() == token.KeywordCollate {
@@ -1175,7 +1179,7 @@ func (p *simpleParser) parseIndexedColumn(r reporter) (stmt *ast.IndexedColumn)
 	}
 
 	next, ok = p.optionalLookahead(r)
-	if !ok || next.Type() == token.EOF {
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
 		return
 	}
 	if next.Type() == token.KeywordAsc {
@@ -1228,3 +1232,1531 @@ func (p *simpleParser) parseCreateVirtualTableStmt(createToken token.Token, r re
 	p.searchNext(r, token.StatementSeparator, token.EOF)
 	return
 }
+
+// parseDeleteStmt parses the DELETE statement as defined in:
+// https://sqlite.org/lang_delete.html
+func (p *simpleParser) parseDeleteStmt(r reporter) (stmt *ast.DeleteStmt) {
+	stmt = &ast.DeleteStmt{}
+	next, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordWith {
+		stmt.WithClause = p.parseWithClause(r)
+	}
+	p.searchNext(r, token.KeywordDelete)
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	stmt.Delete = next
+	p.consumeToken()
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordFrom {
+		stmt.From = next
+		p.consumeToken()
+	} else {
+		r.unexpectedToken(token.KeywordFrom)
+	}
+	stmt.QualifiedTableName = p.parseQualifiedTableName(r)
+
+	next, ok = p.optionalLookahead(r)
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+		return
+	}
+	if next.Type() == token.KeywordWhere {
+		stmt.Where = next
+		p.consumeToken()
+		stmt.Expr = p.parseExpression(r)
+	}
+
+	return
+}
+
+// parseWithClause parses the WithClause as defined in:
+// https://sqlite.org/syntax/with-clause.html
+func (p *simpleParser) parseWithClause(r reporter) (withClause *ast.WithClause) {
+	withClause = &ast.WithClause{}
+	p.searchNext(r, token.KeywordWith)
+	next, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	withClause.With = next
+	p.consumeToken()
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordRecursive {
+		withClause.Recursive = next
+		p.consumeToken()
+	}
+	for {
+		withClause.RecursiveCte = append(withClause.RecursiveCte, p.parseRecursiveCte(r))
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Value() == "," {
+			p.consumeToken()
+		} else {
+			break
+		}
+	}
+	return
+}
+
+func (p *simpleParser) parseRecursiveCte(r reporter) (recursiveCte *ast.RecursiveCte) {
+	recursiveCte = &ast.RecursiveCte{}
+	recursiveCte.CteTableName = p.parseCteTableName(r)
+	next, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordAs {
+		recursiveCte.As = next
+		p.consumeToken()
+	} else {
+		r.unexpectedToken(token.KeywordAs)
+	}
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Value() == "(" {
+		recursiveCte.LeftParen = next
+		p.consumeToken()
+	} else {
+		r.unexpectedToken(token.Delimiter)
+	}
+	recursiveCte.SelectStmt = p.parseSelectStmt(r)
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Value() == ")" {
+		recursiveCte.RightParen = next
+		p.consumeToken()
+	} else {
+		r.unexpectedToken(token.Delimiter)
+	}
+	return
+}
+
+// parseCteTableName parses the cte-table-name stmt as defined in:
+//https://sqlite.org/syntax/cte-table-name.html
+func (p *simpleParser) parseCteTableName(r reporter) (cteTableName *ast.CteTableName) {
+	cteTableName = &ast.CteTableName{}
+	next, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	cteTableName.TableName = next
+	p.consumeToken()
+
+	next, ok = p.optionalLookahead(r)
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+		return
+	}
+	if next.Value() == "(" {
+		cteTableName.LeftParen = next
+		p.consumeToken()
+		for {
+			columnName, ok := p.lookahead(r)
+			if !ok {
+				return
+			}
+			if columnName.Type() == token.Literal {
+				cteTableName.ColumnName = append(cteTableName.ColumnName, columnName)
+				p.consumeToken()
+			} else {
+				r.unexpectedToken(token.Literal)
+			}
+
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Value() == "," {
+				p.consumeToken()
+			}
+
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Value() == ")" {
+				cteTableName.RightParen = next
+				p.consumeToken()
+				break
+			}
+		}
+	}
+	return
+}
+
+// parseSelectStmt parses the select stmt as defined in:
+// https://sqlite.org/syntax/select-stmt.html
+func (p *simpleParser) parseSelectStmt(r reporter) (stmt *ast.SelectStmt) {
+	stmt = &ast.SelectStmt{}
+	next, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordWith {
+		stmt.With = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordRecursive {
+			stmt.Recursive = next
+			p.consumeToken()
+		}
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.Literal {
+			for {
+				stmt.CommonTableExpression = append(stmt.CommonTableExpression, p.parseCommonTableExpression(r))
+				next, ok = p.lookahead(r)
+				if !ok {
+					return
+				}
+				if next.Value() == "," {
+					p.consumeToken()
+				} else {
+					break
+				}
+			}
+		} else {
+			r.unexpectedToken(token.Literal)
+		}
+	}
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	// Keep looping and searching for the select core until its exhausted.
+	// We are sure that a select core starts here as its the type of stmt we expect.
+	for {
+		if !(next.Type() == token.KeywordSelect || next.Type() == token.KeywordValues) {
+			break
+		}
+		stmt.SelectCore = append(stmt.SelectCore, p.parseSelectCore(r))
+
+		next, ok = p.optionalLookahead(r)
+		if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+			return
+		}
+	}
+
+	next, ok = p.optionalLookahead(r)
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+		return
+	}
+	if next.Type() == token.KeywordOrder {
+		stmt.Order = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordBy {
+			stmt.By = next
+			p.consumeToken()
+
+		} else {
+			r.unexpectedToken(token.KeywordBy)
+		}
+		for {
+			stmt.OrderingTerm = append(stmt.OrderingTerm, p.parseOrderingTerm(r))
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Value() == "," {
+				p.consumeToken()
+			} else {
+				break
+			}
+		}
+	}
+
+	next, ok = p.optionalLookahead(r)
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+		return
+	}
+	if next.Type() == token.KeywordLimit {
+		stmt.Limit = next
+		p.consumeToken()
+		stmt.Expr1 = p.parseExpression(r)
+
+		next, ok = p.optionalLookahead(r)
+		if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+			return
+		}
+		if next.Type() == token.KeywordOffset {
+			stmt.Offset = next
+			p.consumeToken()
+			stmt.Expr2 = p.parseExpression(r)
+		}
+		if next.Value() == "," {
+			stmt.Comma = next
+			p.consumeToken()
+			stmt.Expr2 = p.parseExpression(r)
+		}
+	}
+	return
+}
+
+// parseQualifiedTableName parses qualified-table-name as defined in:
+// https://sqlite.org/syntax/qualified-table-name.html
+func (p *simpleParser) parseQualifiedTableName(r reporter) (stmt *ast.QualifiedTableName) {
+	stmt = &ast.QualifiedTableName{}
+	schemaOrTableName, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	// We expect that the first literal can be either the schema name
+	// or the table name. When we confirm the existance of a period, we
+	// re-assign the table name and when we confirm that there is no
+	// period, we reset the schema name value to nil.
+	if schemaOrTableName.Type() == token.Literal {
+		stmt.TableName = schemaOrTableName
+		p.consumeToken()
+	}
+	next, ok := p.optionalLookahead(r)
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+		return
+	}
+	if next.Value() == "." {
+		stmt.Period = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.Literal {
+			stmt.SchemaName = schemaOrTableName
+			stmt.TableName = next
+			p.consumeToken()
+		} else {
+			r.unexpectedToken(token.Literal)
+		}
+	}
+
+	next, ok = p.optionalLookahead(r)
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+		return
+	}
+	if next.Type() == token.KeywordAs {
+		stmt.As = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.Literal {
+			stmt.Alias = next
+			p.consumeToken()
+		} else {
+			r.unexpectedToken(token.Literal)
+		}
+	}
+
+	next, ok = p.optionalLookahead(r)
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+		return
+	}
+	if next.Type() == token.KeywordIndexed {
+		stmt.Indexed = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordBy {
+			stmt.By = next
+			p.consumeToken()
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.Literal {
+				stmt.IndexName = next
+				p.consumeToken()
+			} else {
+				r.unexpectedToken(token.Literal)
+			}
+		} else {
+			r.unexpectedToken(token.KeywordBy)
+		}
+
+	}
+
+	next, ok = p.optionalLookahead(r)
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+		return
+	}
+	if next.Type() == token.KeywordNot {
+		stmt.Not = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordIndexed {
+			stmt.Indexed = next
+			p.consumeToken()
+		} else {
+			r.unexpectedToken(token.KeywordIndexed)
+		}
+	}
+	return
+}
+
+// parseCommonTableExpression parses common-table-expression as defined in:
+// https://sqlite.org/syntax/common-table-expression.html
+func (p *simpleParser) parseCommonTableExpression(r reporter) (stmt *ast.CommonTableExpression) {
+	stmt = &ast.CommonTableExpression{}
+	next, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.Literal {
+		stmt.TableName = next
+		p.consumeToken()
+	} else {
+		r.unexpectedToken(token.Literal)
+	}
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Value() == "(" {
+		stmt.LeftParen1 = next
+		p.consumeToken()
+		for {
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.Literal && next.Value() != "," {
+				stmt.ColumnName = append(stmt.ColumnName, next)
+				p.consumeToken()
+			}
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Value() == "," {
+				p.consumeToken()
+			}
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Value() == ")" {
+				stmt.RightParen1 = next
+				p.consumeToken()
+				break
+			}
+		}
+	}
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordAs {
+		stmt.As = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Value() == "(" {
+			stmt.LeftParen2 = next
+			p.consumeToken()
+			stmt.SelectStmt = p.parseSelectStmt(r)
+
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Value() == ")" {
+				stmt.RightParen2 = next
+				p.consumeToken()
+			}
+		}
+	}
+	return
+}
+
+// parseSelectCore parses a core block of the select statement.
+// The select stmt gets multiple select core stmts, where,
+// each select core can be either starting with a "SELECT" keyword
+// or a "VALUES" keyword. The compound operator belongs to the select core
+// stmt which is right before it and not the one after.
+// Due to a bit of controversy in the table-or-subquery and the join-clause
+// stmts after FROM in SELECT core, all statements are parsed into join-clause.
+func (p *simpleParser) parseSelectCore(r reporter) (stmt *ast.SelectCore) {
+	stmt = &ast.SelectCore{}
+	next, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordSelect {
+		stmt.Select = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordDistinct {
+			stmt.Distinct = next
+			p.consumeToken()
+		} else if next.Type() == token.KeywordAll {
+			stmt.All = next
+			p.consumeToken()
+		}
+
+		for {
+			stmt.ResultColumn = append(stmt.ResultColumn, p.parseResultColumn(r))
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Value() == "," {
+				p.consumeToken()
+			} else {
+				break
+			}
+		}
+
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordFrom {
+			stmt.From = next
+			p.consumeToken()
+			stmt.JoinClause = p.parseJoinClause(r)
+			if stmt.JoinClause == nil {
+				for {
+					stmt.TableOrSubquery = append(stmt.TableOrSubquery, p.parseTableOrSubquery(r))
+					next, ok = p.lookahead(r)
+					if !ok {
+						return
+					}
+					if next.Value() == "," {
+						p.consumeToken()
+					} else {
+						break
+					}
+				}
+			}
+		}
+
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordWhere {
+			stmt.Where = next
+			p.consumeToken()
+			stmt.Expr1 = p.parseExpression(r)
+		}
+
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordGroup {
+			stmt.Group = next
+			p.consumeToken()
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.KeywordBy {
+				stmt.By = next
+				p.consumeToken()
+			}
+			for {
+				stmt.Expr2 = append(stmt.Expr2, p.parseExpression(r))
+				next, ok = p.lookahead(r)
+				if !ok {
+					return
+				}
+				if next.Value() == "," {
+					p.consumeToken()
+				} else {
+					break
+				}
+			}
+
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.KeywordHaving {
+				stmt.Having = next
+				p.consumeToken()
+				stmt.Expr3 = p.parseExpression(r)
+			}
+		}
+
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordWindow {
+			// Consuming the keyword window
+			stmt.Window = next
+			p.consumeToken()
+			for {
+				stmt.NamedWindow = append(stmt.NamedWindow, p.parseNamedWindow(r))
+
+				next, ok = p.optionalLookahead(r)
+				if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+					return
+				}
+				if next.Value() == "," {
+					p.consumeToken()
+				} else {
+					break
+				}
+			}
+		}
+	}
+	if next.Type() == token.KeywordValues {
+		stmt.Values = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Value() == "(" {
+			for {
+				stmt.ParenthesizedExpressions = append(stmt.ParenthesizedExpressions, p.parseParenthesizeExpression(r))
+				next, ok = p.lookahead(r)
+				if !ok {
+					return
+				}
+				if next.Value() == "," {
+					p.consumeToken()
+				} else {
+					break
+				}
+			}
+		} else {
+			r.unexpectedSingleRuneToken('(')
+		}
+	}
+
+	// Checking whether there is a token that leads to a part of the statement
+	// ensures that stmt.CompoundOperator is nil, instead of an assigned empty value.
+	next, ok = p.optionalLookahead(r)
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+		return
+	}
+	if next.Type() == token.KeywordUnion || next.Type() == token.KeywordIntersect || next.Type() == token.KeywordExcept {
+		stmt.CompoundOperator = p.parseCompoundOperator(r)
+	}
+	return
+}
+
+// parseResultColumn parses result-column as defined in:
+// https://sqlite.org/syntax/result-column.html
+func (p *simpleParser) parseResultColumn(r reporter) (stmt *ast.ResultColumn) {
+	stmt = &ast.ResultColumn{}
+	tableNameOrAsteriskOrExpr, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	switch tableNameOrAsteriskOrExpr.Type() {
+	case token.BinaryOperator:
+		stmt.Asterisk = tableNameOrAsteriskOrExpr
+		p.consumeToken()
+	case token.Literal:
+		// Case where the expr can be a literal
+		stmt.Expr = p.parseExpression(r)
+		next, ok := p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Value() == "." {
+			stmt.TableName = tableNameOrAsteriskOrExpr
+			stmt.Expr = nil
+			stmt.Period = next
+			p.consumeToken()
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Value() == "*" {
+				stmt.Asterisk = next
+				p.consumeToken()
+			}
+		} else {
+			next, ok := p.optionalLookahead(r)
+			if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+				return
+			}
+			if next.Type() == token.KeywordAs {
+				stmt.As = next
+				p.consumeToken()
+			}
+
+			next, ok = p.optionalLookahead(r)
+			if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+				return
+			}
+			if next.Type() == token.Literal {
+				stmt.ColumnAlias = next
+				p.consumeToken()
+			}
+		}
+	default:
+		stmt.Expr = p.parseExpression(r)
+		next, ok := p.optionalLookahead(r)
+		if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+			return
+		}
+		if next.Type() == token.KeywordAs {
+			stmt.As = next
+			p.consumeToken()
+		}
+
+		next, ok = p.optionalLookahead(r)
+		if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+			return
+		}
+		if next.Type() == token.Literal {
+			stmt.ColumnAlias = next
+			p.consumeToken()
+		}
+	}
+	return
+}
+
+func (p *simpleParser) parseNamedWindow(r reporter) (stmt *ast.NamedWindow) {
+	stmt = &ast.NamedWindow{}
+	next, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.Literal {
+		stmt.WindowName = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordAs {
+			stmt.As = next
+			p.consumeToken()
+			stmt.WindowDefn = p.parseWindowDefn(r)
+		} else {
+			r.unexpectedToken(token.KeywordAs)
+		}
+	}
+	return
+}
+
+// parseWindowDefn parses window-defn as defined in:
+// https://sqlite.org/syntax/window-defn.html
+func (p *simpleParser) parseWindowDefn(r reporter) (stmt *ast.WindowDefn) {
+	stmt = &ast.WindowDefn{}
+	next, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Value() == "(" {
+		stmt.LeftParen = next
+		p.consumeToken()
+	}
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.Literal {
+		stmt.BaseWindowName = next
+		p.consumeToken()
+	}
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordPartition {
+		stmt.Partition = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordBy {
+			stmt.By1 = next
+			p.consumeToken()
+		} else {
+			r.unexpectedToken(token.KeywordBy)
+		}
+		for {
+			stmt.Expr = append(stmt.Expr, p.parseExpression(r))
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Value() == "," {
+				p.consumeToken()
+			} else {
+				break
+			}
+		}
+	}
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordOrder {
+		stmt.Order = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordBy {
+			stmt.By2 = next
+			p.consumeToken()
+		} else {
+			r.unexpectedToken(token.KeywordBy)
+		}
+		for {
+			stmt.OrderingTerm = append(stmt.OrderingTerm, p.parseOrderingTerm(r))
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Value() == "," {
+				p.consumeToken()
+			} else {
+				break
+			}
+		}
+	}
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordRange || next.Type() == token.KeywordRows || next.Type() == token.KeywordGroups {
+		stmt.FrameSpec = p.parseFrameSpec(r)
+	}
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Value() == ")" {
+		stmt.RightParen = next
+		p.consumeToken()
+	}
+	return
+}
+
+// parsesOrderingTerm parses ordering-term as defined in:
+// https://sqlite.org/syntax/ordering-term.html
+func (p *simpleParser) parseOrderingTerm(r reporter) (stmt *ast.OrderingTerm) {
+	stmt = &ast.OrderingTerm{}
+	stmt.Expr = p.parseExpression(r)
+
+	next, ok := p.optionalLookahead(r)
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+		return
+	}
+	if next.Type() == token.KeywordCollate {
+		stmt.Collate = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.Literal {
+			stmt.CollationName = next
+			p.consumeToken()
+		} else {
+			r.unexpectedToken(token.Literal)
+		}
+	}
+
+	next, ok = p.optionalLookahead(r)
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+		return
+	}
+	if next.Type() == token.KeywordAsc {
+		stmt.Asc = next
+		p.consumeToken()
+	}
+	if next.Type() == token.KeywordDesc {
+		stmt.Desc = next
+		p.consumeToken()
+	}
+
+	next, ok = p.optionalLookahead(r)
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+		return
+	}
+	if next.Type() == token.KeywordNulls {
+		stmt.Nulls = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordFirst {
+			stmt.First = next
+			p.consumeToken()
+		}
+		if next.Type() == token.KeywordLast {
+			stmt.Last = next
+			p.consumeToken()
+		}
+	}
+	return
+}
+
+// parseFrameSpec parses frame-spec as defined in:
+// https://sqlite.org/syntax/frame-spec.html
+func (p *simpleParser) parseFrameSpec(r reporter) (stmt *ast.FrameSpec) {
+	stmt = &ast.FrameSpec{}
+	next, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	switch next.Type() {
+	case token.KeywordRange:
+		stmt.Range = next
+		p.consumeToken()
+	case token.KeywordRows:
+		stmt.Rows = next
+		p.consumeToken()
+	case token.KeywordGroups:
+		stmt.Groups = next
+		p.consumeToken()
+	}
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	switch next.Type() {
+	case token.KeywordBetween:
+		stmt.Between = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		switch next.Type() {
+		case token.KeywordUnbounded:
+			stmt.Unbounded1 = next
+			p.consumeToken()
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.KeywordPreceding {
+				stmt.Preceding1 = next
+				p.consumeToken()
+			}
+		case token.KeywordCurrent:
+			stmt.Current1 = next
+			p.consumeToken()
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.KeywordRow {
+				// This is set as Row1 because this is one of the either paths
+				// taken by the FSM. Other path has 2x ROW's.
+				stmt.Row1 = next
+				p.consumeToken()
+			}
+		default:
+			stmt.Expr1 = p.parseExpression(r)
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.KeywordPreceding {
+				stmt.Preceding1 = next
+				p.consumeToken()
+			}
+			if next.Type() == token.KeywordFollowing {
+				stmt.Following1 = next
+				p.consumeToken()
+			}
+		}
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordAnd {
+			stmt.And = next
+			p.consumeToken()
+		}
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		switch next.Type() {
+		case token.KeywordUnbounded:
+			stmt.Unbounded2 = next
+			p.consumeToken()
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.KeywordFollowing {
+				stmt.Following2 = next
+				p.consumeToken()
+			}
+		case token.KeywordCurrent:
+			stmt.Current2 = next
+			p.consumeToken()
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.KeywordRow {
+				stmt.Row2 = next
+				p.consumeToken()
+			}
+		default:
+			stmt.Expr2 = p.parseExpression(r)
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.KeywordPreceding {
+				stmt.Preceding2 = next
+				p.consumeToken()
+			}
+			if next.Type() == token.KeywordFollowing {
+				stmt.Following2 = next
+				p.consumeToken()
+			}
+		}
+	case token.KeywordUnbounded:
+		stmt.Unbounded1 = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordPreceding {
+			stmt.Preceding1 = next
+			p.consumeToken()
+		}
+	case token.KeywordCurrent:
+		stmt.Current1 = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordRow {
+			stmt.Row1 = next
+			p.consumeToken()
+		}
+	default:
+		stmt.Expr1 = p.parseExpression(r)
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordPreceding {
+			stmt.Preceding1 = next
+			p.consumeToken()
+		}
+	}
+	next, ok = p.optionalLookahead(r)
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+		return
+	}
+	if next.Type() == token.KeywordExclude {
+		stmt.Exclude = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		switch next.Type() {
+		case token.KeywordNo:
+			stmt.No = next
+			p.consumeToken()
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.KeywordOthers {
+				stmt.Others = next
+				p.consumeToken()
+			}
+		case token.KeywordCurrent:
+			stmt.Current3 = next
+			p.consumeToken()
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.KeywordRow {
+				stmt.Row3 = next
+				p.consumeToken()
+			}
+		case token.KeywordGroup:
+			stmt.Group = next
+			p.consumeToken()
+		case token.KeywordTies:
+			stmt.Ties = next
+			p.consumeToken()
+		}
+	}
+	return
+}
+
+func (p *simpleParser) parseParenthesizeExpression(r reporter) (stmt *ast.ParenthesizedExpressions) {
+	stmt = &ast.ParenthesizedExpressions{}
+	next, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Value() == "(" {
+		stmt.LeftParen = next
+		p.consumeToken()
+		for {
+			stmt.Exprs = append(stmt.Exprs, p.parseExpression(r))
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Value() == ")" {
+				stmt.RightParen = next
+				p.consumeToken()
+				break
+			}
+			if next.Value() == "," {
+				p.consumeToken()
+			}
+		}
+	}
+	return
+}
+
+// parseCompoundOperator parses compound-operator as defined in:
+// https://sqlite.org/syntax/compound-operator.html
+func (p *simpleParser) parseCompoundOperator(r reporter) (stmt *ast.CompoundOperator) {
+	stmt = &ast.CompoundOperator{}
+	next, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordUnion {
+		stmt.Union = next
+		p.consumeToken()
+		next, ok = p.optionalLookahead(r)
+		if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+			return
+		}
+		if next.Type() == token.KeywordAll {
+			stmt.All = next
+			p.consumeToken()
+		}
+	}
+	if next.Type() == token.KeywordIntersect {
+		stmt.Intersect = next
+		p.consumeToken()
+	}
+	if next.Type() == token.KeywordExcept {
+		stmt.Except = next
+		p.consumeToken()
+	}
+	return
+}
+
+// parsetableOrSubquery parses table-or-subquery as defined in:
+// https://sqlite.org/syntax/table-or-subquery.html
+func (p *simpleParser) parseTableOrSubquery(r reporter) (stmt *ast.TableOrSubquery) {
+	stmt = &ast.TableOrSubquery{}
+	schemaOrTableNameOrLeftPar, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	if schemaOrTableNameOrLeftPar.Type() == token.Literal {
+		stmt.TableName = schemaOrTableNameOrLeftPar
+		p.consumeToken()
+
+		next, ok := p.optionalLookahead(r)
+		if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+			return
+		}
+		var tableNameOrTableFunctionName token.Token
+		if next.Value() == "." {
+			stmt.Period = next
+			p.consumeToken()
+			tableNameOrTableFunctionName, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.Literal {
+				stmt.SchemaName = schemaOrTableNameOrLeftPar
+				stmt.TableName = tableNameOrTableFunctionName
+				p.consumeToken()
+			} else {
+				r.unexpectedToken(token.Literal)
+			}
+		}
+
+		next, ok = p.optionalLookahead(r)
+		if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+			return
+		}
+		if next.Type() == token.KeywordAs || next.Type() == token.KeywordIndexed || next.Type() == token.Literal || next.Type() == token.KeywordNot {
+			if next.Type() == token.KeywordAs {
+				stmt.As = next
+				p.consumeToken()
+				next, ok = p.lookahead(r)
+				if !ok {
+					return
+				}
+				if next.Type() == token.Literal {
+					stmt.TableAlias = next
+					p.consumeToken()
+				} else {
+					r.unexpectedToken(token.Literal)
+				}
+			}
+			if next.Type() == token.Literal {
+				stmt.TableAlias = next
+				p.consumeToken()
+			}
+
+			next, ok = p.optionalLookahead(r)
+			if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+				return
+			}
+			if next.Type() == token.KeywordIndexed {
+				stmt.Indexed = next
+				p.consumeToken()
+				next, ok = p.lookahead(r)
+				if !ok {
+					return
+				}
+				if next.Type() == token.KeywordBy {
+					stmt.By = next
+					p.consumeToken()
+					next, ok = p.lookahead(r)
+					if !ok {
+						return
+					}
+					if next.Type() == token.Literal {
+						stmt.IndexName = next
+						p.consumeToken()
+					} else {
+						r.unexpectedToken(token.Literal)
+					}
+				} else {
+					r.unexpectedToken(token.KeywordBy)
+				}
+			}
+			if next.Type() == token.KeywordNot {
+				stmt.Not = next
+				p.consumeToken()
+				next, ok = p.lookahead(r)
+				if !ok {
+					return
+				}
+				if next.Type() == token.KeywordIndexed {
+					stmt.Indexed = next
+					p.consumeToken()
+				}
+			}
+		} else {
+			if next.Value() == "(" {
+				stmt.TableFunctionName = tableNameOrTableFunctionName
+				for {
+					// Since this rule allows an open bracket, we need to check whether an expr
+					// exists before we allow it to look for an expresion to avoid null ptr errors.
+					next, ok := p.lookahead(r)
+					if !ok {
+						return
+					}
+					if next.Value() == ")" {
+						stmt.RightParen = next
+						p.consumeToken()
+						break
+					}
+					stmt.Expr = append(stmt.Expr, p.parseExpression(r))
+					next, ok = p.lookahead(r)
+					if !ok {
+						return
+					}
+					if next.Value() == "," {
+						p.consumeToken()
+					}
+				}
+
+				next, ok = p.optionalLookahead(r)
+				if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+					return
+				}
+				if next.Type() == token.KeywordAs {
+					stmt.As = next
+					p.consumeToken()
+					next, ok = p.lookahead(r)
+					if !ok {
+						return
+					}
+					if next.Type() == token.Literal {
+						stmt.TableAlias = next
+						p.consumeToken()
+					}
+				}
+				if next.Type() == token.Literal {
+					stmt.TableAlias = next
+					p.consumeToken()
+				}
+			}
+		}
+	} else if schemaOrTableNameOrLeftPar.Value() == "(" {
+		stmt.SelectStmt = p.parseSelectStmt(r)
+		if stmt.SelectStmt == nil {
+			stmt.JoinClause = p.parseJoinClause(r)
+			if stmt.JoinClause == nil {
+				for {
+					stmt.TableOrSubquery = append(stmt.TableOrSubquery, p.parseTableOrSubquery(r))
+					next, ok := p.lookahead(r)
+					if !ok {
+						return
+					}
+					if next.Value() == "," {
+						p.consumeToken()
+					}
+					if next.Value() == ")" {
+						stmt.RightParen = next
+						p.consumeToken()
+						break
+					}
+				}
+			}
+			next, ok := p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Value() == ")" {
+				stmt.RightParen = next
+				p.consumeToken()
+				return
+			}
+		} else {
+			next, ok := p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Value() == ")" {
+				stmt.RightParen = next
+				p.consumeToken()
+			}
+
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.KeywordAs {
+				stmt.As = next
+				p.consumeToken()
+			}
+
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.Literal {
+				stmt.TableAlias = next
+				p.consumeToken()
+			}
+		}
+	}
+	return
+}
+
+// parseJoinClause parses join-clause as defined in:
+// https://sqlite.org/syntax/join-clause.html
+func (p *simpleParser) parseJoinClause(r reporter) (stmt *ast.JoinClause) {
+	stmt = &ast.JoinClause{}
+	stmt.TableOrSubquery = p.parseTableOrSubquery(r)
+
+	for {
+		next, ok := p.optionalLookahead(r)
+		if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+			return
+		}
+		if !((next.Type() == token.KeywordNatural) || (next.Type() == token.KeywordJoin) || (next.Value() == ",") || (next.Type() == token.KeywordLeft) || (next.Type() == token.KeywordInner) || (next.Type() == token.KeywordCross)) {
+			break
+		}
+		stmt.JoinClausePart = p.parseJoinClausePart(r)
+	}
+	return
+}
+
+func (p *simpleParser) parseJoinClausePart(r reporter) (stmt *ast.JoinClausePart) {
+	stmt = &ast.JoinClausePart{}
+	stmt.JoinOperator = p.parseJoinOperator(r)
+	stmt.TableOrSubquery = p.parseTableOrSubquery(r)
+	// This check for existance of join constraint is necessary to return a nil
+	// value of join constraint, before an empty value is assigned to it
+	next, ok := p.optionalLookahead(r)
+	if !ok || next.Type() == token.EOF || next.Type() == token.StatementSeparator {
+		return
+	}
+	if !(next.Type() == token.KeywordOn || next.Type() == token.KeywordUsing) {
+		return
+	}
+	stmt.JoinConstraint = p.parseJoinConstraint(r)
+	return
+}
+
+// parseJoinConstraint parses join-constraint as defined in:
+// https://sqlite.org/syntax/join-constraint.html
+func (p *simpleParser) parseJoinConstraint(r reporter) (stmt *ast.JoinConstraint) {
+	stmt = &ast.JoinConstraint{}
+	next, ok := p.optionalLookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordOn {
+		stmt.On = next
+		p.consumeToken()
+		stmt.Expr = p.parseExpression(r)
+	}
+	if next.Type() == token.KeywordUsing {
+		stmt.Using = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Value() == "(" {
+			stmt.LeftParen = next
+			p.consumeToken()
+		}
+		for {
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Type() == token.Literal {
+				stmt.ColumnName = append(stmt.ColumnName, next)
+				p.consumeToken()
+			}
+
+			next, ok = p.lookahead(r)
+			if !ok {
+				return
+			}
+			if next.Value() == "," {
+				p.consumeToken()
+			} else if next.Value() == ")" {
+				stmt.RightParen = next
+				p.consumeToken()
+				break
+			}
+		}
+	}
+	return
+}
+
+// parseJoinOperator parses join-operator as defined in:
+// https://sqlite.org/syntax/join-operator.html
+func (p *simpleParser) parseJoinOperator(r reporter) (stmt *ast.JoinOperator) {
+	stmt = &ast.JoinOperator{}
+	next, ok := p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Value() == "," {
+		stmt.Comma = next
+		p.consumeToken()
+		return
+	}
+	if next.Type() == token.KeywordJoin {
+		stmt.Join = next
+		p.consumeToken()
+		return
+	}
+	if next.Type() == token.KeywordNatural {
+		stmt.Natural = next
+		p.consumeToken()
+	}
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordLeft {
+		stmt.Left = next
+		p.consumeToken()
+		next, ok = p.lookahead(r)
+		if !ok {
+			return
+		}
+		if next.Type() == token.KeywordOuter {
+			stmt.Outer = next
+			p.consumeToken()
+		}
+	}
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordInner {
+		stmt.Inner = next
+		p.consumeToken()
+	}
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordCross {
+		stmt.Cross = next
+		p.consumeToken()
+	}
+
+	next, ok = p.lookahead(r)
+	if !ok {
+		return
+	}
+	if next.Type() == token.KeywordJoin {
+		stmt.Join = next
+		p.consumeToken()
+	}
+	return
+}


Test patch:
diff --git a/internal/parser/parser_test.go b/internal/parser/parser_test.go
index 42bb013..7e0f1a1 100644
--- a/internal/parser/parser_test.go
+++ b/internal/parser/parser_test.go
@@ -932,6 +932,3537 @@ func TestSingleStatementParse(t *testing.T) {
 				},
 			},
 		},
+		{
+			"DELETE basic",
+			"DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					Delete: token.New(1, 1, 0, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 8, 7, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 13, 12, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with WHERE and basic qualified table name",
+			"DELETE FROM myTable WHERE myLiteral",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					Delete: token.New(1, 1, 0, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 8, 7, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 13, 12, 7, token.Literal, "myTable"),
+					},
+					Where: token.New(1, 21, 20, 5, token.KeywordWhere, "WHERE"),
+					Expr: &ast.Expr{
+						LiteralValue: token.New(1, 27, 26, 9, token.Literal, "myLiteral"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with schema name and table name",
+			"DELETE FROM mySchema.myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					Delete: token.New(1, 1, 0, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 8, 7, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						SchemaName: token.New(1, 13, 12, 8, token.Literal, "mySchema"),
+						Period:     token.New(1, 21, 20, 1, token.Literal, "."),
+						TableName:  token.New(1, 22, 21, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with schema name, table name and AS",
+			"DELETE FROM mySchema.myTable AS newSchemaTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					Delete: token.New(1, 1, 0, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 8, 7, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						SchemaName: token.New(1, 13, 12, 8, token.Literal, "mySchema"),
+						Period:     token.New(1, 21, 20, 1, token.Literal, "."),
+						TableName:  token.New(1, 22, 21, 7, token.Literal, "myTable"),
+						As:         token.New(1, 30, 29, 2, token.KeywordAs, "AS"),
+						Alias:      token.New(1, 33, 32, 14, token.Literal, "newSchemaTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with schema name, table name, AS and INDEXED BY",
+			"DELETE FROM mySchema.myTable AS newSchemaTable INDEXED BY myIndex",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					Delete: token.New(1, 1, 0, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 8, 7, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						SchemaName: token.New(1, 13, 12, 8, token.Literal, "mySchema"),
+						Period:     token.New(1, 21, 20, 1, token.Literal, "."),
+						TableName:  token.New(1, 22, 21, 7, token.Literal, "myTable"),
+						As:         token.New(1, 30, 29, 2, token.KeywordAs, "AS"),
+						Alias:      token.New(1, 33, 32, 14, token.Literal, "newSchemaTable"),
+						Indexed:    token.New(1, 48, 47, 7, token.KeywordIndexed, "INDEXED"),
+						By:         token.New(1, 56, 55, 2, token.KeywordBy, "BY"),
+						IndexName:  token.New(1, 59, 58, 7, token.Literal, "myIndex"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with schema name, table name and NOT INDEXED",
+			"DELETE FROM mySchema.myTable NOT INDEXED",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					Delete: token.New(1, 1, 0, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 8, 7, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						SchemaName: token.New(1, 13, 12, 8, token.Literal, "mySchema"),
+						Period:     token.New(1, 21, 20, 1, token.Literal, "."),
+						TableName:  token.New(1, 22, 21, 7, token.Literal, "myTable"),
+						Not:        token.New(1, 30, 29, 3, token.KeywordNot, "NOT"),
+						Indexed:    token.New(1, 34, 33, 7, token.KeywordIndexed, "INDEXED"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, basic select stmt and basic cte-table-name",
+			"WITH myTable AS (SELECT *) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 26, 25, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 28, 27, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 35, 34, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 40, 39, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			`DELETE with "with clause" with RECURSIVE, basic select stmt and basic cte-table-name`,
+			"WITH RECURSIVE myTable AS (SELECT *) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With:      token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						Recursive: token.New(1, 6, 5, 9, token.KeywordRecursive, "RECURSIVE"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 16, 15, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 24, 23, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 27, 26, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 28, 27, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 35, 34, 1, token.BinaryOperator, "*"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 36, 35, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 38, 37, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 45, 44, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 50, 49, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			`DELETE with "with clause" with RECURSIVE, basic select stmt and cte-table-name with single col`,
+			"WITH RECURSIVE myTable (myCol) AS (SELECT *) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With:      token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						Recursive: token.New(1, 6, 5, 9, token.KeywordRecursive, "RECURSIVE"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 16, 15, 7, token.Literal, "myTable"),
+									LeftParen: token.New(1, 24, 23, 1, token.Delimiter, "("),
+									ColumnName: []token.Token{
+										token.New(1, 25, 24, 5, token.Literal, "myCol"),
+									},
+									RightParen: token.New(1, 30, 29, 1, token.Delimiter, ")"),
+								},
+								As:        token.New(1, 32, 31, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 35, 34, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 36, 35, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 43, 42, 1, token.BinaryOperator, "*"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 44, 43, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 46, 45, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 53, 52, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 58, 57, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			`DELETE with "with clause" with RECURSIVE, basic select stmt and cte-table-name with multiple cols`,
+			"WITH RECURSIVE myTable (myCol1,myCol2) AS (SELECT *) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With:      token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						Recursive: token.New(1, 6, 5, 9, token.KeywordRecursive, "RECURSIVE"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 16, 15, 7, token.Literal, "myTable"),
+									LeftParen: token.New(1, 24, 23, 1, token.Delimiter, "("),
+									ColumnName: []token.Token{
+										token.New(1, 25, 24, 6, token.Literal, "myCol1"),
+										token.New(1, 32, 31, 6, token.Literal, "myCol2"),
+									},
+									RightParen: token.New(1, 38, 37, 1, token.Delimiter, ")"),
+								},
+								As:        token.New(1, 40, 39, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 43, 42, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 44, 43, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 51, 50, 1, token.BinaryOperator, "*"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 52, 51, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 54, 53, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 61, 60, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 66, 65, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause,select stmt with WITH, basic common table expression and basic cte-table-name",
+			"WITH myTable AS (WITH myTable AS (SELECT *) SELECT *) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									With: token.New(1, 18, 17, 4, token.KeywordWith, "WITH"),
+									CommonTableExpression: []*ast.CommonTableExpression{
+										&ast.CommonTableExpression{
+											TableName:  token.New(1, 23, 22, 7, token.Literal, "myTable"),
+											As:         token.New(1, 31, 30, 2, token.KeywordAs, "AS"),
+											LeftParen2: token.New(1, 34, 33, 1, token.Delimiter, "("),
+											SelectStmt: &ast.SelectStmt{
+												SelectCore: []*ast.SelectCore{
+													&ast.SelectCore{
+														Select: token.New(1, 35, 34, 6, token.KeywordSelect, "SELECT"),
+														ResultColumn: []*ast.ResultColumn{
+															&ast.ResultColumn{
+																Asterisk: token.New(1, 42, 41, 1, token.BinaryOperator, "*"),
+															},
+														},
+													},
+												},
+											},
+											RightParen2: token.New(1, 43, 42, 1, token.Delimiter, ")"),
+										},
+									},
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 45, 44, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 52, 51, 1, token.BinaryOperator, "*"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 53, 52, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 55, 54, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 62, 61, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 67, 66, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause,select stmt with WITH, common table expression with single col and basic cte-table-name",
+			"WITH myTable AS (WITH myTable (myCol) AS (SELECT *) SELECT *) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									With: token.New(1, 18, 17, 4, token.KeywordWith, "WITH"),
+									CommonTableExpression: []*ast.CommonTableExpression{
+										&ast.CommonTableExpression{
+											TableName:  token.New(1, 23, 22, 7, token.Literal, "myTable"),
+											LeftParen1: token.New(1, 31, 30, 1, token.Delimiter, "("),
+											ColumnName: []token.Token{
+												token.New(1, 32, 31, 5, token.Literal, "myCol"),
+											},
+											RightParen1: token.New(1, 37, 36, 1, token.Delimiter, ")"),
+											As:          token.New(1, 39, 38, 2, token.KeywordAs, "AS"),
+											LeftParen2:  token.New(1, 42, 41, 1, token.Delimiter, "("),
+											SelectStmt: &ast.SelectStmt{
+												SelectCore: []*ast.SelectCore{
+													&ast.SelectCore{
+														Select: token.New(1, 43, 42, 6, token.KeywordSelect, "SELECT"),
+														ResultColumn: []*ast.ResultColumn{
+															&ast.ResultColumn{
+																Asterisk: token.New(1, 50, 49, 1, token.BinaryOperator, "*"),
+															},
+														},
+													},
+												},
+											},
+											RightParen2: token.New(1, 51, 50, 1, token.Delimiter, ")"),
+										},
+									},
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 53, 52, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 60, 59, 1, token.BinaryOperator, "*"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 61, 60, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 63, 62, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 70, 69, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 75, 74, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause,select stmt with WITH and RECURSIVE, basic common table expression and basic cte-table-name",
+			"WITH myTable AS (WITH RECURSIVE myTable AS (SELECT *) SELECT *) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									With:      token.New(1, 18, 17, 4, token.KeywordWith, "WITH"),
+									Recursive: token.New(1, 23, 22, 9, token.KeywordRecursive, "RECURSIVE"),
+									CommonTableExpression: []*ast.CommonTableExpression{
+										&ast.CommonTableExpression{
+											TableName:  token.New(1, 33, 32, 7, token.Literal, "myTable"),
+											As:         token.New(1, 41, 40, 2, token.KeywordAs, "AS"),
+											LeftParen2: token.New(1, 44, 43, 1, token.Delimiter, "("),
+											SelectStmt: &ast.SelectStmt{
+												SelectCore: []*ast.SelectCore{
+													&ast.SelectCore{
+														Select: token.New(1, 45, 44, 6, token.KeywordSelect, "SELECT"),
+														ResultColumn: []*ast.ResultColumn{
+															&ast.ResultColumn{
+																Asterisk: token.New(1, 52, 51, 1, token.BinaryOperator, "*"),
+															},
+														},
+													},
+												},
+											},
+											RightParen2: token.New(1, 53, 52, 1, token.Delimiter, ")"),
+										},
+									},
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 55, 54, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 62, 61, 1, token.BinaryOperator, "*"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 63, 62, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 65, 64, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 72, 71, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 77, 76, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause,select stmt with WITH, common table expression with multiple cols and basic cte-table-name",
+			"WITH myTable AS (WITH myTable (myCol1,myCol2) AS (SELECT *) SELECT *) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									With: token.New(1, 18, 17, 4, token.KeywordWith, "WITH"),
+									CommonTableExpression: []*ast.CommonTableExpression{
+										&ast.CommonTableExpression{
+											TableName:  token.New(1, 23, 22, 7, token.Literal, "myTable"),
+											LeftParen1: token.New(1, 31, 30, 1, token.Delimiter, "("),
+											ColumnName: []token.Token{
+												token.New(1, 32, 31, 6, token.Literal, "myCol1"),
+												token.New(1, 39, 38, 6, token.Literal, "myCol2"),
+											},
+											RightParen1: token.New(1, 45, 44, 1, token.Delimiter, ")"),
+											As:          token.New(1, 47, 46, 2, token.KeywordAs, "AS"),
+											LeftParen2:  token.New(1, 50, 49, 1, token.Delimiter, "("),
+											SelectStmt: &ast.SelectStmt{
+												SelectCore: []*ast.SelectCore{
+													&ast.SelectCore{
+														Select: token.New(1, 51, 50, 6, token.KeywordSelect, "SELECT"),
+														ResultColumn: []*ast.ResultColumn{
+															&ast.ResultColumn{
+																Asterisk: token.New(1, 58, 57, 1, token.BinaryOperator, "*"),
+															},
+														},
+													},
+												},
+											},
+											RightParen2: token.New(1, 59, 58, 1, token.Delimiter, ")"),
+										},
+									},
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 61, 60, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 68, 67, 1, token.BinaryOperator, "*"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 69, 68, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 71, 70, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 78, 77, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 83, 82, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with DISTINCT and basic cte-table-name",
+			"WITH myTable AS (SELECT DISTINCT *) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select:   token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											Distinct: token.New(1, 25, 24, 8, token.KeywordDistinct, "DISTINCT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 34, 33, 1, token.BinaryOperator, "*"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 35, 34, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 37, 36, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 44, 43, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 49, 48, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with ALL and basic cte-table-name",
+			"WITH myTable AS (SELECT ALL *) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											All:    token.New(1, 25, 24, 3, token.KeywordAll, "ALL"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 29, 28, 1, token.BinaryOperator, "*"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 30, 29, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 32, 31, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 39, 38, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 44, 43, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt's result column with table name and basic cte-table-name",
+			"WITH myTable AS (SELECT myTable.*) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													TableName: token.New(1, 25, 24, 7, token.Literal, "myTable"),
+													Period:    token.New(1, 32, 31, 1, token.Literal, "."),
+													Asterisk:  token.New(1, 33, 32, 1, token.BinaryOperator, "*"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 34, 33, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 36, 35, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 43, 42, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 48, 47, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt's result column with expr and basic cte-table-name",
+			"WITH myTable AS (SELECT myExpr) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Expr: &ast.Expr{
+														LiteralValue: token.New(1, 25, 24, 6, token.Literal, "myExpr"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 31, 30, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 33, 32, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 40, 39, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 45, 44, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt's result column with expr with column-alias and basic cte-table-name",
+			"WITH myTable AS (SELECT myExpr myColAlias) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Expr: &ast.Expr{
+														LiteralValue: token.New(1, 25, 24, 6, token.Literal, "myExpr"),
+													},
+													ColumnAlias: token.New(1, 32, 31, 10, token.Literal, "myColAlias"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 42, 41, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 44, 43, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 51, 50, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 56, 55, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt's result column with expr with column-alias and AS and basic cte-table-name",
+			"WITH myTable AS (SELECT myExpr AS myColAlias) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Expr: &ast.Expr{
+														LiteralValue: token.New(1, 25, 24, 6, token.Literal, "myExpr"),
+													},
+													As:          token.New(1, 32, 31, 2, token.KeywordAs, "AS"),
+													ColumnAlias: token.New(1, 35, 34, 10, token.Literal, "myColAlias"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 45, 44, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 47, 46, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 54, 53, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 59, 58, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with FROM with basic joinclause and basic cte-table-name",
+			"WITH myTable AS (SELECT * FROM myTable) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											From: token.New(1, 27, 26, 4, token.KeywordFrom, "FROM"),
+											JoinClause: &ast.JoinClause{
+												TableOrSubquery: &ast.TableOrSubquery{
+													TableName: token.New(1, 32, 31, 7, token.Literal, "myTable"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 39, 38, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 41, 40, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 48, 47, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 53, 52, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with FROM with joinclause's basic join constraint and basic cte-table-name",
+			"WITH myTable AS (SELECT * FROM myTable1,myTable2) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											From: token.New(1, 27, 26, 4, token.KeywordFrom, "FROM"),
+											JoinClause: &ast.JoinClause{
+												TableOrSubquery: &ast.TableOrSubquery{
+													TableName: token.New(1, 32, 31, 8, token.Literal, "myTable1"),
+												},
+												JoinClausePart: &ast.JoinClausePart{
+													JoinOperator: &ast.JoinOperator{
+														Comma: token.New(1, 40, 39, 1, token.Delimiter, ","),
+													},
+													TableOrSubquery: &ast.TableOrSubquery{
+														TableName: token.New(1, 41, 40, 8, token.Literal, "myTable2"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 49, 48, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 51, 50, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 58, 57, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 63, 62, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with FROM with joinclause's ON and basic cte-table-name",
+			"WITH myTable AS (SELECT * FROM myTable1,myTable2 ON myExpr) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											From: token.New(1, 27, 26, 4, token.KeywordFrom, "FROM"),
+											JoinClause: &ast.JoinClause{
+												TableOrSubquery: &ast.TableOrSubquery{
+													TableName: token.New(1, 32, 31, 8, token.Literal, "myTable1"),
+												},
+												JoinClausePart: &ast.JoinClausePart{
+													JoinOperator: &ast.JoinOperator{
+														Comma: token.New(1, 40, 39, 1, token.Delimiter, ","),
+													},
+													TableOrSubquery: &ast.TableOrSubquery{
+														TableName: token.New(1, 41, 40, 8, token.Literal, "myTable2"),
+													},
+													JoinConstraint: &ast.JoinConstraint{
+														On: token.New(1, 50, 49, 2, token.KeywordOn, "ON"),
+														Expr: &ast.Expr{
+															LiteralValue: token.New(1, 53, 52, 6, token.Literal, "myExpr"),
+														},
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 59, 58, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 61, 60, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 68, 67, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 73, 72, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with FROM with joinclause's USING and single Col and basic cte-table-name",
+			"WITH myTable AS (SELECT * FROM myTable1,myTable2 USING (myCol)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											From: token.New(1, 27, 26, 4, token.KeywordFrom, "FROM"),
+											JoinClause: &ast.JoinClause{
+												TableOrSubquery: &ast.TableOrSubquery{
+													TableName: token.New(1, 32, 31, 8, token.Literal, "myTable1"),
+												},
+												JoinClausePart: &ast.JoinClausePart{
+													JoinOperator: &ast.JoinOperator{
+														Comma: token.New(1, 40, 39, 1, token.Delimiter, ","),
+													},
+													TableOrSubquery: &ast.TableOrSubquery{
+														TableName: token.New(1, 41, 40, 8, token.Literal, "myTable2"),
+													},
+													JoinConstraint: &ast.JoinConstraint{
+														Using:     token.New(1, 50, 49, 5, token.KeywordUsing, "USING"),
+														LeftParen: token.New(1, 56, 55, 1, token.Delimiter, "("),
+														ColumnName: []token.Token{
+															token.New(1, 57, 56, 5, token.Literal, "myCol"),
+														},
+														RightParen: token.New(1, 62, 61, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 63, 62, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 65, 64, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 72, 71, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 77, 76, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with FROM with joinclause's USING and multiple Cols and basic cte-table-name",
+			"WITH myTable AS (SELECT * FROM myTable1,myTable2 USING (myCol1,myCol2)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											From: token.New(1, 27, 26, 4, token.KeywordFrom, "FROM"),
+											JoinClause: &ast.JoinClause{
+												TableOrSubquery: &ast.TableOrSubquery{
+													TableName: token.New(1, 32, 31, 8, token.Literal, "myTable1"),
+												},
+												JoinClausePart: &ast.JoinClausePart{
+													JoinOperator: &ast.JoinOperator{
+														Comma: token.New(1, 40, 39, 1, token.Delimiter, ","),
+													},
+													TableOrSubquery: &ast.TableOrSubquery{
+														TableName: token.New(1, 41, 40, 8, token.Literal, "myTable2"),
+													},
+													JoinConstraint: &ast.JoinConstraint{
+														Using:     token.New(1, 50, 49, 5, token.KeywordUsing, "USING"),
+														LeftParen: token.New(1, 56, 55, 1, token.Delimiter, "("),
+														ColumnName: []token.Token{
+															token.New(1, 57, 56, 6, token.Literal, "myCol1"),
+															token.New(1, 64, 63, 6, token.Literal, "myCol2"),
+														},
+														RightParen: token.New(1, 70, 69, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 71, 70, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 73, 72, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 80, 79, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 85, 84, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with FROM with joinclause's basic join constraint and JOIN and basic cte-table-name",
+			"WITH myTable AS (SELECT * FROM myTable1 JOIN myTable2) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											From: token.New(1, 27, 26, 4, token.KeywordFrom, "FROM"),
+											JoinClause: &ast.JoinClause{
+												TableOrSubquery: &ast.TableOrSubquery{
+													TableName: token.New(1, 32, 31, 8, token.Literal, "myTable1"),
+												},
+												JoinClausePart: &ast.JoinClausePart{
+													JoinOperator: &ast.JoinOperator{
+														Join: token.New(1, 41, 40, 4, token.KeywordJoin, "JOIN"),
+													},
+													TableOrSubquery: &ast.TableOrSubquery{
+														TableName: token.New(1, 46, 45, 8, token.Literal, "myTable2"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 54, 53, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 56, 55, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 63, 62, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 68, 67, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with FROM with joinclause's basic join constraint,NATURAL and JOIN in join operator and basic cte-table-name",
+			"WITH myTable AS (SELECT * FROM myTable1 NATURAL JOIN myTable2) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											From: token.New(1, 27, 26, 4, token.KeywordFrom, "FROM"),
+											JoinClause: &ast.JoinClause{
+												TableOrSubquery: &ast.TableOrSubquery{
+													TableName: token.New(1, 32, 31, 8, token.Literal, "myTable1"),
+												},
+												JoinClausePart: &ast.JoinClausePart{
+													JoinOperator: &ast.JoinOperator{
+														Natural: token.New(1, 41, 40, 7, token.KeywordNatural, "NATURAL"),
+														Join:    token.New(1, 49, 48, 4, token.KeywordJoin, "JOIN"),
+													},
+													TableOrSubquery: &ast.TableOrSubquery{
+														TableName: token.New(1, 54, 53, 8, token.Literal, "myTable2"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 62, 61, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 64, 63, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 71, 70, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 76, 75, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with FROM with joinclause's basic join constraint, LEFT and JOIN in join operator and basic cte-table-name",
+			"WITH myTable AS (SELECT * FROM myTable1 LEFT JOIN myTable2) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											From: token.New(1, 27, 26, 4, token.KeywordFrom, "FROM"),
+											JoinClause: &ast.JoinClause{
+												TableOrSubquery: &ast.TableOrSubquery{
+													TableName: token.New(1, 32, 31, 8, token.Literal, "myTable1"),
+												},
+												JoinClausePart: &ast.JoinClausePart{
+													JoinOperator: &ast.JoinOperator{
+														Left: token.New(1, 41, 40, 4, token.KeywordLeft, "LEFT"),
+														Join: token.New(1, 46, 45, 4, token.KeywordJoin, "JOIN"),
+													},
+													TableOrSubquery: &ast.TableOrSubquery{
+														TableName: token.New(1, 51, 50, 8, token.Literal, "myTable2"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 59, 58, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 61, 60, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 68, 67, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 73, 72, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with FROM with joinclause's basic join constraint, LEFT, OUTER and JOIN in join operator and basic cte-table-name",
+			"WITH myTable AS (SELECT * FROM myTable1 LEFT OUTER JOIN myTable2) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											From: token.New(1, 27, 26, 4, token.KeywordFrom, "FROM"),
+											JoinClause: &ast.JoinClause{
+												TableOrSubquery: &ast.TableOrSubquery{
+													TableName: token.New(1, 32, 31, 8, token.Literal, "myTable1"),
+												},
+												JoinClausePart: &ast.JoinClausePart{
+													JoinOperator: &ast.JoinOperator{
+														Left:  token.New(1, 41, 40, 4, token.KeywordLeft, "LEFT"),
+														Outer: token.New(1, 46, 45, 5, token.KeywordOuter, "OUTER"),
+														Join:  token.New(1, 52, 51, 4, token.KeywordJoin, "JOIN"),
+													},
+													TableOrSubquery: &ast.TableOrSubquery{
+														TableName: token.New(1, 57, 56, 8, token.Literal, "myTable2"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 65, 64, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 67, 66, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 74, 73, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 79, 78, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with FROM with joinclause's basic join constraint,INNER and JOIN in join operator and basic cte-table-name",
+			"WITH myTable AS (SELECT * FROM myTable1 INNER JOIN myTable2) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											From: token.New(1, 27, 26, 4, token.KeywordFrom, "FROM"),
+											JoinClause: &ast.JoinClause{
+												TableOrSubquery: &ast.TableOrSubquery{
+													TableName: token.New(1, 32, 31, 8, token.Literal, "myTable1"),
+												},
+												JoinClausePart: &ast.JoinClausePart{
+													JoinOperator: &ast.JoinOperator{
+														Inner: token.New(1, 41, 40, 5, token.KeywordInner, "INNER"),
+														Join:  token.New(1, 47, 46, 4, token.KeywordJoin, "JOIN"),
+													},
+													TableOrSubquery: &ast.TableOrSubquery{
+														TableName: token.New(1, 52, 51, 8, token.Literal, "myTable2"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 60, 59, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 62, 61, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 69, 68, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 74, 73, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with FROM with joinclause's basic join constraint,CROSS and JOIN in join operator and basic cte-table-name",
+			"WITH myTable AS (SELECT * FROM myTable1 CROSS JOIN myTable2) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											From: token.New(1, 27, 26, 4, token.KeywordFrom, "FROM"),
+											JoinClause: &ast.JoinClause{
+												TableOrSubquery: &ast.TableOrSubquery{
+													TableName: token.New(1, 32, 31, 8, token.Literal, "myTable1"),
+												},
+												JoinClausePart: &ast.JoinClausePart{
+													JoinOperator: &ast.JoinOperator{
+														Cross: token.New(1, 41, 40, 5, token.KeywordCross, "CROSS"),
+														Join:  token.New(1, 47, 46, 4, token.KeywordJoin, "JOIN"),
+													},
+													TableOrSubquery: &ast.TableOrSubquery{
+														TableName: token.New(1, 52, 51, 8, token.Literal, "myTable2"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 60, 59, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 62, 61, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 69, 68, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 74, 73, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WHERE and basic cte-table-name",
+			"WITH myTable AS (SELECT * WHERE myExpr) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Where: token.New(1, 27, 26, 5, token.KeywordWhere, "WHERE"),
+											Expr1: &ast.Expr{
+												LiteralValue: token.New(1, 33, 32, 6, token.Literal, "myExpr"),
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 39, 38, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 41, 40, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 48, 47, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 53, 52, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with GROUP BY and single expr, and basic cte-table-name",
+			"WITH myTable AS (SELECT * GROUP BY myExpr) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Group: token.New(1, 27, 26, 5, token.KeywordGroup, "GROUP"),
+											By:    token.New(1, 33, 32, 2, token.KeywordBy, "BY"),
+											Expr2: []*ast.Expr{
+												&ast.Expr{
+													LiteralValue: token.New(1, 36, 35, 6, token.Literal, "myExpr"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 42, 41, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 44, 43, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 51, 50, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 56, 55, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with GROUP BY and multiple expr, and basic cte-table-name",
+			"WITH myTable AS (SELECT * GROUP BY myExpr1,myExpr2) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Group: token.New(1, 27, 26, 5, token.KeywordGroup, "GROUP"),
+											By:    token.New(1, 33, 32, 2, token.KeywordBy, "BY"),
+											Expr2: []*ast.Expr{
+												&ast.Expr{
+													LiteralValue: token.New(1, 36, 35, 7, token.Literal, "myExpr1"),
+												},
+												&ast.Expr{
+													LiteralValue: token.New(1, 44, 43, 7, token.Literal, "myExpr2"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 51, 50, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 53, 52, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 60, 59, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 65, 64, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with GROUP BY, multiple expr and HAVING, and basic cte-table-name",
+			"WITH myTable AS (SELECT * GROUP BY myExpr1,myExpr2 HAVING myExpr3) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Group: token.New(1, 27, 26, 5, token.KeywordGroup, "GROUP"),
+											By:    token.New(1, 33, 32, 2, token.KeywordBy, "BY"),
+											Expr2: []*ast.Expr{
+												&ast.Expr{
+													LiteralValue: token.New(1, 36, 35, 7, token.Literal, "myExpr1"),
+												},
+												&ast.Expr{
+													LiteralValue: token.New(1, 44, 43, 7, token.Literal, "myExpr2"),
+												},
+											},
+											Having: token.New(1, 52, 51, 6, token.KeywordHaving, "HAVING"),
+											Expr3: &ast.Expr{
+												LiteralValue: token.New(1, 59, 58, 7, token.Literal, "myExpr3"),
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 66, 65, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 68, 67, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 75, 74, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 80, 79, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and basic WindowDefn and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS ()) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen:  token.New(1, 46, 45, 1, token.Delimiter, "("),
+														RightParen: token.New(1, 47, 46, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 48, 47, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 50, 49, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 57, 56, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 62, 61, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with basiWindowName, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (basicWindowName)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen:      token.New(1, 46, 45, 1, token.Delimiter, "("),
+														BaseWindowName: token.New(1, 47, 46, 15, token.Literal, "basicWindowName"),
+														RightParen:     token.New(1, 62, 61, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 63, 62, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 65, 64, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 72, 71, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 77, 76, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with PARTITION and single expr, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (PARTITION BY myExpr)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														Partition: token.New(1, 47, 46, 9, token.KeywordPartition, "PARTITION"),
+														By1:       token.New(1, 57, 56, 2, token.KeywordBy, "BY"),
+														Expr: []*ast.Expr{
+															&ast.Expr{
+																LiteralValue: token.New(1, 60, 59, 6, token.Literal, "myExpr"),
+															},
+														},
+														RightParen: token.New(1, 66, 65, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 67, 66, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 69, 68, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 76, 75, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 81, 80, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with PARTITION and multiple expr, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (PARTITION BY myExpr1,myExpr2)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														Partition: token.New(1, 47, 46, 9, token.KeywordPartition, "PARTITION"),
+														By1:       token.New(1, 57, 56, 2, token.KeywordBy, "BY"),
+														Expr: []*ast.Expr{
+															&ast.Expr{
+																LiteralValue: token.New(1, 60, 59, 7, token.Literal, "myExpr1"),
+															},
+															&ast.Expr{
+																LiteralValue: token.New(1, 68, 67, 7, token.Literal, "myExpr2"),
+															},
+														},
+														RightParen: token.New(1, 75, 74, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 76, 75, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 78, 77, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 85, 84, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 90, 89, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with ORDER BY and single basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (ORDER BY myExpr)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														Order:     token.New(1, 47, 46, 5, token.KeywordOrder, "ORDER"),
+														By2:       token.New(1, 53, 52, 2, token.KeywordBy, "BY"),
+														OrderingTerm: []*ast.OrderingTerm{
+															&ast.OrderingTerm{
+																Expr: &ast.Expr{
+																	LiteralValue: token.New(1, 56, 55, 6, token.Literal, "myExpr"),
+																},
+															},
+														},
+														RightParen: token.New(1, 62, 61, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 63, 62, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 65, 64, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 72, 71, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 77, 76, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with ORDER BY and multiple basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (ORDER BY myExpr1,myExpr2)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														Order:     token.New(1, 47, 46, 5, token.KeywordOrder, "ORDER"),
+														By2:       token.New(1, 53, 52, 2, token.KeywordBy, "BY"),
+														OrderingTerm: []*ast.OrderingTerm{
+															&ast.OrderingTerm{
+																Expr: &ast.Expr{
+																	LiteralValue: token.New(1, 56, 55, 7, token.Literal, "myExpr1"),
+																},
+															},
+															&ast.OrderingTerm{
+																Expr: &ast.Expr{
+																	LiteralValue: token.New(1, 64, 63, 7, token.Literal, "myExpr2"),
+																},
+															},
+														},
+														RightParen: token.New(1, 71, 70, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 72, 71, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 74, 73, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 81, 80, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 86, 85, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with ORDER BY, single basic ordering term and COLLATE, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (ORDER BY myExpr1 COLLATE myCollation)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														Order:     token.New(1, 47, 46, 5, token.KeywordOrder, "ORDER"),
+														By2:       token.New(1, 53, 52, 2, token.KeywordBy, "BY"),
+														OrderingTerm: []*ast.OrderingTerm{
+															&ast.OrderingTerm{
+																Expr: &ast.Expr{
+																	LiteralValue: token.New(1, 56, 55, 7, token.Literal, "myExpr1"),
+																},
+																Collate:       token.New(1, 64, 63, 7, token.KeywordCollate, "COLLATE"),
+																CollationName: token.New(1, 72, 71, 11, token.Literal, "myCollation"),
+															},
+														},
+														RightParen: token.New(1, 83, 82, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 84, 83, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 86, 85, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 93, 92, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 98, 97, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with ORDER BY, single basic ordering term and ASC, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (ORDER BY myExpr1 ASC)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														Order:     token.New(1, 47, 46, 5, token.KeywordOrder, "ORDER"),
+														By2:       token.New(1, 53, 52, 2, token.KeywordBy, "BY"),
+														OrderingTerm: []*ast.OrderingTerm{
+															&ast.OrderingTerm{
+																Expr: &ast.Expr{
+																	LiteralValue: token.New(1, 56, 55, 7, token.Literal, "myExpr1"),
+																},
+																Asc: token.New(1, 64, 63, 3, token.KeywordAsc, "ASC"),
+															},
+														},
+														RightParen: token.New(1, 67, 66, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 68, 67, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 70, 69, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 77, 76, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 82, 81, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with ORDER BY, single basic ordering term and DESC, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (ORDER BY myExpr1 DESC)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														Order:     token.New(1, 47, 46, 5, token.KeywordOrder, "ORDER"),
+														By2:       token.New(1, 53, 52, 2, token.KeywordBy, "BY"),
+														OrderingTerm: []*ast.OrderingTerm{
+															&ast.OrderingTerm{
+																Expr: &ast.Expr{
+																	LiteralValue: token.New(1, 56, 55, 7, token.Literal, "myExpr1"),
+																},
+																Desc: token.New(1, 64, 63, 4, token.KeywordDesc, "DESC"),
+															},
+														},
+														RightParen: token.New(1, 68, 67, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 69, 68, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 71, 70, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 78, 77, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 83, 82, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with ORDER BY, single basic ordering term and NULLS FIRST, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (ORDER BY myExpr1 NULLS FIRST)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														Order:     token.New(1, 47, 46, 5, token.KeywordOrder, "ORDER"),
+														By2:       token.New(1, 53, 52, 2, token.KeywordBy, "BY"),
+														OrderingTerm: []*ast.OrderingTerm{
+															&ast.OrderingTerm{
+																Expr: &ast.Expr{
+																	LiteralValue: token.New(1, 56, 55, 7, token.Literal, "myExpr1"),
+																},
+																Nulls: token.New(1, 64, 63, 5, token.KeywordNulls, "NULLS"),
+																First: token.New(1, 70, 69, 5, token.KeywordFirst, "FIRST"),
+															},
+														},
+														RightParen: token.New(1, 75, 74, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 76, 75, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 78, 77, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 85, 84, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 90, 89, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with ORDER BY, single basic ordering term and NULLS LAST, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (ORDER BY myExpr1 NULLS LAST)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														Order:     token.New(1, 47, 46, 5, token.KeywordOrder, "ORDER"),
+														By2:       token.New(1, 53, 52, 2, token.KeywordBy, "BY"),
+														OrderingTerm: []*ast.OrderingTerm{
+															&ast.OrderingTerm{
+																Expr: &ast.Expr{
+																	LiteralValue: token.New(1, 56, 55, 7, token.Literal, "myExpr1"),
+																},
+																Nulls: token.New(1, 64, 63, 5, token.KeywordNulls, "NULLS"),
+																Last:  token.New(1, 70, 69, 4, token.KeywordLast, "LAST"),
+															},
+														},
+														RightParen: token.New(1, 74, 73, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 75, 74, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 77, 76, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 84, 83, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 89, 88, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with basic frame spec with RANGE and single basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (RANGE UNBOUNDED PRECEDING)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														FrameSpec: &ast.FrameSpec{
+															Range:      token.New(1, 47, 46, 5, token.KeywordRange, "RANGE"),
+															Unbounded1: token.New(1, 53, 52, 9, token.KeywordUnbounded, "UNBOUNDED"),
+															Preceding1: token.New(1, 63, 62, 9, token.KeywordPreceding, "PRECEDING"),
+														},
+														RightParen: token.New(1, 72, 71, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 73, 72, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 75, 74, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 82, 81, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 87, 86, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with basic frame spec with ROWS and single basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (ROWS UNBOUNDED PRECEDING)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														FrameSpec: &ast.FrameSpec{
+															Rows:       token.New(1, 47, 46, 4, token.KeywordRows, "ROWS"),
+															Unbounded1: token.New(1, 52, 51, 9, token.KeywordUnbounded, "UNBOUNDED"),
+															Preceding1: token.New(1, 62, 61, 9, token.KeywordPreceding, "PRECEDING"),
+														},
+														RightParen: token.New(1, 71, 70, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 72, 71, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 74, 73, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 81, 80, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 86, 85, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with basic frame spec with GROUPS, UNBOUNDED PRECEDING and single basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (GROUPS UNBOUNDED PRECEDING)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														FrameSpec: &ast.FrameSpec{
+															Groups:     token.New(1, 47, 46, 6, token.KeywordGroups, "GROUPS"),
+															Unbounded1: token.New(1, 54, 53, 9, token.KeywordUnbounded, "UNBOUNDED"),
+															Preceding1: token.New(1, 64, 63, 9, token.KeywordPreceding, "PRECEDING"),
+														},
+														RightParen: token.New(1, 73, 72, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 74, 73, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 76, 75, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 83, 82, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 88, 87, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with basic frame spec with RANGE and expr PRECEDING and single basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (RANGE myLiteral PRECEDING)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														FrameSpec: &ast.FrameSpec{
+															Range: token.New(1, 47, 46, 5, token.KeywordRange, "RANGE"),
+															Expr1: &ast.Expr{
+																LiteralValue: token.New(1, 53, 52, 9, token.Literal, "myLiteral"),
+															},
+															Preceding1: token.New(1, 63, 62, 9, token.KeywordPreceding, "PRECEDING"),
+														},
+														RightParen: token.New(1, 72, 71, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 73, 72, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 75, 74, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 82, 81, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 87, 86, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with basic frame spec with RANGE and CURRENT ROW and single basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (RANGE CURRENT ROW)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														FrameSpec: &ast.FrameSpec{
+															Range:    token.New(1, 47, 46, 5, token.KeywordRange, "RANGE"),
+															Current1: token.New(1, 53, 52, 7, token.KeywordCurrent, "CURRENT"),
+															Row1:     token.New(1, 61, 60, 3, token.KeywordRow, "ROW"),
+														},
+														RightParen: token.New(1, 64, 63, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 65, 64, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 67, 66, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 74, 73, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 79, 78, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with basic frame spec with GROUPS, BETWEEN UNBOUNDED PRECEDING, AND, expr PRECEDING and single basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (GROUPS BETWEEN UNBOUNDED PRECEDING AND myLiteral PRECEDING)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														FrameSpec: &ast.FrameSpec{
+															Groups:     token.New(1, 47, 46, 6, token.KeywordGroups, "GROUPS"),
+															Between:    token.New(1, 54, 53, 7, token.KeywordBetween, "BETWEEN"),
+															Unbounded1: token.New(1, 62, 61, 9, token.KeywordUnbounded, "UNBOUNDED"),
+															Preceding1: token.New(1, 72, 71, 9, token.KeywordPreceding, "PRECEDING"),
+															And:        token.New(1, 82, 81, 3, token.KeywordAnd, "AND"),
+															Expr2: &ast.Expr{
+																LiteralValue: token.New(1, 86, 85, 9, token.Literal, "myLiteral"),
+															},
+															Preceding2: token.New(1, 96, 95, 9, token.KeywordPreceding, "PRECEDING"),
+														},
+														RightParen: token.New(1, 105, 104, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 106, 105, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 108, 107, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 115, 114, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 120, 119, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with basic frame spec with RANGE, BETWEEN and expr PRECEDING, AND, expr FOLLOWING and single basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (RANGE BETWEEN myLiteral PRECEDING AND myExpr FOLLOWING)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														FrameSpec: &ast.FrameSpec{
+															Range:   token.New(1, 47, 46, 5, token.KeywordRange, "RANGE"),
+															Between: token.New(1, 53, 52, 7, token.KeywordBetween, "BETWEEN"),
+															Expr1: &ast.Expr{
+																LiteralValue: token.New(1, 61, 60, 9, token.Literal, "myLiteral"),
+															},
+															Preceding1: token.New(1, 71, 70, 9, token.KeywordPreceding, "PRECEDING"),
+															And:        token.New(1, 81, 80, 3, token.KeywordAnd, "AND"),
+															Expr2: &ast.Expr{
+																LiteralValue: token.New(1, 85, 84, 6, token.Literal, "myExpr"),
+															},
+															Following2: token.New(1, 92, 91, 9, token.KeywordFollowing, "FOLLOWING"),
+														},
+														RightParen: token.New(1, 101, 100, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 102, 101, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 104, 103, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 111, 110, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 116, 115, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with basic frame spec with RANGE, BETWEEEN, CURRENT ROW, AND and UNBOUNDED FOLLOWING, and single basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														FrameSpec: &ast.FrameSpec{
+															Range:      token.New(1, 47, 46, 5, token.KeywordRange, "RANGE"),
+															Between:    token.New(1, 53, 52, 7, token.KeywordBetween, "BETWEEN"),
+															Current1:   token.New(1, 61, 60, 7, token.KeywordCurrent, "CURRENT"),
+															Row1:       token.New(1, 69, 68, 3, token.KeywordRow, "ROW"),
+															And:        token.New(1, 73, 72, 3, token.KeywordAnd, "AND"),
+															Unbounded2: token.New(1, 77, 76, 9, token.KeywordUnbounded, "UNBOUNDED"),
+															Following2: token.New(1, 87, 86, 9, token.KeywordFollowing, "FOLLOWING"),
+														},
+														RightParen: token.New(1, 96, 95, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 97, 96, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 99, 98, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 106, 105, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 111, 110, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with basic frame spec with RANGE, BETWEEEN, expr FOLLOWING, AND and CURRENT ROW, and single basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (RANGE BETWEEN myExpr FOLLOWING AND CURRENT ROW)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														FrameSpec: &ast.FrameSpec{
+															Range:   token.New(1, 47, 46, 5, token.KeywordRange, "RANGE"),
+															Between: token.New(1, 53, 52, 7, token.KeywordBetween, "BETWEEN"),
+															Expr1: &ast.Expr{
+																LiteralValue: token.New(1, 61, 60, 6, token.Literal, "myExpr"),
+															},
+															Following1: token.New(1, 68, 67, 9, token.KeywordFollowing, "FOLLOWING"),
+															And:        token.New(1, 78, 77, 3, token.KeywordAnd, "AND"),
+															Current2:   token.New(1, 82, 81, 7, token.KeywordCurrent, "CURRENT"),
+															Row2:       token.New(1, 90, 89, 3, token.KeywordRow, "ROW"),
+														},
+														RightParen: token.New(1, 93, 92, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 94, 93, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 96, 95, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 103, 102, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 108, 107, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with basic frame spec with RANGE, EXCLUDE NO OTHERS and single basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (RANGE UNBOUNDED PRECEDING EXCLUDE NO OTHERS)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														FrameSpec: &ast.FrameSpec{
+															Range:      token.New(1, 47, 46, 5, token.KeywordRange, "RANGE"),
+															Unbounded1: token.New(1, 53, 52, 9, token.KeywordUnbounded, "UNBOUNDED"),
+															Preceding1: token.New(1, 63, 62, 9, token.KeywordPreceding, "PRECEDING"),
+															Exclude:    token.New(1, 73, 72, 7, token.KeywordExclude, "EXCLUDE"),
+															No:         token.New(1, 81, 80, 2, token.KeywordNo, "NO"),
+															Others:     token.New(1, 84, 83, 6, token.KeywordOthers, "OTHERS"),
+														},
+														RightParen: token.New(1, 90, 89, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 91, 90, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 93, 92, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 100, 99, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 105, 104, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with basic frame spec with RANGE, EXCLUDE CURRENT ROW and single basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (RANGE UNBOUNDED PRECEDING EXCLUDE CURRENT ROW)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														FrameSpec: &ast.FrameSpec{
+															Range:      token.New(1, 47, 46, 5, token.KeywordRange, "RANGE"),
+															Unbounded1: token.New(1, 53, 52, 9, token.KeywordUnbounded, "UNBOUNDED"),
+															Preceding1: token.New(1, 63, 62, 9, token.KeywordPreceding, "PRECEDING"),
+															Exclude:    token.New(1, 73, 72, 7, token.KeywordExclude, "EXCLUDE"),
+															Current3:   token.New(1, 81, 80, 7, token.KeywordCurrent, "CURRENT"),
+															Row3:       token.New(1, 89, 88, 3, token.KeywordRow, "ROW"),
+														},
+														RightParen: token.New(1, 92, 91, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 93, 92, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 95, 94, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 102, 101, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 107, 106, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with basic frame spec with RANGE, EXCLUDE GROUP and single basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (RANGE UNBOUNDED PRECEDING EXCLUDE GROUP)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														FrameSpec: &ast.FrameSpec{
+															Range:      token.New(1, 47, 46, 5, token.KeywordRange, "RANGE"),
+															Unbounded1: token.New(1, 53, 52, 9, token.KeywordUnbounded, "UNBOUNDED"),
+															Preceding1: token.New(1, 63, 62, 9, token.KeywordPreceding, "PRECEDING"),
+															Exclude:    token.New(1, 73, 72, 7, token.KeywordExclude, "EXCLUDE"),
+															Group:      token.New(1, 81, 80, 5, token.KeywordGroup, "GROUP"),
+														},
+														RightParen: token.New(1, 86, 85, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 87, 86, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 89, 88, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 96, 95, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 101, 100, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with basic frame spec with RANGE, EXCLUDE TIES and single basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (RANGE UNBOUNDED PRECEDING EXCLUDE TIES)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														FrameSpec: &ast.FrameSpec{
+															Range:      token.New(1, 47, 46, 5, token.KeywordRange, "RANGE"),
+															Unbounded1: token.New(1, 53, 52, 9, token.KeywordUnbounded, "UNBOUNDED"),
+															Preceding1: token.New(1, 63, 62, 9, token.KeywordPreceding, "PRECEDING"),
+															Exclude:    token.New(1, 73, 72, 7, token.KeywordExclude, "EXCLUDE"),
+															Ties:       token.New(1, 81, 80, 4, token.KeywordTies, "TIES"),
+														},
+														RightParen: token.New(1, 85, 84, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 86, 85, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 88, 87, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 95, 94, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 100, 99, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, select stmt with WINDOW and WindowDefn with basic frame spec with RANGE and CURRENT ROW and single basic ordering term, and basic cte-table-name",
+			"WITH myTable AS (SELECT * WINDOW myWindow AS (PARTITION BY myExpr1 ORDER BY myExpr2 RANGE CURRENT ROW)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											Window: token.New(1, 27, 26, 6, token.KeywordWindow, "WINDOW"),
+											NamedWindow: []*ast.NamedWindow{
+												&ast.NamedWindow{
+													WindowName: token.New(1, 34, 33, 8, token.Literal, "myWindow"),
+													As:         token.New(1, 43, 42, 2, token.KeywordAs, "AS"),
+													WindowDefn: &ast.WindowDefn{
+														LeftParen: token.New(1, 46, 45, 1, token.Delimiter, "("),
+														Partition: token.New(1, 47, 46, 9, token.KeywordPartition, "PARTITION"),
+														By1:       token.New(1, 57, 56, 2, token.KeywordBy, "BY"),
+														Expr: []*ast.Expr{
+															&ast.Expr{
+																LiteralValue: token.New(1, 60, 59, 7, token.Literal, "myExpr1"),
+															},
+														},
+														Order: token.New(1, 68, 67, 5, token.KeywordOrder, "ORDER"),
+														By2:   token.New(1, 74, 73, 2, token.KeywordBy, "BY"),
+														OrderingTerm: []*ast.OrderingTerm{
+															&ast.OrderingTerm{
+																Expr: &ast.Expr{
+																	LiteralValue: token.New(1, 77, 76, 7, token.Literal, "myExpr2"),
+																},
+															},
+														},
+														FrameSpec: &ast.FrameSpec{
+															Range:    token.New(1, 85, 84, 5, token.KeywordRange, "RANGE"),
+															Current1: token.New(1, 91, 90, 7, token.KeywordCurrent, "CURRENT"),
+															Row1:     token.New(1, 99, 98, 3, token.KeywordRow, "ROW"),
+														},
+														RightParen: token.New(1, 102, 101, 1, token.Delimiter, ")"),
+													},
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 103, 102, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 105, 104, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 112, 111, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 117, 116, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, VALUES with single expr with single set, and basic cte-table-name",
+			"WITH myTable AS (VALUES (myExpr)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Values: token.New(1, 18, 17, 6, token.KeywordValues, "VALUES"),
+											ParenthesizedExpressions: []*ast.ParenthesizedExpressions{
+												&ast.ParenthesizedExpressions{
+													LeftParen: token.New(1, 25, 24, 1, token.Delimiter, "("),
+													Exprs: []*ast.Expr{
+														&ast.Expr{
+															LiteralValue: token.New(1, 26, 25, 6, token.Literal, "myExpr"),
+														},
+													},
+													RightParen: token.New(1, 32, 31, 1, token.Delimiter, ")"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 33, 32, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 35, 34, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 42, 41, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 47, 46, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, VALUES with multiple expr with single set, and basic cte-table-name",
+			"WITH myTable AS (VALUES (myExpr1,myExpr2)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Values: token.New(1, 18, 17, 6, token.KeywordValues, "VALUES"),
+											ParenthesizedExpressions: []*ast.ParenthesizedExpressions{
+												&ast.ParenthesizedExpressions{
+													LeftParen: token.New(1, 25, 24, 1, token.Delimiter, "("),
+													Exprs: []*ast.Expr{
+														&ast.Expr{
+															LiteralValue: token.New(1, 26, 25, 7, token.Literal, "myExpr1"),
+														},
+														&ast.Expr{
+															LiteralValue: token.New(1, 34, 33, 7, token.Literal, "myExpr2"),
+														},
+													},
+													RightParen: token.New(1, 41, 40, 1, token.Delimiter, ")"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 42, 41, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 44, 43, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 51, 50, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 56, 55, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, VALUES with multiple expr with multiple sets, and basic cte-table-name",
+			"WITH myTable AS (VALUES (myExpr1,myExpr2),(myExpr1,myExpr2)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Values: token.New(1, 18, 17, 6, token.KeywordValues, "VALUES"),
+											ParenthesizedExpressions: []*ast.ParenthesizedExpressions{
+												&ast.ParenthesizedExpressions{
+													LeftParen: token.New(1, 25, 24, 1, token.Delimiter, "("),
+													Exprs: []*ast.Expr{
+														&ast.Expr{
+															LiteralValue: token.New(1, 26, 25, 7, token.Literal, "myExpr1"),
+														},
+														&ast.Expr{
+															LiteralValue: token.New(1, 34, 33, 7, token.Literal, "myExpr2"),
+														},
+													},
+													RightParen: token.New(1, 41, 40, 1, token.Delimiter, ")"),
+												},
+												&ast.ParenthesizedExpressions{
+													LeftParen: token.New(1, 43, 42, 1, token.Delimiter, "("),
+													Exprs: []*ast.Expr{
+														&ast.Expr{
+															LiteralValue: token.New(1, 44, 43, 7, token.Literal, "myExpr1"),
+														},
+														&ast.Expr{
+															LiteralValue: token.New(1, 52, 51, 7, token.Literal, "myExpr2"),
+														},
+													},
+													RightParen: token.New(1, 59, 58, 1, token.Delimiter, ")"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 60, 59, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 62, 61, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 69, 68, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 74, 73, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, basic VALUES and basic SELECT with UNION compound operator, and basic cte-table-name",
+			"WITH myTable AS (SELECT * UNION VALUES (myExpr1)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											CompoundOperator: &ast.CompoundOperator{
+												Union: token.New(1, 27, 26, 5, token.KeywordUnion, "UNION"),
+											},
+										},
+										&ast.SelectCore{
+
+											Values: token.New(1, 33, 32, 6, token.KeywordValues, "VALUES"),
+											ParenthesizedExpressions: []*ast.ParenthesizedExpressions{
+												&ast.ParenthesizedExpressions{
+													LeftParen: token.New(1, 40, 39, 1, token.Delimiter, "("),
+													Exprs: []*ast.Expr{
+														&ast.Expr{
+															LiteralValue: token.New(1, 41, 40, 7, token.Literal, "myExpr1"),
+														},
+													},
+													RightParen: token.New(1, 48, 47, 1, token.Delimiter, ")"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 49, 48, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 51, 50, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 58, 57, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 63, 62, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, basic VALUES and basic SELECT with UNION ALL compound operator, and basic cte-table-name",
+			"WITH myTable AS (SELECT * UNION ALL VALUES (myExpr1)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											CompoundOperator: &ast.CompoundOperator{
+												Union: token.New(1, 27, 26, 5, token.KeywordUnion, "UNION"),
+												All:   token.New(1, 33, 32, 3, token.KeywordAll, "ALL"),
+											},
+										},
+										&ast.SelectCore{
+
+											Values: token.New(1, 37, 36, 6, token.KeywordValues, "VALUES"),
+											ParenthesizedExpressions: []*ast.ParenthesizedExpressions{
+												&ast.ParenthesizedExpressions{
+													LeftParen: token.New(1, 44, 43, 1, token.Delimiter, "("),
+													Exprs: []*ast.Expr{
+														&ast.Expr{
+															LiteralValue: token.New(1, 45, 44, 7, token.Literal, "myExpr1"),
+														},
+													},
+													RightParen: token.New(1, 52, 51, 1, token.Delimiter, ")"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 53, 52, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 55, 54, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 62, 61, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 67, 66, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, basic VALUES and basic SELECT with INTERSECT compound operator, and basic cte-table-name",
+			"WITH myTable AS (SELECT * INTERSECT VALUES (myExpr1)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											CompoundOperator: &ast.CompoundOperator{
+												Intersect: token.New(1, 27, 26, 9, token.KeywordIntersect, "INTERSECT"),
+											},
+										},
+										&ast.SelectCore{
+
+											Values: token.New(1, 37, 36, 6, token.KeywordValues, "VALUES"),
+											ParenthesizedExpressions: []*ast.ParenthesizedExpressions{
+												&ast.ParenthesizedExpressions{
+													LeftParen: token.New(1, 44, 43, 1, token.Delimiter, "("),
+													Exprs: []*ast.Expr{
+														&ast.Expr{
+															LiteralValue: token.New(1, 45, 44, 7, token.Literal, "myExpr1"),
+														},
+													},
+													RightParen: token.New(1, 52, 51, 1, token.Delimiter, ")"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 53, 52, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 55, 54, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 62, 61, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 67, 66, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, basic VALUES and basic SELECT with EXCEPT compound operator, and basic cte-table-name",
+			"WITH myTable AS (SELECT * EXCEPT VALUES (myExpr1)) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+											CompoundOperator: &ast.CompoundOperator{
+												Except: token.New(1, 27, 26, 6, token.KeywordExcept, "EXCEPT"),
+											},
+										},
+										&ast.SelectCore{
+
+											Values: token.New(1, 34, 33, 6, token.KeywordValues, "VALUES"),
+											ParenthesizedExpressions: []*ast.ParenthesizedExpressions{
+												&ast.ParenthesizedExpressions{
+													LeftParen: token.New(1, 41, 40, 1, token.Delimiter, "("),
+													Exprs: []*ast.Expr{
+														&ast.Expr{
+															LiteralValue: token.New(1, 42, 41, 7, token.Literal, "myExpr1"),
+														},
+													},
+													RightParen: token.New(1, 49, 48, 1, token.Delimiter, ")"),
+												},
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 50, 49, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 52, 51, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 59, 58, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 64, 63, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, basic SELECT with ORDER BY, and basic cte-table-name",
+			"WITH myTable AS (SELECT * ORDER BY myLiteral) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+										},
+									},
+									Order: token.New(1, 27, 26, 5, token.KeywordOrder, "ORDER"),
+									By:    token.New(1, 33, 32, 2, token.KeywordBy, "BY"),
+									OrderingTerm: []*ast.OrderingTerm{
+										&ast.OrderingTerm{
+											Expr: &ast.Expr{
+												LiteralValue: token.New(1, 36, 35, 9, token.Literal, "myLiteral"),
+											},
+										},
+									},
+								},
+								RightParen: token.New(1, 45, 44, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 47, 46, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 54, 53, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 59, 58, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, basic SELECT with basic LIMIT with single Expr, and basic cte-table-name",
+			"WITH myTable AS (SELECT * LIMIT myExpr1) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+										},
+									},
+									Limit: token.New(1, 27, 26, 5, token.KeywordLimit, "LIMIT"),
+									Expr1: &ast.Expr{
+										LiteralValue: token.New(1, 33, 32, 7, token.Literal, "myExpr1"),
+									},
+								},
+								RightParen: token.New(1, 40, 39, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 42, 41, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 49, 48, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 54, 53, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, basic SELECT with LIMIT with multiple Expr with comma, and basic cte-table-name",
+			"WITH myTable AS (SELECT * LIMIT myExpr1,myExpr2) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+										},
+									},
+									Limit: token.New(1, 27, 26, 5, token.KeywordLimit, "LIMIT"),
+									Expr1: &ast.Expr{
+										LiteralValue: token.New(1, 33, 32, 7, token.Literal, "myExpr1"),
+									},
+									Comma: token.New(1, 40, 39, 1, token.Delimiter, ","),
+									Expr2: &ast.Expr{
+										LiteralValue: token.New(1, 41, 40, 7, token.Literal, "myExpr2"),
+									},
+								},
+								RightParen: token.New(1, 48, 47, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 50, 49, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 57, 56, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 62, 61, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
+		{
+			"DELETE with basic with clause, basic SELECT with LIMIT with multiple Expr with OFFSET, and basic cte-table-name",
+			"WITH myTable AS (SELECT * LIMIT myExpr1 OFFSET myExpr2) DELETE FROM myTable",
+			&ast.SQLStmt{
+				DeleteStmt: &ast.DeleteStmt{
+					WithClause: &ast.WithClause{
+						With: token.New(1, 1, 0, 4, token.KeywordWith, "WITH"),
+						RecursiveCte: []*ast.RecursiveCte{
+							&ast.RecursiveCte{
+								CteTableName: &ast.CteTableName{
+									TableName: token.New(1, 6, 5, 7, token.Literal, "myTable"),
+								},
+								As:        token.New(1, 14, 13, 2, token.KeywordAs, "AS"),
+								LeftParen: token.New(1, 17, 16, 1, token.Delimiter, "("),
+								SelectStmt: &ast.SelectStmt{
+									SelectCore: []*ast.SelectCore{
+										&ast.SelectCore{
+											Select: token.New(1, 18, 17, 6, token.KeywordSelect, "SELECT"),
+											ResultColumn: []*ast.ResultColumn{
+												&ast.ResultColumn{
+													Asterisk: token.New(1, 25, 24, 1, token.BinaryOperator, "*"),
+												},
+											},
+										},
+									},
+									Limit: token.New(1, 27, 26, 5, token.KeywordLimit, "LIMIT"),
+									Expr1: &ast.Expr{
+										LiteralValue: token.New(1, 33, 32, 7, token.Literal, "myExpr1"),
+									},
+									Offset: token.New(1, 41, 40, 6, token.KeywordOffset, "OFFSET"),
+									Expr2: &ast.Expr{
+										LiteralValue: token.New(1, 48, 47, 7, token.Literal, "myExpr2"),
+									},
+								},
+								RightParen: token.New(1, 55, 54, 1, token.Delimiter, ")"),
+							},
+						},
+					},
+					Delete: token.New(1, 57, 56, 6, token.KeywordDelete, "DELETE"),
+					From:   token.New(1, 64, 63, 4, token.KeywordFrom, "FROM"),
+					QualifiedTableName: &ast.QualifiedTableName{
+						TableName: token.New(1, 69, 68, 7, token.Literal, "myTable"),
+					},
+				},
+			},
+		},
 	}
 	for _, input := range inputs {
 		t.Run(input.Name, func(t *testing.T) {