Skip to content

Commit 284a3ee

Browse files
authored
importinto: use same type context flag setting as insert (#58606)
close #58443
1 parent 42d4fae commit 284a3ee

File tree

5 files changed

+65
-8
lines changed

5 files changed

+65
-8
lines changed

pkg/executor/select.go

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

10501050
errLevels := sc.ErrLevels()
10511051
errLevels[errctx.ErrGroupDividedByZero] = errctx.LevelWarn
1052+
inImportInto := false
10521053
switch stmt := s.(type) {
10531054
// `ResetUpdateStmtCtx` and `ResetDeleteStmtCtx` may modify the flags, so we'll need to store them.
10541055
case *ast.UpdateStmt:
@@ -1077,12 +1078,7 @@ func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) {
10771078
!strictSQLMode || stmt.IgnoreErr,
10781079
)
10791080
sc.Priority = stmt.Priority
1080-
sc.SetTypeFlags(sc.TypeFlags().
1081-
WithTruncateAsWarning(!strictSQLMode || stmt.IgnoreErr).
1082-
WithIgnoreInvalidDateErr(vars.SQLMode.HasAllowInvalidDatesMode()).
1083-
WithIgnoreZeroInDate(!vars.SQLMode.HasNoZeroInDateMode() ||
1084-
!vars.SQLMode.HasNoZeroDateMode() || !strictSQLMode || stmt.IgnoreErr ||
1085-
vars.SQLMode.HasAllowInvalidDatesMode()))
1081+
sc.SetTypeFlags(util.GetTypeFlagsForInsert(sc.TypeFlags(), vars.SQLMode, stmt.IgnoreErr))
10861082
case *ast.CreateTableStmt, *ast.AlterTableStmt:
10871083
sc.InCreateOrAlterStmt = true
10881084
sc.SetTypeFlags(sc.TypeFlags().
@@ -1096,6 +1092,9 @@ func ResetContextOfStmt(ctx sessionctx.Context, s ast.StmtNode) (err error) {
10961092
sc.InLoadDataStmt = true
10971093
// return warning instead of error when load data meet no partition for value
10981094
errLevels[errctx.ErrGroupNoMatchedPartition] = errctx.LevelWarn
1095+
case *ast.ImportIntoStmt:
1096+
inImportInto = true
1097+
sc.SetTypeFlags(util.GetTypeFlagsForImportInto(sc.TypeFlags(), vars.SQLMode))
10991098
case *ast.SelectStmt:
11001099
sc.InSelectStmt = true
11011100

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

11591158
vars.PlanCacheParams.Reset()

pkg/executor/select_test.go

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

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

2021
"github.com/pingcap/tidb/pkg/domain"
2122
"github.com/pingcap/tidb/pkg/executor"
2223
"github.com/pingcap/tidb/pkg/parser/ast"
24+
"github.com/pingcap/tidb/pkg/parser/mysql"
2325
"github.com/pingcap/tidb/pkg/util/mock"
26+
"github.com/stretchr/testify/require"
2427
)
2528

2629
func BenchmarkResetContextOfStmt(b *testing.B) {
@@ -31,3 +34,37 @@ func BenchmarkResetContextOfStmt(b *testing.B) {
3134
executor.ResetContextOfStmt(ctx, stmt)
3235
}
3336
}
37+
38+
func TestImportIntoShouldHaveSameFlagsAsInsert(t *testing.T) {
39+
insertStmt := &ast.InsertStmt{}
40+
importStmt := &ast.ImportIntoStmt{}
41+
insertCtx := mock.NewContext()
42+
importCtx := mock.NewContext()
43+
insertCtx.BindDomain(&domain.Domain{})
44+
importCtx.BindDomain(&domain.Domain{})
45+
for _, modeStr := range []string{
46+
"",
47+
"IGNORE_SPACE",
48+
"STRICT_TRANS_TABLES",
49+
"STRICT_ALL_TABLES",
50+
"ALLOW_INVALID_DATES",
51+
"NO_ZERO_IN_DATE",
52+
"NO_ZERO_DATE",
53+
"NO_ZERO_IN_DATE,STRICT_ALL_TABLES",
54+
"NO_ZERO_DATE,STRICT_ALL_TABLES",
55+
"NO_ZERO_IN_DATE,NO_ZERO_DATE,STRICT_ALL_TABLES",
56+
} {
57+
t.Run(fmt.Sprintf("mode %s", modeStr), func(t *testing.T) {
58+
mode, err := mysql.GetSQLMode(modeStr)
59+
require.NoError(t, err)
60+
insertCtx.GetSessionVars().SQLMode = mode
61+
require.NoError(t, executor.ResetContextOfStmt(insertCtx, insertStmt))
62+
importCtx.GetSessionVars().SQLMode = mode
63+
require.NoError(t, executor.ResetContextOfStmt(importCtx, importStmt))
64+
65+
insertTypeCtx := insertCtx.GetSessionVars().StmtCtx.TypeCtx()
66+
importTypeCtx := importCtx.GetSessionVars().StmtCtx.TypeCtx()
67+
require.EqualValues(t, insertTypeCtx.Flags(), importTypeCtx.Flags())
68+
})
69+
}
70+
}

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
@@ -41,6 +41,7 @@ go_library(
4141
"//pkg/session/cursor",
4242
"//pkg/session/txninfo",
4343
"//pkg/sessionctx/stmtctx",
44+
"//pkg/types",
4445
"//pkg/util/collate",
4546
"//pkg/util/disk",
4647
"//pkg/util/execdetails",

pkg/util/misc.go

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

0 commit comments

Comments
 (0)