Skip to content

Commit

Permalink
parser: fix Text() in SubSelect parse (pingcap#5718)
Browse files Browse the repository at this point in the history
ex. "SELECT 1 > (select 1)“ , ast.SubqueryExpr#Query's Text() will return "(select ". by mistake.
  • Loading branch information
mccxj authored and tiancaiamao committed Jan 26, 2018
1 parent e09aa11 commit 7c5ea17
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
4 changes: 2 additions & 2 deletions parser/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -4366,15 +4366,15 @@ SubSelect:
parser.setLastSelectFieldText(s, endOffset)
src := parser.src
// See the implementation of yyParse function
s.SetText(src[yyS[yypt-1].offset-1:yyS[yypt].offset-1])
s.SetText(src[yyS[yypt-1].offset:yyS[yypt].offset])
$$ = &ast.SubqueryExpr{Query: s}
}
| '(' UnionStmt ')'
{
s := $2.(*ast.UnionStmt)
src := parser.src
// See the implementation of yyParse function
s.SetText(src[yyS[yypt-1].offset-1:yyS[yypt].offset-1])
s.SetText(src[yyS[yypt-1].offset:yyS[yypt].offset])
$$ = &ast.SubqueryExpr{Query: s}
}

Expand Down
36 changes: 36 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1754,6 +1754,25 @@ func (s *testParserSuite) TestCommentErrMsg(c *C) {
s.RunErrMsgTest(c, table)
}

type subqueryChecker struct {
text string
c *C
}

// Enter implements ast.Visitor interface.
func (sc *subqueryChecker) Enter(inNode ast.Node) (outNode ast.Node, skipChildren bool) {
if expr, ok := inNode.(*ast.SubqueryExpr); ok {
sc.c.Assert(expr.Query.Text(), Equals, sc.text)
return inNode, true
}
return inNode, false
}

// Leave implements ast.Visitor interface.
func (sc *subqueryChecker) Leave(inNode ast.Node) (node ast.Node, ok bool) {
return inNode, true
}

func (s *testParserSuite) TestSubquery(c *C) {
defer testleak.AfterTest(c)()
table := []testCase{
Expand All @@ -1773,6 +1792,23 @@ func (s *testParserSuite) TestSubquery(c *C) {
{"SELECT - NOT EXISTS (select 1)", false},
}
s.RunTest(c, table)

tests := []struct {
input string
text string
}{
{"SELECT 1 > (select 1)", "select 1"},
{"SELECT 1 > (select 1 union select 2)", "select 1 union select 2"},
}
parser := New()
for _, t := range tests {
stmt, err := parser.ParseOneStmt(t.input, "", "")
c.Assert(err, IsNil)
stmt.Accept(&subqueryChecker{
text: t.text,
c: c,
})
}
}
func (s *testParserSuite) TestUnion(c *C) {
defer testleak.AfterTest(c)()
Expand Down

0 comments on commit 7c5ea17

Please sign in to comment.