diff --git a/executor/executor_test.go b/executor/executor_test.go index 2c0aaf55584d3..f5cde6021a1f4 100644 --- a/executor/executor_test.go +++ b/executor/executor_test.go @@ -5533,3 +5533,165 @@ func (s *testSuite1) TestInsertValuesWithSubQuery(c *C) { tk.MustExec("insert into t2 set a = 3, b = 5, c = b") tk.MustQuery("select * from t2").Check(testkit.Rows("2 4 2", "3 5 5")) } +<<<<<<< HEAD +======= + +func (s *testSuite1) TestDIVZeroInPartitionExpr(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test;") + tk.MustExec("drop table if exists t1") + tk.MustExec("create table t1(a int) partition by range (10 div a) (partition p0 values less than (10), partition p1 values less than maxvalue)") + defer tk.MustExec("drop table if exists t1") + + tk.MustExec("set @@sql_mode=''") + tk.MustExec("insert into t1 values (NULL), (0), (1)") + tk.MustExec("set @@sql_mode='STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO'") + tk.MustGetErrCode("insert into t1 values (NULL), (0), (1)", mysql.ErrDivisionByZero) +} + +func (s *testSuite1) TestInsertIntoGivenPartitionSet(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test;") + tk.MustExec("drop table if exists t1") + tk.MustExec(`create table t1( + a int(11) DEFAULT NULL, + b varchar(10) DEFAULT NULL, + UNIQUE KEY idx_a (a)) PARTITION BY RANGE (a) + (PARTITION p0 VALUES LESS THAN (10) ENGINE = InnoDB, + PARTITION p1 VALUES LESS THAN (20) ENGINE = InnoDB, + PARTITION p2 VALUES LESS THAN (30) ENGINE = InnoDB, + PARTITION p3 VALUES LESS THAN (40) ENGINE = InnoDB, + PARTITION p4 VALUES LESS THAN MAXVALUE ENGINE = InnoDB)`) + defer tk.MustExec("drop table if exists t1") + + // insert into + tk.MustExec("insert into t1 partition(p0) values(1, 'a'), (2, 'b')") + tk.MustQuery("select * from t1 partition(p0) order by a").Check(testkit.Rows("1 a", "2 b")) + tk.MustExec("insert into t1 partition(p0, p1) values(3, 'c'), (4, 'd')") + tk.MustQuery("select * from t1 partition(p1)").Check(testkit.Rows()) + + err := tk.ExecToErr("insert into t1 values(1, 'a')") + c.Assert(err.Error(), Equals, "[kv:1062]Duplicate entry '1' for key 'idx_a'") + + err = tk.ExecToErr("insert into t1 partition(p0, p_non_exist) values(1, 'a')") + c.Assert(err.Error(), Equals, "[table:1735]Unknown partition 'p_non_exist' in table 't1'") + + err = tk.ExecToErr("insert into t1 partition(p0, p1) values(40, 'a')") + c.Assert(err.Error(), Equals, "[table:1748]Found a row not matching the given partition set") + + // replace into + tk.MustExec("replace into t1 partition(p0) values(1, 'replace')") + tk.MustExec("replace into t1 partition(p0, p1) values(3, 'replace'), (4, 'replace')") + + err = tk.ExecToErr("replace into t1 values(1, 'a')") + tk.MustQuery("select * from t1 partition (p0) order by a").Check(testkit.Rows("1 a", "2 b", "3 replace", "4 replace")) + + err = tk.ExecToErr("replace into t1 partition(p0, p_non_exist) values(1, 'a')") + c.Assert(err.Error(), Equals, "[table:1735]Unknown partition 'p_non_exist' in table 't1'") + + err = tk.ExecToErr("replace into t1 partition(p0, p1) values(40, 'a')") + c.Assert(err.Error(), Equals, "[table:1748]Found a row not matching the given partition set") + + tk.MustExec("truncate table t1") + + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int, b char(10))") + defer tk.MustExec("drop table if exists t") + + // insert into general table + err = tk.ExecToErr("insert into t partition(p0, p1) values(1, 'a')") + c.Assert(err.Error(), Equals, "[planner:1747]PARTITION () clause on non partitioned table") + + // insert into from select + tk.MustExec("insert into t values(1, 'a'), (2, 'b')") + tk.MustExec("insert into t1 partition(p0) select * from t") + tk.MustQuery("select * from t1 partition(p0) order by a").Check(testkit.Rows("1 a", "2 b")) + + tk.MustExec("truncate table t") + tk.MustExec("insert into t values(3, 'c'), (4, 'd')") + tk.MustExec("insert into t1 partition(p0, p1) select * from t") + tk.MustQuery("select * from t1 partition(p1) order by a").Check(testkit.Rows()) + tk.MustQuery("select * from t1 partition(p0) order by a").Check(testkit.Rows("1 a", "2 b", "3 c", "4 d")) + + err = tk.ExecToErr("insert into t1 select 1, 'a'") + c.Assert(err.Error(), Equals, "[kv:1062]Duplicate entry '1' for key 'idx_a'") + + err = tk.ExecToErr("insert into t1 partition(p0, p_non_exist) select 1, 'a'") + c.Assert(err.Error(), Equals, "[table:1735]Unknown partition 'p_non_exist' in table 't1'") + + err = tk.ExecToErr("insert into t1 partition(p0, p1) select 40, 'a'") + c.Assert(err.Error(), Equals, "[table:1748]Found a row not matching the given partition set") + + // replace into from select + tk.MustExec("replace into t1 partition(p0) select 1, 'replace'") + tk.MustExec("truncate table t") + tk.MustExec("insert into t values(3, 'replace'), (4, 'replace')") + tk.MustExec("replace into t1 partition(p0, p1) select * from t") + + err = tk.ExecToErr("replace into t1 values select 1, 'a'") + tk.MustQuery("select * from t1 partition (p0) order by a").Check(testkit.Rows("1 replace", "2 b", "3 replace", "4 replace")) + + err = tk.ExecToErr("replace into t1 partition(p0, p_non_exist) select 1, 'a'") + c.Assert(err.Error(), Equals, "[table:1735]Unknown partition 'p_non_exist' in table 't1'") + + err = tk.ExecToErr("replace into t1 partition(p0, p1) select 40, 'a'") + c.Assert(err.Error(), Equals, "[table:1748]Found a row not matching the given partition set") +} + +func (s *testSuite1) TestUpdateGivenPartitionSet(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test;") + tk.MustExec("drop table if exists t1,t2,t3") + tk.MustExec(`create table t1( + a int(11), + b varchar(10) DEFAULT NULL, + primary key idx_a (a)) PARTITION BY RANGE (a) + (PARTITION p0 VALUES LESS THAN (10) ENGINE = InnoDB, + PARTITION p1 VALUES LESS THAN (20) ENGINE = InnoDB, + PARTITION p2 VALUES LESS THAN (30) ENGINE = InnoDB, + PARTITION p3 VALUES LESS THAN (40) ENGINE = InnoDB, + PARTITION p4 VALUES LESS THAN MAXVALUE ENGINE = InnoDB)`) + + tk.MustExec(`create table t2( + a int(11) DEFAULT NULL, + b varchar(10) DEFAULT NULL) PARTITION BY RANGE (a) + (PARTITION p0 VALUES LESS THAN (10) ENGINE = InnoDB, + PARTITION p1 VALUES LESS THAN (20) ENGINE = InnoDB, + PARTITION p2 VALUES LESS THAN (30) ENGINE = InnoDB, + PARTITION p3 VALUES LESS THAN (40) ENGINE = InnoDB, + PARTITION p4 VALUES LESS THAN MAXVALUE ENGINE = InnoDB)`) + + tk.MustExec(`create table t3 (a int(11), b varchar(10) default null)`) + + defer tk.MustExec("drop table if exists t1,t2,t3") + tk.MustExec("insert into t3 values(1, 'a'), (2, 'b'), (11, 'c'), (21, 'd')") + err := tk.ExecToErr("update t3 partition(p0) set a = 40 where a = 2") + c.Assert(err.Error(), Equals, "[planner:1747]PARTITION () clause on non partitioned table") + + // update with primary key change + tk.MustExec("insert into t1 values(1, 'a'), (2, 'b'), (11, 'c'), (21, 'd')") + err = tk.ExecToErr("update t1 partition(p0, p1) set a = 40") + c.Assert(err.Error(), Equals, "[table:1748]Found a row not matching the given partition set") + err = tk.ExecToErr("update t1 partition(p0) set a = 40 where a = 2") + c.Assert(err.Error(), Equals, "[table:1748]Found a row not matching the given partition set") + // test non-exist partition. + err = tk.ExecToErr("update t1 partition (p0, p_non_exist) set a = 40") + c.Assert(err.Error(), Equals, "[table:1735]Unknown partition 'p_non_exist' in table 't1'") + // test join. + err = tk.ExecToErr("update t1 partition (p0), t3 set t1.a = 40 where t3.a = 2") + c.Assert(err.Error(), Equals, "[table:1748]Found a row not matching the given partition set") + + tk.MustExec("update t1 partition(p0) set a = 3 where a = 2") + tk.MustExec("update t1 partition(p0, p3) set a = 33 where a = 1") + + // update without partition change + tk.MustExec("insert into t2 values(1, 'a'), (2, 'b'), (11, 'c'), (21, 'd')") + err = tk.ExecToErr("update t2 partition(p0, p1) set a = 40") + c.Assert(err.Error(), Equals, "[table:1748]Found a row not matching the given partition set") + err = tk.ExecToErr("update t2 partition(p0) set a = 40 where a = 2") + c.Assert(err.Error(), Equals, "[table:1748]Found a row not matching the given partition set") + + tk.MustExec("update t2 partition(p0) set a = 3 where a = 2") + tk.MustExec("update t2 partition(p0, p3) set a = 33 where a = 1") +} +>>>>>>> 313ed01... expression,executor: fix DIV() as partition expression behavior under ERROR_FOR_DIVISION_BY_ZERO sql_mode (#17302) diff --git a/expression/builtin_arithmetic.go b/expression/builtin_arithmetic.go index 7bd59ec95347a..e2e7b839c9784 100644 --- a/expression/builtin_arithmetic.go +++ b/expression/builtin_arithmetic.go @@ -747,16 +747,20 @@ func (s *builtinArithmeticIntDivideDecimalSig) Clone() builtinFunc { } func (s *builtinArithmeticIntDivideIntSig) evalInt(row chunk.Row) (int64, bool, error) { - b, isNull, err := s.args[1].EvalInt(s.ctx, row) + return s.evalIntWithCtx(s.ctx, row) +} + +func (s *builtinArithmeticIntDivideIntSig) evalIntWithCtx(sctx sessionctx.Context, row chunk.Row) (int64, bool, error) { + b, isNull, err := s.args[1].EvalInt(sctx, row) if isNull || err != nil { return 0, isNull, err } if b == 0 { - return 0, true, handleDivisionByZeroError(s.ctx) + return 0, true, handleDivisionByZeroError(sctx) } - a, isNull, err := s.args[0].EvalInt(s.ctx, row) + a, isNull, err := s.args[0].EvalInt(sctx, row) if isNull || err != nil { return 0, isNull, err }