From e9dd353e3141f4dc6c88d6aef3279293eae374f7 Mon Sep 17 00:00:00 2001 From: guo-shaoge Date: Thu, 4 Nov 2021 19:17:02 +0800 Subject: [PATCH] cherry pick #29438 to release-5.1 Signed-off-by: ti-srebot --- expression/builtin_compare.go | 33 +------ expression/builtin_compare_test.go | 4 +- expression/integration_test.go | 140 ++++++++++++++++++++++++++++- 3 files changed, 144 insertions(+), 33 deletions(-) diff --git a/expression/builtin_compare.go b/expression/builtin_compare.go index 5c9367004ec89..51e131aa5c8dd 100644 --- a/expression/builtin_compare.go +++ b/expression/builtin_compare.go @@ -634,11 +634,7 @@ func (b *builtinGreatestTimeSig) Clone() builtinFunc { // evalString evals a builtinGreatestTimeSig. // See http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_greatest -func (b *builtinGreatestTimeSig) evalString(row chunk.Row) (res string, isNull bool, err error) { - var ( - strRes string - timeRes types.Time - ) +func (b *builtinGreatestTimeSig) evalString(row chunk.Row) (strRes string, isNull bool, err error) { sc := b.ctx.GetSessionVars().StmtCtx for i := 0; i < len(b.args); i++ { v, isNull, err := b.args[i].EvalString(b.ctx, row) @@ -657,16 +653,8 @@ func (b *builtinGreatestTimeSig) evalString(row chunk.Row) (res string, isNull b if i == 0 || strings.Compare(v, strRes) > 0 { strRes = v } - if i == 0 || t.Compare(timeRes) > 0 { - timeRes = t - } - } - if timeRes.IsZero() { - res = strRes - } else { - res = timeRes.String() } - return res, false, nil + return strRes, false, nil } type leastFunctionClass struct { @@ -852,12 +840,7 @@ func (b *builtinLeastTimeSig) Clone() builtinFunc { // evalString evals a builtinLeastTimeSig. // See http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#functionleast -func (b *builtinLeastTimeSig) evalString(row chunk.Row) (res string, isNull bool, err error) { - var ( - // timeRes will be converted to a strRes only when the arguments is a valid datetime value. - strRes string // Record the strRes of each arguments. - timeRes types.Time // Record the time representation of a valid arguments. - ) +func (b *builtinLeastTimeSig) evalString(row chunk.Row) (strRes string, isNull bool, err error) { sc := b.ctx.GetSessionVars().StmtCtx for i := 0; i < len(b.args); i++ { v, isNull, err := b.args[i].EvalString(b.ctx, row) @@ -875,17 +858,9 @@ func (b *builtinLeastTimeSig) evalString(row chunk.Row) (res string, isNull bool if i == 0 || strings.Compare(v, strRes) < 0 { strRes = v } - if i == 0 || t.Compare(timeRes) < 0 { - timeRes = t - } } - if timeRes.IsZero() { - res = strRes - } else { - res = timeRes.String() - } - return res, false, nil + return strRes, false, nil } type intervalFunctionClass struct { diff --git a/expression/builtin_compare_test.go b/expression/builtin_compare_test.go index 9d11d8b5ad18a..b8d3db9ae9937 100644 --- a/expression/builtin_compare_test.go +++ b/expression/builtin_compare_test.go @@ -296,11 +296,11 @@ func (s *testEvaluatorSuite) TestGreatestLeastFunc(c *C) { }, { []interface{}{tm, "invalid_time_1", "invalid_time_2", tmWithFsp}, - curTimeWithFspString, curTimeString, false, false, + "invalid_time_2", curTimeString, false, false, }, { []interface{}{tm, "invalid_time_2", "invalid_time_1", tmWithFsp}, - curTimeWithFspString, curTimeString, false, false, + "invalid_time_2", curTimeString, false, false, }, { []interface{}{tm, "invalid_time", nil, tmWithFsp}, diff --git a/expression/integration_test.go b/expression/integration_test.go index aa8c8eb2fce4d..9d1d21630f99e 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -3906,8 +3906,7 @@ func (s *testIntegrationSuite) TestCompareBuiltin(c *C) { result.Check(testkit.Rows("3 c 1.3 2")) tk.MustQuery("show warnings").Check(testkit.Rows()) result = tk.MustQuery(`select greatest(cast("2017-01-01" as datetime), "123", "234", cast("2018-01-01" as date)), greatest(cast("2017-01-01" as date), "123", null)`) - // todo: MySQL returns "2018-01-01 " - result.Check(testkit.Rows("2018-01-01 00:00:00 ")) + result.Check(testkit.Rows("234 ")) tk.MustQuery("show warnings").Check(testutil.RowsWithSep("|", "Warning|1292|Incorrect time value: '123'", "Warning|1292|Incorrect time value: '234'", "Warning|1292|Incorrect time value: '123'")) // for least result = tk.MustQuery(`select least(1, 2, 3), least("a", "b", "c"), least(1.1, 1.2, 1.3), least("123a", 1, 2)`) @@ -9878,3 +9877,140 @@ func (s *testIntegrationSuite) TestConstPropNullFunctions(c *C) { tk.MustExec("insert into t2 values (0, 'c', null), (1, null, 0.1), (3, 'b', 0.01), (2, 'q', 0.12), (null, 'a', -0.1), (null, null, null)") tk.MustQuery("select * from t2 where t2.i2=((select count(1) from t1 where t1.i1=t2.i2))").Check(testkit.Rows("1 0.1")) } +<<<<<<< HEAD +======= + +func (s *testIntegrationSuite) TestIssue27233(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test;") + tk.MustExec("drop table if exists t;") + tk.MustExec("CREATE TABLE `t` (\n `COL1` tinyint(45) NOT NULL,\n `COL2` tinyint(45) NOT NULL,\n PRIMARY KEY (`COL1`,`COL2`) /*T![clustered_index] NONCLUSTERED */\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;") + tk.MustExec("insert into t values(122,100),(124,-22),(124,34),(127,103);") + tk.MustQuery("SELECT col2 FROM t AS T1 WHERE ( SELECT count(DISTINCT COL1, COL2) FROM t AS T2 WHERE T2.COL1 > T1.COL1 ) > 2 ;"). + Check(testkit.Rows("100")) +} + +func (s *testIntegrationSuite) TestIssue27236(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test;") + row := tk.MustQuery(`select extract(hour_second from "-838:59:59.00");`) + row.Check(testkit.Rows("-8385959")) + + tk.MustExec(`drop table if exists t`) + tk.MustExec(`create table t(c1 varchar(100));`) + tk.MustExec(`insert into t values('-838:59:59.00'), ('700:59:59.00');`) + row = tk.MustQuery(`select extract(hour_second from c1) from t order by c1;`) + row.Check(testkit.Rows("-8385959", "7005959")) +} + +func (s *testIntegrationSuite) TestIssue26977(c *C) { + tk := testkit.NewTestKit(c, s.store) + result := tk.MustQuery("select a + 1 as f from (select cast(0xfffffffffffffff0 as unsigned) as a union select cast(1 as unsigned)) t having f != 2;") + result.Check(testkit.Rows("18446744073709551601")) +} + +func (s *testIntegrationSuite) TestIssue27610(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec(`use test;`) + tk.MustExec(`drop table if exists PK_TCOLLATION3966STROBJSTROBJ;`) + tk.MustExec("CREATE TABLE `PK_TCOLLATION3966STROBJSTROBJ` (\n `COL1` enum('ll','aa','bb','cc','dd','ee') COLLATE utf8_general_ci NOT NULL,\n `COL2` varchar(20) COLLATE utf8_general_ci DEFAULT NULL,\n PRIMARY KEY (`COL1`) /*T![clustered_index] CLUSTERED */\n) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;") + tk.MustExec(`insert into PK_TCOLLATION3966STROBJSTROBJ values("ee", "tttt");`) + tk.MustQuery("SELECT col1, COL2 FROM PK_TCOLLATION3966STROBJSTROBJ WHERE COL1 IN ('notexist','6') and col2 not in (\"abcd\");"). + Check(testkit.Rows()) +} + +func (s *testIntegrationSuite) TestLastInsertId(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec(`use test;`) + tk.MustExec(`drop table if exists lastinsertid;`) + tk.MustExec(`create table lastinsertid (id int not null primary key auto_increment);`) + tk.MustQuery("SELECT @@last_insert_id;").Check(testkit.Rows("0")) + tk.MustExec(`INSERT INTO lastinsertid VALUES (NULL);`) + tk.MustQuery("SELECT @@last_insert_id, LAST_INSERT_ID()").Check(testkit.Rows("1 1")) + tk.MustExec(`INSERT INTO lastinsertid VALUES (NULL);`) + tk.MustQuery("SELECT @@last_insert_id, LAST_INSERT_ID()").Check(testkit.Rows("2 2")) + tk.MustExec(`INSERT INTO lastinsertid VALUES (NULL);`) + tk.MustQuery("SELECT @@last_insert_id, LAST_INSERT_ID()").Check(testkit.Rows("3 3")) +} + +func (s *testIntegrationSuite) TestIdentity(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec(`use test;`) + tk.MustExec(`drop table if exists identity;`) + tk.MustExec(`create table identity (id int not null primary key auto_increment);`) + tk.MustQuery("SELECT @@identity;").Check(testkit.Rows("0")) + tk.MustExec(`INSERT INTO identity VALUES (NULL);`) + tk.MustQuery("SELECT @@identity, LAST_INSERT_ID()").Check(testkit.Rows("1 1")) + tk.MustExec(`INSERT INTO identity VALUES (NULL);`) + tk.MustQuery("SELECT @@identity, LAST_INSERT_ID()").Check(testkit.Rows("2 2")) + tk.MustExec(`INSERT INTO identity VALUES (NULL);`) + tk.MustQuery("SELECT @@identity, LAST_INSERT_ID()").Check(testkit.Rows("3 3")) +} + +func (s *testIntegrationSuite) TestIssue28804(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists perf_offline_day;") + tk.MustExec(`CREATE TABLE perf_offline_day ( +uuid varchar(50), +ts timestamp NOT NULL, +user_id varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, +platform varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL, +host_id bigint(20) DEFAULT NULL, +PRIMARY KEY (uuid,ts) /*T![clustered_index] NONCLUSTERED */ +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci +PARTITION BY RANGE ( UNIX_TIMESTAMP(ts) ) ( +PARTITION p20210906 VALUES LESS THAN (1630944000), +PARTITION p20210907 VALUES LESS THAN (1631030400), +PARTITION p20210908 VALUES LESS THAN (1631116800), +PARTITION p20210909 VALUES LESS THAN (1631203200) +);`) + tk.MustExec("set @@tidb_partition_prune_mode = 'static'") + tk.MustExec("INSERT INTO `perf_offline_day` VALUES ('dd082c8a-3bab-4431-943a-348fe0592abd','2021-09-08 13:00:07','Xg9C8zq81jGNbugM', 'pc', 12345);") + tk.MustQuery("SELECT cast(floor(hour(ts) / 4) as char) as win_start FROM perf_offline_day partition (p20210907, p20210908) GROUP BY win_start;").Check(testkit.Rows("3")) +} + +func (s *testIntegrationSuite) TestIssue28643(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a time(4));") + tk.MustExec("insert into t values(\"-838:59:59.000000\");") + tk.MustExec("insert into t values(\"838:59:59.000000\");") + tk.MustExec("set tidb_enable_vectorized_expression = on;") + tk.MustQuery("select hour(a) from t;").Check(testkit.Rows("838", "838")) + tk.MustExec("set tidb_enable_vectorized_expression = off;") + tk.MustQuery("select hour(a) from t;").Check(testkit.Rows("838", "838")) +} + +func (s *testIntegrationSuite) TestIssue29434(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + + tk.MustExec("drop table if exists t1;") + tk.MustExec("create table t1(c1 datetime);") + tk.MustExec("insert into t1 values('2021-12-12 10:10:10.000');") + tk.MustExec("set tidb_enable_vectorized_expression = on;") + tk.MustQuery("select greatest(c1, '99999999999999') from t1;").Check(testkit.Rows("99999999999999")) + tk.MustExec("set tidb_enable_vectorized_expression = off;") + tk.MustQuery("select greatest(c1, '99999999999999') from t1;").Check(testkit.Rows("99999999999999")) + + tk.MustExec("set tidb_enable_vectorized_expression = on;") + tk.MustQuery("select least(c1, '99999999999999') from t1;").Check(testkit.Rows("2021-12-12 10:10:10")) + tk.MustExec("set tidb_enable_vectorized_expression = off;") + tk.MustQuery("select least(c1, '99999999999999') from t1;").Check(testkit.Rows("2021-12-12 10:10:10")) +} + +func (s *testIntegrationSuite) TestIssue29244(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a time(4));") + tk.MustExec("insert into t values(\"-700:10:10.123456111\");") + tk.MustExec("insert into t values(\"700:10:10.123456111\");") + tk.MustExec("set tidb_enable_vectorized_expression = on;") + tk.MustQuery("select microsecond(a) from t;").Check(testkit.Rows("123500", "123500")) + tk.MustExec("set tidb_enable_vectorized_expression = off;") + tk.MustQuery("select microsecond(a) from t;").Check(testkit.Rows("123500", "123500")) +} +>>>>>>> 8ae81b385... expression: fix different results for greatest when vectorized is off (#29438)