mirror of
https://github.com/chaisql/chai.git
synced 2025-11-01 11:22:42 +08:00
parser: fix statement parsing
This commit is contained in:
@@ -80,28 +80,37 @@ func (p *Parser) ParseQuery() (query.Query, error) {
|
|||||||
|
|
||||||
// ParseQuery parses a Genji SQL string and returns a Query.
|
// ParseQuery parses a Genji SQL string and returns a Query.
|
||||||
func (p *Parser) Parse(fn func(statement.Statement) error) error {
|
func (p *Parser) Parse(fn func(statement.Statement) error) error {
|
||||||
semi := true
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if tok, pos, lit := p.ScanIgnoreWhitespace(); tok == scanner.EOF {
|
err := p.skipMany(scanner.SEMICOLON)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
end, err := p.parseOptional(scanner.EOF)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if end {
|
||||||
return nil
|
return nil
|
||||||
} else if tok == scanner.SEMICOLON {
|
}
|
||||||
semi = true
|
|
||||||
} else {
|
s, err := p.ParseStatement()
|
||||||
if !semi {
|
if err != nil {
|
||||||
return newParseError(scanner.Tokstr(tok, lit), []string{";"}, pos)
|
return err
|
||||||
}
|
}
|
||||||
p.Unscan()
|
|
||||||
s, err := p.ParseStatement()
|
tok, pos, lit := p.ScanIgnoreWhitespace()
|
||||||
if err != nil {
|
switch tok {
|
||||||
return err
|
case scanner.EOF:
|
||||||
}
|
return fn(s)
|
||||||
|
case scanner.SEMICOLON:
|
||||||
err = fn(s)
|
err = fn(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
semi = false
|
p.Unscan()
|
||||||
|
return newParseError(scanner.Tokstr(tok, lit), []string{";"}, pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,6 +151,16 @@ func (p *Parser) ParseStatement() (statement.Statement, error) {
|
|||||||
}, pos)
|
}, pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Parser) skipMany(tok scanner.Token) error {
|
||||||
|
for {
|
||||||
|
t, _, _ := p.ScanIgnoreWhitespace()
|
||||||
|
if t != tok {
|
||||||
|
p.Unscan()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// parseCondition parses the "WHERE" clause of the query, if it exists.
|
// parseCondition parses the "WHERE" clause of the query, if it exists.
|
||||||
func (p *Parser) parseCondition() (expr.Expr, error) {
|
func (p *Parser) parseCondition() (expr.Expr, error) {
|
||||||
// Check if the WHERE token exists.
|
// Check if the WHERE token exists.
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ func (p *Parser) parseSelectStatement() (*statement.SelectStmt, error) {
|
|||||||
// Parse limit: "LIMIT expr"
|
// Parse limit: "LIMIT expr"
|
||||||
stmt.LimitExpr, err = p.parseLimit()
|
stmt.LimitExpr, err = p.parseLimit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to parse LIMIT clause")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse offset: "OFFSET expr"
|
// Parse offset: "OFFSET expr"
|
||||||
stmt.OffsetExpr, err = p.parseOffset()
|
stmt.OffsetExpr, err = p.parseOffset()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to parse OFFSET clause")
|
||||||
}
|
}
|
||||||
|
|
||||||
return stmt, nil
|
return stmt, nil
|
||||||
|
|||||||
Reference in New Issue
Block a user