Skip to content

Commit 08d5d29

Browse files
authored
*: use StaticExprContext instead of mock context to build expression (#54101)
ref #53388, close #54271
1 parent 14ed0c0 commit 08d5d29

File tree

5 files changed

+57
-9
lines changed

5 files changed

+57
-9
lines changed

pkg/ddl/partition.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ import (
5959
"github.com/pingcap/tidb/pkg/util/dbterror"
6060
"github.com/pingcap/tidb/pkg/util/hack"
6161
"github.com/pingcap/tidb/pkg/util/mathutil"
62-
"github.com/pingcap/tidb/pkg/util/mock"
6362
decoder "github.com/pingcap/tidb/pkg/util/rowDecoder"
6463
"github.com/pingcap/tidb/pkg/util/slice"
6564
"github.com/pingcap/tidb/pkg/util/stringutil"
@@ -4259,9 +4258,7 @@ func (cns columnNameSlice) At(i int) string {
42594258
}
42604259

42614260
func isPartExprUnsigned(ectx expression.EvalContext, tbInfo *model.TableInfo) bool {
4262-
// We should not rely on any configuration, system or session variables, so use a mock ctx!
4263-
// Same as in tables.newPartitionExpr
4264-
ctx := mock.NewContext()
4261+
ctx := tables.NewPartitionExprBuildCtx()
42654262
expr, err := expression.ParseSimpleExpr(ctx, tbInfo.Partition.Expr, expression.WithTableInfo("", tbInfo))
42664263
if err != nil {
42674264
logutil.DDLLogger().Error("isPartExpr failed parsing expression!", zap.Error(err))

pkg/table/tables/BUILD.bazel

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ go_library(
1818
"//pkg/errno",
1919
"//pkg/expression",
2020
"//pkg/expression/context",
21+
"//pkg/expression/contextstatic",
2122
"//pkg/kv",
2223
"//pkg/meta",
2324
"//pkg/meta/autoid",
@@ -43,7 +44,6 @@ go_library(
4344
"//pkg/util/generatedexpr",
4445
"//pkg/util/hack",
4546
"//pkg/util/logutil",
46-
"//pkg/util/mock",
4747
"//pkg/util/ranger",
4848
"//pkg/util/rowcodec",
4949
"//pkg/util/sqlexec",

pkg/table/tables/partition.go

+24-4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/pingcap/errors"
3030
"github.com/pingcap/tidb/pkg/errctx"
3131
"github.com/pingcap/tidb/pkg/expression"
32+
"github.com/pingcap/tidb/pkg/expression/contextstatic"
3233
"github.com/pingcap/tidb/pkg/kv"
3334
"github.com/pingcap/tidb/pkg/parser"
3435
"github.com/pingcap/tidb/pkg/parser/ast"
@@ -44,7 +45,6 @@ import (
4445
"github.com/pingcap/tidb/pkg/util/dbterror"
4546
"github.com/pingcap/tidb/pkg/util/hack"
4647
"github.com/pingcap/tidb/pkg/util/logutil"
47-
"github.com/pingcap/tidb/pkg/util/mock"
4848
"github.com/pingcap/tidb/pkg/util/ranger"
4949
"github.com/pingcap/tidb/pkg/util/stringutil"
5050
"go.uber.org/zap"
@@ -238,10 +238,30 @@ func initPartition(t *partitionedTable, def model.PartitionDefinition) (*partiti
238238
return &newPart, nil
239239
}
240240

241+
// NewPartitionExprBuildCtx returns a context to build partition expression.
242+
func NewPartitionExprBuildCtx() expression.BuildContext {
243+
return contextstatic.NewStaticExprContext(
244+
contextstatic.WithEvalCtx(contextstatic.NewStaticEvalContext(
245+
// Set a non-strict SQL mode and allow all date values if possible to make sure constant fold can work to
246+
// estimate some undetermined result when locating a row to a partition.
247+
// See issue: https://github.com/pingcap/tidb/issues/54271 for details.
248+
contextstatic.WithSQLMode(mysql.ModeAllowInvalidDates),
249+
contextstatic.WithTypeFlags(types.StrictFlags.
250+
WithIgnoreTruncateErr(true).
251+
WithIgnoreZeroDateErr(true).
252+
WithIgnoreZeroInDate(true).
253+
WithIgnoreInvalidDateErr(true),
254+
),
255+
contextstatic.WithErrLevelMap(errctx.LevelMap{
256+
errctx.ErrGroupTruncate: errctx.LevelIgnore,
257+
}),
258+
)),
259+
)
260+
}
261+
241262
func newPartitionExpr(tblInfo *model.TableInfo, tp model.PartitionType, expr string, partCols []model.CIStr, defs []model.PartitionDefinition) (*PartitionExpr, error) {
242-
// a partitioned table cannot rely on session context/sql modes, so use a default one!
243-
ctx := mock.NewContext()
244-
dbName := model.NewCIStr(ctx.GetSessionVars().CurrentDB)
263+
ctx := NewPartitionExprBuildCtx()
264+
dbName := model.NewCIStr(ctx.GetEvalCtx().CurrentDB())
245265
columns, names, err := expression.ColumnInfos2ColumnsAndNames(ctx, dbName, tblInfo.Name, tblInfo.Cols(), tblInfo)
246266
if err != nil {
247267
return nil, err

tests/integrationtest/r/table/partition.result

+17
Original file line numberDiff line numberDiff line change
@@ -569,3 +569,20 @@ a
569569
-1
570570
0
571571
1
572+
set @@sql_mode='allow_invalid_dates';
573+
create table t_54271(a datetime primary key) partition by range columns(a) (
574+
partition p0 values less than ('2020-02-31 00:00:00'),
575+
partition p1 values less than (MAXVALUE)
576+
);
577+
insert into t_54271 values('2020-03-01 00:00:00');
578+
set @@sql_mode='';
579+
insert into t_54271 values('2020-03-01 00:00:00');
580+
Error 1062 (23000): Duplicate entry '2020-03-01 00:00:00' for key 't_54271.PRIMARY'
581+
select * from t_54271;
582+
a
583+
2020-03-01 00:00:00
584+
select * from t_54271 partition (p0);
585+
a
586+
select * from t_54271 partition (p1);
587+
a
588+
2020-03-01 00:00:00

tests/integrationtest/t/table/partition.test

+14
Original file line numberDiff line numberDiff line change
@@ -430,3 +430,17 @@ alter table t partition by range(a) (partition p0 values less than (0), partitio
430430
alter table t remove partitioning;
431431
select * from t;
432432

433+
# Issue #54271
434+
set @@sql_mode='allow_invalid_dates';
435+
create table t_54271(a datetime primary key) partition by range columns(a) (
436+
partition p0 values less than ('2020-02-31 00:00:00'),
437+
partition p1 values less than (MAXVALUE)
438+
);
439+
insert into t_54271 values('2020-03-01 00:00:00');
440+
set @@sql_mode='';
441+
--error 1062
442+
insert into t_54271 values('2020-03-01 00:00:00');
443+
select * from t_54271;
444+
select * from t_54271 partition (p0);
445+
select * from t_54271 partition (p1);
446+

0 commit comments

Comments
 (0)