From b7e32bcf9994f0fc916c59e6d5f573a39127d105 Mon Sep 17 00:00:00 2001 From: Yuanjia Zhang Date: Mon, 20 May 2024 17:47:46 +0800 Subject: [PATCH] planner: fix the wrong result caused by `year_col cmp out-of-range-uint` (#53395) close pingcap/tidb#50235 --- pkg/planner/core/integration_test.go | 9 +++++++++ pkg/util/ranger/points.go | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/pkg/planner/core/integration_test.go b/pkg/planner/core/integration_test.go index 5c06840c2d4b0..01d8ccd2511b9 100644 --- a/pkg/planner/core/integration_test.go +++ b/pkg/planner/core/integration_test.go @@ -1218,6 +1218,15 @@ func TestRepeatPushDownToTiFlash(t *testing.T) { tk.MustQuery("explain select repeat(a,b) from t;").CheckAt([]int{0, 2, 4}, rows) } +func TestIssue50235(t *testing.T) { + store := testkit.CreateMockStore(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec(`use test`) + tk.MustExec(`create table tt (c year(4) NOT NULL DEFAULT '2016', primary key(c));`) + tk.MustExec(`insert into tt values (2016);`) + tk.MustQuery(`select * from tt where c < 16212511333665770580`).Check(testkit.Rows("2016")) +} + func TestIssue36194(t *testing.T) { store, dom := testkit.CreateMockStoreAndDomain(t) tk := testkit.NewTestKit(t, store) diff --git a/pkg/util/ranger/points.go b/pkg/util/ranger/points.go index 7f015e3f0385e..f01bfa89d97cf 100644 --- a/pkg/util/ranger/points.go +++ b/pkg/util/ranger/points.go @@ -330,6 +330,12 @@ func (r *builder) buildFromBinOp( } // If nulleq with null value, values.ToInt64 will return err if col.GetType().GetType() == mysql.TypeYear && !value.IsNull() { + // Convert the out-of-range uint number to int and then let the following logic can handle it correctly. + // Since the max value of year is 2155, `col op MaxUint` should have the same result with `col op MaxInt`. + if value.Kind() == types.KindUint64 && value.GetUint64() > math.MaxInt64 { + value.SetInt64(math.MaxInt64) + } + // If the original value is adjusted, we need to change the condition. // For example, col < 2156. Since the max year is 2155, 2156 is changed to 2155. // col < 2155 is wrong. It should be col <= 2155.