Skip to content

Commit 65c78b2

Browse files
authored
importinto: use same type context flag setting as insert (#58606) (#61882)
close #58443
1 parent 2512de3 commit 65c78b2

File tree

5 files changed

+69
-2
lines changed

5 files changed

+69
-2
lines changed

pkg/executor/executor.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2124,6 +2124,7 @@ func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) {
21242124

21252125
errLevels := sc.ErrLevels()
21262126
errLevels[errctx.ErrGroupDividedByZero] = errctx.LevelWarn
2127+
inImportInto := false
21272128
switch stmt := s.(type) {
21282129
// `ResetUpdateStmtCtx` and `ResetDeleteStmtCtx` may modify the flags, so we'll need to store them.
21292130
case *ast.UpdateStmt:
@@ -2148,6 +2149,7 @@ func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) {
21482149
!strictSQLMode || stmt.IgnoreErr,
21492150
)
21502151
sc.Priority = stmt.Priority
2152+
sc.SetTypeFlags(util.GetTypeFlagsForInsert(sc.TypeFlags(), vars.SQLMode, stmt.IgnoreErr))
21512153
sc.SetTypeFlags(sc.TypeFlags().
21522154
WithTruncateAsWarning(!strictSQLMode || stmt.IgnoreErr).
21532155
WithIgnoreInvalidDateErr(vars.SQLMode.HasAllowInvalidDatesMode()).
@@ -2167,6 +2169,9 @@ func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) {
21672169
sc.InLoadDataStmt = true
21682170
// return warning instead of error when load data meet no partition for value
21692171
errLevels[errctx.ErrGroupNoMatchedPartition] = errctx.LevelWarn
2172+
case *ast.ImportIntoStmt:
2173+
inImportInto = true
2174+
sc.SetTypeFlags(util.GetTypeFlagsForImportInto(sc.TypeFlags(), vars.SQLMode))
21702175
case *ast.SelectStmt:
21712176
sc.InSelectStmt = true
21722177

@@ -2224,7 +2229,7 @@ func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) {
22242229
// WithAllowNegativeToUnsigned with false value indicates values less than 0 should be clipped to 0 for unsigned integer types.
22252230
// This is the case for `insert`, `update`, `alter table`, `create table` and `load data infile` statements, when not in strict SQL mode.
22262231
// see https://dev.mysql.com/doc/refman/5.7/en/out-of-range-and-overflow.html
2227-
WithAllowNegativeToUnsigned(!sc.InInsertStmt && !sc.InLoadDataStmt && !sc.InUpdateStmt && !sc.InCreateOrAlterStmt),
2232+
WithAllowNegativeToUnsigned(!sc.InInsertStmt && !sc.InLoadDataStmt && !inImportInto && !sc.InUpdateStmt && !sc.InCreateOrAlterStmt),
22282233
)
22292234

22302235
vars.PlanCacheParams.Reset()

pkg/executor/executor_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,17 @@
1515
package executor_test
1616

1717
import (
18+
"fmt"
1819
"testing"
1920

21+
"github.com/pingcap/tidb/pkg/domain"
22+
"github.com/pingcap/tidb/pkg/executor"
23+
"github.com/pingcap/tidb/pkg/parser/ast"
24+
"github.com/pingcap/tidb/pkg/parser/mysql"
2025
"github.com/pingcap/tidb/pkg/testkit"
2126
"github.com/pingcap/tidb/pkg/testkit/testfailpoint"
27+
"github.com/pingcap/tidb/pkg/util/mock"
28+
"github.com/stretchr/testify/require"
2229
)
2330

2431
func TestChangePumpAndDrainer(t *testing.T) {
@@ -61,3 +68,37 @@ func TestAdminCheckPanic(t *testing.T) {
6168
tk.MustExec("set @@tidb_enable_fast_table_check = ON")
6269
tk.MustExecToErr("admin check table t")
6370
}
71+
72+
func TestImportIntoShouldHaveSameFlagsAsInsert(t *testing.T) {
73+
insertStmt := &ast.InsertStmt{}
74+
importStmt := &ast.ImportIntoStmt{}
75+
insertCtx := mock.NewContext()
76+
importCtx := mock.NewContext()
77+
domain.BindDomain(insertCtx, &domain.Domain{})
78+
domain.BindDomain(importCtx, &domain.Domain{})
79+
for _, modeStr := range []string{
80+
"",
81+
"IGNORE_SPACE",
82+
"STRICT_TRANS_TABLES",
83+
"STRICT_ALL_TABLES",
84+
"ALLOW_INVALID_DATES",
85+
"NO_ZERO_IN_DATE",
86+
"NO_ZERO_DATE",
87+
"NO_ZERO_IN_DATE,STRICT_ALL_TABLES",
88+
"NO_ZERO_DATE,STRICT_ALL_TABLES",
89+
"NO_ZERO_IN_DATE,NO_ZERO_DATE,STRICT_ALL_TABLES",
90+
} {
91+
t.Run(fmt.Sprintf("mode %s", modeStr), func(t *testing.T) {
92+
mode, err := mysql.GetSQLMode(modeStr)
93+
require.NoError(t, err)
94+
insertCtx.GetSessionVars().SQLMode = mode
95+
require.NoError(t, executor.ResetContextOfStmt(insertCtx, insertStmt))
96+
importCtx.GetSessionVars().SQLMode = mode
97+
require.NoError(t, executor.ResetContextOfStmt(importCtx, importStmt))
98+
99+
insertTypeCtx := insertCtx.GetSessionVars().StmtCtx.TypeCtx()
100+
importTypeCtx := importCtx.GetSessionVars().StmtCtx.TypeCtx()
101+
require.EqualValues(t, insertTypeCtx.Flags(), importTypeCtx.Flags())
102+
})
103+
}
104+
}

pkg/types/context.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ const (
3434
// FlagTruncateAsWarning indicates to append the truncate error to warnings instead of returning it to user.
3535
FlagTruncateAsWarning
3636
// FlagAllowNegativeToUnsigned indicates to allow the casting from negative to unsigned int.
37-
// When this flag is not set by default, casting a negative value to unsigned results an overflow error.
37+
// When this flag is not set by default, casting a negative value to unsigned
38+
// results an overflow error, but if SQL mode is not strict, it's converted
39+
// to 0 with a warning.
3840
// Otherwise, a negative value will be cast to the corresponding unsigned value without any error.
3941
// For example, when casting -1 to an unsigned bigint with `FlagAllowNegativeToUnsigned` set,
4042
// we will get `18446744073709551615` which is the biggest unsigned value.

pkg/util/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ go_library(
3535
"//pkg/parser/terror",
3636
"//pkg/session/txninfo",
3737
"//pkg/sessionctx/stmtctx",
38+
"//pkg/types",
3839
"//pkg/util/collate",
3940
"//pkg/util/disk",
4041
"//pkg/util/execdetails",

pkg/util/misc.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import (
4545
"github.com/pingcap/tidb/pkg/parser/model"
4646
"github.com/pingcap/tidb/pkg/parser/mysql"
4747
"github.com/pingcap/tidb/pkg/parser/terror"
48+
"github.com/pingcap/tidb/pkg/types"
4849
"github.com/pingcap/tidb/pkg/util/collate"
4950
"github.com/pingcap/tidb/pkg/util/logutil"
5051
tlsutil "github.com/pingcap/tidb/pkg/util/tls"
@@ -689,3 +690,20 @@ func createTLSCertificates(certpath string, keypath string, rsaKeySize int) erro
689690
// use RSA and unspecified signature algorithm
690691
return CreateCertificates(certpath, keypath, rsaKeySize, x509.RSA, x509.UnknownSignatureAlgorithm)
691692
}
693+
694+
// GetTypeFlagsForInsert gets the type flags for insert statement.
695+
func GetTypeFlagsForInsert(baseFlags types.Flags, sqlMode mysql.SQLMode, ignoreErr bool) types.Flags {
696+
strictSQLMode := sqlMode.HasStrictMode()
697+
return baseFlags.
698+
WithTruncateAsWarning(!strictSQLMode || ignoreErr).
699+
WithIgnoreInvalidDateErr(sqlMode.HasAllowInvalidDatesMode()).
700+
WithIgnoreZeroInDate(!sqlMode.HasNoZeroInDateMode() ||
701+
!sqlMode.HasNoZeroDateMode() || !strictSQLMode || ignoreErr ||
702+
sqlMode.HasAllowInvalidDatesMode())
703+
}
704+
705+
// GetTypeFlagsForImportInto gets the type flags for import into statement which
706+
// has the same flags as normal `INSERT INTO xxx`.
707+
func GetTypeFlagsForImportInto(baseFlags types.Flags, sqlMode mysql.SQLMode) types.Flags {
708+
return GetTypeFlagsForInsert(baseFlags, sqlMode, false)
709+
}

0 commit comments

Comments
 (0)