Skip to content

Commit

Permalink
Add Bad{Statement,QueryExpr,Expr,Type,DDL,DML} ASTs
Browse files Browse the repository at this point in the history
#230 (comment)

Co-Authored-By: apstndb <[email protected]>
  • Loading branch information
makenowjust and apstndb committed Dec 20, 2024
1 parent c601633 commit 2c0d969
Show file tree
Hide file tree
Showing 20 changed files with 653 additions and 492 deletions.
82 changes: 71 additions & 11 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ type Statement interface {
// - https://cloud.google.com/spanner/docs/reference/standard-sql/data-definition-language
// - https://cloud.google.com/spanner/docs/reference/standard-sql/dml-syntax

func (BadNode) isStatement() {}
func (BadStatement) isStatement() {}
func (BadDDL) isStatement() {}
func (BadDML) isStatement() {}
func (QueryStatement) isStatement() {}
func (CreateSchema) isStatement() {}
func (DropSchema) isStatement() {}
Expand Down Expand Up @@ -111,7 +113,7 @@ type QueryExpr interface {
isQueryExpr()
}

func (BadNode) isQueryExpr() {}
func (BadQueryExpr) isQueryExpr() {}
func (Select) isQueryExpr() {}
func (Query) isQueryExpr() {}
func (FromQuery) isQueryExpr() {}
Expand Down Expand Up @@ -177,7 +179,7 @@ type Expr interface {
isExpr()
}

func (BadNode) isExpr() {}
func (BadExpr) isExpr() {}
func (BinaryExpr) isExpr() {}
func (UnaryExpr) isExpr() {}
func (InExpr) isExpr() {}
Expand Down Expand Up @@ -300,7 +302,7 @@ type Type interface {
isType()
}

func (BadNode) isType() {}
func (BadType) isType() {}
func (SimpleType) isType() {}
func (ArrayType) isType() {}
func (StructType) isType() {}
Expand Down Expand Up @@ -348,7 +350,7 @@ type DDL interface {
//
// - https://cloud.google.com/spanner/docs/reference/standard-sql/data-definition-language

func (BadNode) isDDL() {}
func (BadDDL) isDDL() {}
func (CreateSchema) isDDL() {}
func (DropSchema) isDDL() {}
func (CreateDatabase) isDDL() {}
Expand Down Expand Up @@ -507,10 +509,10 @@ type DML interface {
isDML()
}

func (BadNode) isDML() {}
func (Insert) isDML() {}
func (Delete) isDML() {}
func (Update) isDML() {}
func (BadDML) isDML() {}
func (Insert) isDML() {}
func (Delete) isDML() {}
func (Update) isDML() {}

// InsertInput represents input values of INSERT statement.
type InsertInput interface {
Expand Down Expand Up @@ -558,6 +560,66 @@ type BadNode struct {
Tokens []*token.Token
}

// BadStatement is a BadNode for Statement.
//
// {{.BadNode | sql}}
type BadStatement struct {
// pos = BadNode.pos
// end = BadNode.end

BadNode *BadNode
}

// BadQueryExpr is a BadNode for QueryExpr.
//
// {{.BadNode | sql}}
type BadQueryExpr struct {
// pos = BadNode.pos
// end = BadNode.end

BadNode *BadNode
}

// BadExpr is a BadNode for Expr.
//
// {{.BadNode | sql}}
type BadExpr struct {
// pos = BadNode.pos
// end = BadNode.end

BadNode *BadNode
}

// BadType is a BadNode for Type.
//
// {{.BadNode | sql}}
type BadType struct {
// pos = BadNode.pos
// end = BadNode.end

BadNode *BadNode
}

// BadDDL is a BadNode for DDL.
//
// {{.BadNode | sql}}
type BadDDL struct {
// pos = BadNode.pos
// end = BadNode.end

BadNode *BadNode
}

// BadDML is a BadNode for DML.
//
// {{.BadNode | sql}}
type BadDML struct {
// pos = BadNode.pos
// end = BadNode.end

BadNode *BadNode
}

// ================================================================================
//
// SELECT
Expand Down Expand Up @@ -2285,8 +2347,6 @@ type DropProtoBundle struct {
Bundle token.Pos // position of "BUNDLE" pseudo keyword
}

// end of PROTO BUNDLE statements

// CreateTable is CREATE TABLE statement node.
//
// CREATE TABLE {{if .IfNotExists}}IF NOT EXISTS{{end}} {{.Name | sql}} (
Expand Down
48 changes: 48 additions & 0 deletions ast/pos.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions ast/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,13 @@ func (b *BadNode) SQL() string {
return sql
}

func (b *BadStatement) SQL() string { return b.BadNode.SQL() }
func (b *BadQueryExpr) SQL() string { return b.BadNode.SQL() }
func (b *BadExpr) SQL() string { return b.BadNode.SQL() }
func (b *BadType) SQL() string { return b.BadNode.SQL() }
func (b *BadDDL) SQL() string { return b.BadNode.SQL() }
func (b *BadDML) SQL() string { return b.BadNode.SQL() }

// ================================================================================
//
// SELECT
Expand Down
44 changes: 25 additions & 19 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func (p *Parser) parseStatement() (stmt ast.Statement) {
l := p.Lexer.Clone()
defer func() {
if r := recover(); r != nil {
stmt = p.handleParseStatementError(r, l)
stmt = &ast.BadStatement{BadNode: p.handleParseStatementError(r, l)}
}
}()

Expand Down Expand Up @@ -233,7 +233,7 @@ func (p *Parser) parseQueryStatement() (stmt *ast.QueryStatement) {
// When parsing is failed on tryParseHint or tryParseWith, the result of these methods are discarded
// becasue they are concrete structs and we cannot fill them with *ast.BadNode.
stmt = &ast.QueryStatement{
Query: p.handleParseStatementError(r, l),
Query: &ast.BadQueryExpr{BadNode: p.handleParseStatementError(r, l)},
}
}
}()
Expand Down Expand Up @@ -2749,7 +2749,7 @@ func (p *Parser) parseDDL() (ddl ast.DDL) {
l := p.Lexer.Clone()
defer func() {
if r := recover(); r != nil {
ddl = p.handleParseStatementError(r, l)
ddl = &ast.BadDDL{BadNode: p.handleParseStatementError(r, l)}
}
}()

Expand Down Expand Up @@ -4641,7 +4641,7 @@ func (p *Parser) parseDML() (dml ast.DML) {
l := p.Lexer.Clone()
defer func() {
if r := recover(); r != nil {
dml = p.handleParseStatementError(r, l)
dml = &ast.BadDML{BadNode: p.handleParseStatementError(r, l)}
}
}()

Expand Down Expand Up @@ -5072,7 +5072,7 @@ skip:
}
}

func (p *Parser) handleParseQueryExprError(simple bool, r any, l *Lexer) *ast.BadNode {
func (p *Parser) handleParseQueryExprError(simple bool, r any, l *Lexer) *ast.BadQueryExpr {
p.handleError(r, l)

var tokens []*token.Token
Expand Down Expand Up @@ -5101,14 +5101,16 @@ skip:
p.Lexer.nextToken(true)
}

return &ast.BadNode{
NodePos: pos,
NodeEnd: end,
Tokens: tokens,
return &ast.BadQueryExpr{
BadNode: &ast.BadNode{
NodePos: pos,
NodeEnd: end,
Tokens: tokens,
},
}
}

func (p *Parser) handleParseExprError(r any, l *Lexer) *ast.BadNode {
func (p *Parser) handleParseExprError(r any, l *Lexer) *ast.BadExpr {
p.handleError(r, l)

var tokens []*token.Token
Expand Down Expand Up @@ -5137,14 +5139,16 @@ skip:
p.Lexer.nextToken(true)
}

return &ast.BadNode{
NodePos: pos,
NodeEnd: end,
Tokens: tokens,
return &ast.BadExpr{
BadNode: &ast.BadNode{
NodePos: pos,
NodeEnd: end,
Tokens: tokens,
},
}
}

func (p *Parser) handleParseTypeError(r any, l *Lexer) *ast.BadNode {
func (p *Parser) handleParseTypeError(r any, l *Lexer) *ast.BadType {
p.handleError(r, l)

var tokens []*token.Token
Expand Down Expand Up @@ -5183,10 +5187,12 @@ skip:
p.Lexer.nextToken(true)
}

return &ast.BadNode{
NodePos: pos,
NodeEnd: end,
Tokens: tokens,
return &ast.BadType{
BadNode: &ast.BadNode{
NodePos: pos,
NodeEnd: end,
Tokens: tokens,
},
}
}

Expand Down
Loading

0 comments on commit 2c0d969

Please sign in to comment.