Skip to content

Commit

Permalink
parser: disallow subquery without table alias (#19102) (#20367)
Browse files Browse the repository at this point in the history
Signed-off-by: ti-srebot <ti-srebot@pingcap.com>
  • Loading branch information
ti-srebot authored Nov 12, 2020
1 parent ee324ef commit 5304eff
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 8 deletions.
2 changes: 2 additions & 0 deletions ddl/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ var (
ErrFunctionalIndexOnField = terror.ClassDDL.New(mysql.ErrFunctionalIndexOnField, mysql.MySQLErrName[mysql.ErrFunctionalIndexOnField])
// ErrInvalidAutoRandom returns when auto_random is used incorrectly.
ErrInvalidAutoRandom = terror.ClassDDL.New(mysql.ErrInvalidAutoRandom, mysql.MySQLErrName[mysql.ErrInvalidAutoRandom])
// ErrDerivedMustHaveAlias returns when a sub select statement does not have a table alias.
ErrDerivedMustHaveAlias = terror.ClassDDL.New(mysql.ErrDerivedMustHaveAlias, mysql.MySQLErrName[mysql.ErrDerivedMustHaveAlias])

// ErrSequenceRunOut returns when the sequence has been run out.
ErrSequenceRunOut = terror.ClassDDL.New(mysql.ErrSequenceRunOut, mysql.MySQLErrName[mysql.ErrSequenceRunOut])
Expand Down
5 changes: 5 additions & 0 deletions errors.toml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ error = '''
The used table type doesn't support FULLTEXT indexes
'''

["ddl:1248"]
error = '''
Every derived table must have its own alias
'''

["ddl:1253"]
error = '''
COLLATION '%s' is not valid for CHARACTER SET '%s'
Expand Down
28 changes: 27 additions & 1 deletion executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3916,7 +3916,33 @@ func (s *testSuite3) TestDoSubquery(c *C) {
c.Assert(r, IsNil, Commentf("result of Do not empty"))
}

func (s *testSuite3) TestTSOFail(c *C) {
func (s *testSuite3) TestSubqueryTableAlias(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec(`use test`)
tk.MustExec(`drop table if exists t`)

tk.MustExec("set sql_mode = ''")
tk.MustGetErrCode("select a, b from (select 1 a) ``, (select 2 b) ``;", mysql.ErrDerivedMustHaveAlias)
tk.MustGetErrCode("select a, b from (select 1 a) `x`, (select 2 b) `x`;", mysql.ErrNonuniqTable)
tk.MustGetErrCode("select a, b from (select 1 a), (select 2 b);", mysql.ErrDerivedMustHaveAlias)
// ambiguous column name
tk.MustGetErrCode("select a from (select 1 a) ``, (select 2 a) ``;", mysql.ErrDerivedMustHaveAlias)
tk.MustGetErrCode("select a from (select 1 a) `x`, (select 2 a) `x`;", mysql.ErrNonuniqTable)
tk.MustGetErrCode("select x.a from (select 1 a) `x`, (select 2 a) `x`;", mysql.ErrNonuniqTable)
tk.MustGetErrCode("select a from (select 1 a), (select 2 a);", mysql.ErrDerivedMustHaveAlias)

tk.MustExec("set sql_mode = 'oracle';")
tk.MustQuery("select a, b from (select 1 a) ``, (select 2 b) ``;").Check(testkit.Rows("1 2"))
tk.MustQuery("select a, b from (select 1 a) `x`, (select 2 b) `x`;").Check(testkit.Rows("1 2"))
tk.MustQuery("select a, b from (select 1 a), (select 2 b);").Check(testkit.Rows("1 2"))
// ambiguous column name
tk.MustGetErrCode("select a from (select 1 a) ``, (select 2 a) ``;", mysql.ErrNonUniq)
tk.MustGetErrCode("select a from (select 1 a) `x`, (select 2 a) `x`;", mysql.ErrNonUniq)
tk.MustGetErrCode("select x.a from (select 1 a) `x`, (select 2 a) `x`;", mysql.ErrNonUniq)
tk.MustGetErrCode("select a from (select 1 a), (select 2 a);", mysql.ErrNonUniq)
}

func (s *testSerialSuite1) TestTSOFail(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec(`use test`)
tk.MustExec(`drop table if exists t`)
Expand Down
22 changes: 15 additions & 7 deletions planner/core/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,11 @@ func (p *preprocessor) Enter(in ast.Node) (out ast.Node, skipChildren bool) {
if node.Kind == ast.BRIEKindRestore {
p.flag |= inCreateOrDropTable
}
case *ast.TableSource:
isModeOracle := p.ctx.GetSessionVars().SQLMode&mysql.ModeOracle != 0
if _, ok := node.Source.(*ast.SelectStmt); ok && !isModeOracle && len(node.AsName.L) == 0 {
p.err = ddl.ErrDerivedMustHaveAlias.GenWithStackByArgs()
}
default:
p.flag &= ^parentIsJoin
}
Expand Down Expand Up @@ -556,13 +561,16 @@ func (p *preprocessor) checkNonUniqTableAlias(stmt *ast.Join) {
p.tableAliasInJoin = append(p.tableAliasInJoin, make(map[string]interface{}))
}
tableAliases := p.tableAliasInJoin[len(p.tableAliasInJoin)-1]
if err := isTableAliasDuplicate(stmt.Left, tableAliases); err != nil {
p.err = err
return
}
if err := isTableAliasDuplicate(stmt.Right, tableAliases); err != nil {
p.err = err
return
isOracleMode := p.ctx.GetSessionVars().SQLMode&mysql.ModeOracle != 0
if !isOracleMode {
if err := isTableAliasDuplicate(stmt.Left, tableAliases); err != nil {
p.err = err
return
}
if err := isTableAliasDuplicate(stmt.Right, tableAliases); err != nil {
p.err = err
return
}
}
p.flag |= parentIsJoin
}
Expand Down

0 comments on commit 5304eff

Please sign in to comment.