Skip to content

Commit

Permalink
planner, executor: adjustOverlongColName for CreateView (#14850)
Browse files Browse the repository at this point in the history
  • Loading branch information
XuHuaiyu authored Feb 20, 2020
1 parent 51a832e commit fe05ed5
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 7 deletions.
41 changes: 41 additions & 0 deletions executor/ddl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,47 @@ func (s *testSuite6) TestCreateView(c *C) {
tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Note|1051|Unknown table 'test.v2_if_exists'", "Note|1051|Unknown table 'test.v3_if_exists'"))
}

func (s *testSuite6) TestCreateViewWithOverlongColName(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("create table t(a int)")
defer tk.MustExec("drop table t")
tk.MustExec("create view v as select distinct'" + strings.Repeat("a", 65) + "', " +
"max('" + strings.Repeat("b", 65) + "'), " +
"'cccccccccc', '" + strings.Repeat("d", 65) + "';")
resultCreateStmt := "CREATE ALGORITHM=UNDEFINED DEFINER=``@`` SQL SECURITY DEFINER VIEW `v` (`name_exp_1`, `name_exp_2`, `cccccccccc`, `name_exp_4`) AS SELECT DISTINCT '" + strings.Repeat("a", 65) + "',MAX('" + strings.Repeat("b", 65) + "'),'cccccccccc','" + strings.Repeat("d", 65) + "'"
tk.MustQuery("select * from v")
tk.MustQuery("select name_exp_1, name_exp_2, cccccccccc, name_exp_4 from v")
tk.MustQuery("show create view v").Check(testkit.Rows("v " + resultCreateStmt + " "))
tk.MustExec("drop view v;")
tk.MustExec(resultCreateStmt)

tk.MustExec("drop view v ")
tk.MustExec("create definer='root'@'localhost' view v as select 'a', '" + strings.Repeat("b", 65) + "' from t " +
"union select '" + strings.Repeat("c", 65) + "', " +
"count(distinct '" + strings.Repeat("b", 65) + "', " +
"'c');")
resultCreateStmt = "CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` (`a`, `name_exp_2`) AS SELECT 'a','" + strings.Repeat("b", 65) + "' FROM `test`.`t` UNION SELECT '" + strings.Repeat("c", 65) + "',COUNT(DISTINCT '" + strings.Repeat("b", 65) + "', 'c')"
tk.MustQuery("select * from v")
tk.MustQuery("select a, name_exp_2 from v")
tk.MustQuery("show create view v").Check(testkit.Rows("v " + resultCreateStmt + " "))
tk.MustExec("drop view v;")
tk.MustExec(resultCreateStmt)

tk.MustExec("drop view v ")
tk.MustExec("create definer='root'@'localhost' view v as select 'a' as '" + strings.Repeat("b", 65) + "' from t;")
tk.MustQuery("select * from v")
tk.MustQuery("select name_exp_1 from v")
resultCreateStmt = "CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` (`name_exp_1`) AS SELECT 'a' AS `" + strings.Repeat("b", 65) + "` FROM `test`.`t`"
tk.MustQuery("show create view v").Check(testkit.Rows("v " + resultCreateStmt + " "))
tk.MustExec("drop view v;")
tk.MustExec(resultCreateStmt)

tk.MustExec("drop view v ")
err := tk.ExecToErr("create view v(`" + strings.Repeat("b", 65) + "`) as select a from t;")
c.Assert(err.Error(), Equals, "[ddl:1059]Identifier name 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' is too long")
}

func (s *testSuite6) TestCreateDropDatabase(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("create database if not exists drop_test;")
Expand Down
25 changes: 18 additions & 7 deletions planner/core/planbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2530,6 +2530,7 @@ func (b *PlanBuilder) buildDDL(ctx context.Context, node ast.DDLNode) (Plan, err
schema := plan.Schema()
names := plan.OutputNames()
if v.Cols == nil {
adjustOverlongViewColname(plan.(LogicalPlan))
v.Cols = make([]model.CIStr, len(schema.Columns))
for i, name := range names {
v.Cols[i] = name.ColName
Expand All @@ -2538,14 +2539,12 @@ func (b *PlanBuilder) buildDDL(ctx context.Context, node ast.DDLNode) (Plan, err
if len(v.Cols) != schema.Len() {
return nil, ddl.ErrViewWrongList
}
if _, ok := plan.(LogicalPlan); ok {
if b.ctx.GetSessionVars().User != nil {
authErr = ErrTableaccessDenied.GenWithStackByArgs("CREATE VIEW", b.ctx.GetSessionVars().User.Hostname,
b.ctx.GetSessionVars().User.Username, v.ViewName.Name.L)
}
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.CreateViewPriv, v.ViewName.Schema.L,
v.ViewName.Name.L, "", authErr)
if b.ctx.GetSessionVars().User != nil {
authErr = ErrTableaccessDenied.GenWithStackByArgs("CREATE VIEW", b.ctx.GetSessionVars().User.Hostname,
b.ctx.GetSessionVars().User.Username, v.ViewName.Name.L)
}
b.visitInfo = appendVisitInfo(b.visitInfo, mysql.CreateViewPriv, v.ViewName.Schema.L,
v.ViewName.Name.L, "", authErr)
if v.Definer.CurrentUser && b.ctx.GetSessionVars().User != nil {
v.Definer = b.ctx.GetSessionVars().User
}
Expand Down Expand Up @@ -2948,3 +2947,15 @@ func buildChecksumTableSchema() (*expression.Schema, []*types.FieldName) {
schema.Append(buildColumnWithName("", "Total_bytes", mysql.TypeLonglong, 22))
return schema.col2Schema(), schema.names
}

// adjustOverlongViewColname adjusts the overlong outputNames of a view to
// `new_exp_$off` where `$off` is the offset of the output column, $off starts from 1.
// There is still some MySQL compatible problems.
func adjustOverlongViewColname(plan LogicalPlan) {
outputNames := plan.OutputNames()
for i := range outputNames {
if outputName := outputNames[i].ColName.L; len(outputName) > mysql.MaxColumnNameLength {
outputNames[i].ColName = model.NewCIStr(fmt.Sprintf("name_exp_%d", i+1))
}
}
}

0 comments on commit fe05ed5

Please sign in to comment.