From 2c8b28c37be2d3b9bf9c805753e5c4670864df44 Mon Sep 17 00:00:00 2001 From: wjHuang Date: Fri, 6 Nov 2020 12:06:32 +0800 Subject: [PATCH] ddl: forbid invalid usage of window function in the generated column (#20855) Signed-off-by: wjhuang2016 --- ddl/db_test.go | 8 ++++++++ ddl/error.go | 1 + ddl/generated_column.go | 7 +++++++ 3 files changed, 16 insertions(+) diff --git a/ddl/db_test.go b/ddl/db_test.go index 29c85542b70ca..513367e4ddc2a 100644 --- a/ddl/db_test.go +++ b/ddl/db_test.go @@ -6361,3 +6361,11 @@ func (s *testSerialDBSuite) TestModifyColumnTypeWhenInterception(c *C) { res := tk.MustQuery("show warnings") c.Assert(len(res.Rows()), Equals, count) } + +func (s *testDBSuite4) TestGeneratedColumnWindowFunction(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test_db") + tk.MustExec("DROP TABLE IF EXISTS t") + tk.MustGetErrCode("CREATE TABLE t (a INT , b INT as (ROW_NUMBER() OVER (ORDER BY a)))", errno.ErrWindowInvalidWindowFuncUse) + tk.MustGetErrCode("CREATE TABLE t (a INT , index idx ((ROW_NUMBER() OVER (ORDER BY a))))", errno.ErrWindowInvalidWindowFuncUse) +} diff --git a/ddl/error.go b/ddl/error.go index 905728453ae46..c8f444e72032b 100644 --- a/ddl/error.go +++ b/ddl/error.go @@ -111,6 +111,7 @@ var ( errUnsupportedCreatePartition = dbterror.ClassDDL.NewStdErr(mysql.ErrUnsupportedDDLOperation, parser_mysql.Message(fmt.Sprintf(mysql.MySQLErrName[mysql.ErrUnsupportedDDLOperation].Raw, "partition type, treat as normal table"), nil), "", "") errTablePartitionDisabled = dbterror.ClassDDL.NewStdErr(mysql.ErrUnsupportedDDLOperation, parser_mysql.Message("Partitions are ignored because Table Partition is disabled, please set 'tidb_enable_table_partition' if you need to need to enable it", nil), "", "") errUnsupportedIndexType = dbterror.ClassDDL.NewStdErr(mysql.ErrUnsupportedDDLOperation, parser_mysql.Message(fmt.Sprintf(mysql.MySQLErrName[mysql.ErrUnsupportedDDLOperation].Raw, "index type"), nil), "", "") + errWindowInvalidWindowFuncUse = dbterror.ClassDDL.NewStd(mysql.ErrWindowInvalidWindowFuncUse) // ErrDupKeyName returns for duplicated key name ErrDupKeyName = dbterror.ClassDDL.NewStd(mysql.ErrDupKeyName) diff --git a/ddl/generated_column.go b/ddl/generated_column.go index d76b030a84434..62a7c6dff9588 100644 --- a/ddl/generated_column.go +++ b/ddl/generated_column.go @@ -229,6 +229,7 @@ type illegalFunctionChecker struct { hasIllegalFunc bool hasAggFunc bool hasRowVal bool // hasRowVal checks whether the functional index refers to a row value + hasWindowFunc bool } func (c *illegalFunctionChecker) Enter(inNode ast.Node) (outNode ast.Node, skipChildren bool) { @@ -251,6 +252,9 @@ func (c *illegalFunctionChecker) Enter(inNode ast.Node) (outNode ast.Node, skipC case *ast.RowExpr: c.hasRowVal = true return inNode, true + case *ast.WindowFuncExpr: + c.hasWindowFunc = true + return inNode, true } return inNode, false } @@ -289,6 +293,9 @@ func checkIllegalFn4Generated(name string, genType int, expr ast.ExprNode) error return ErrFunctionalIndexRowValueIsNotAllowed.GenWithStackByArgs(name) } } + if c.hasWindowFunc { + return errWindowInvalidWindowFuncUse.GenWithStackByArgs(name) + } return nil }