Skip to content

Commit

Permalink
address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
alivxxx committed Aug 26, 2019
1 parent 3de13c1 commit 52dcfa0
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 8 deletions.
9 changes: 6 additions & 3 deletions parser.go

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

3 changes: 3 additions & 0 deletions parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -5738,6 +5738,7 @@ SelectStmtBasic:
SelectStmtOpts: $2.(*ast.SelectStmtOpts),
Distinct: $2.(*ast.SelectStmtOpts).Distinct,
Fields: $3.(*ast.FieldList),
QueryBlockOffset: parser.queryBlockOffset(),
}
if st.SelectStmtOpts.TableHints != nil {
st.TableHints = st.SelectStmtOpts.TableHints
Expand Down Expand Up @@ -8102,6 +8103,7 @@ StatementList:
s.SetText(lexer.stmtText())
}
parser.result = append(parser.result, s)
parser.blockOffset = 0
}
}
| StatementList ';' Statement
Expand All @@ -8112,6 +8114,7 @@ StatementList:
s.SetText(lexer.stmtText())
}
parser.result = append(parser.result, s)
parser.blockOffset = 0
}
}

Expand Down
40 changes: 40 additions & 0 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4290,3 +4290,43 @@ func (checker *nodeTextCleaner) Enter(in ast.Node) (out ast.Node, skipChildren b
func (checker *nodeTextCleaner) Leave(in ast.Node) (out ast.Node, ok bool) {
return in, true
}

type queryBlockOffsetChecker struct {
curOffset int
mismatch bool
}

func (checker *queryBlockOffsetChecker) Enter(in ast.Node) (ast.Node, bool) {
sel, ok := in.(*ast.SelectStmt)
if !ok {
return in, false
}
checker.curOffset++
if sel.QueryBlockOffset != checker.curOffset {
checker.mismatch = true
}
return in, false
}

func (checker *queryBlockOffsetChecker) Leave(in ast.Node) (out ast.Node, ok bool) {
return in, true
}

func (s *testParserSuite) SelectStmtOffset(c *C) {
parser := parser.New()
sqls := []string{
"select * from t; select * from t",
"select a, (select count(*) from t t1 where t1.b > t.a) from t where b > (select b from t t2 where t2.b = t.a limit 1)",
"select count(*) from t t1 where t1.a < (select count(*) from t t2 where t1.a > t2.a)",
}
checker := &queryBlockOffsetChecker{}
for _, sql := range sqls {
stmts, _, err := parser.Parse(sql, "", "")
c.Assert(err, IsNil)
for _, stmt := range stmts {
checker.curOffset = 0
stmt.Accept(checker)
c.Assert(checker.mismatch, IsFalse)
}
}
}
17 changes: 12 additions & 5 deletions yy_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,12 @@ func TrimComment(txt string) string {

// Parser represents a parser instance. Some temporary objects are stored in it to reduce object allocation during Parse function.
type Parser struct {
charset string
collation string
result []ast.StmtNode
src string
lexer Scanner
charset string
collation string
result []ast.StmtNode
src string
lexer Scanner
blockOffset int

// the following fields are used by yyParse to reduce allocation.
cache []yySymType
Expand Down Expand Up @@ -134,6 +135,7 @@ func (parser *Parser) Parse(sql, charset, collation string) (stmt []ast.StmtNode
parser.collation = collation
parser.src = sql
parser.result = parser.result[:0]
parser.blockOffset = 0

var l yyLexer
parser.lexer.reset(sql)
Expand Down Expand Up @@ -217,6 +219,11 @@ func (parser *Parser) endOffset(v *yySymType) int {
return offset
}

func (parser *Parser) queryBlockOffset() int {
parser.blockOffset++
return parser.blockOffset
}

func toInt(l yyLexer, lval *yySymType, str string) int {
n, err := strconv.ParseUint(str, 10, 64)
if err != nil {
Expand Down

0 comments on commit 52dcfa0

Please sign in to comment.