Repository: pingcap/tidb (Go)

Issue:
partition insert ignore not supported, causing insert to fail
## Bug Report

Please answer these questions before submitting your issue. Thanks!

### 1. Minimal reproduce step (Required)

```
CREATE TABLE `IDT_HP23902` (
  `COL1` smallint DEFAULT NULL,
  `COL2` varchar(20) DEFAULT NULL,
  `COL4` datetime DEFAULT NULL,
  `COL3` bigint DEFAULT NULL,
  `COL5` float DEFAULT NULL,
  KEY `UK_COL1` (`COL1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
PARTITION BY HASH( `COL1`+30 )
PARTITIONS 6;


insert ignore into IDT_HP23902_tmp partition(p0, p1)(col1, col3) values(-10355, 1930590137900568573), (13810, -1332233145730692137);
```

### 2. What did you expect to see? (Required)
 successful
### 3. What did you see instead (Required)
ERROR 1748 (HY000): Found a row not matching the given partition set
### 4. What is your TiDB version? (Required)

```
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tidb_version()                                                                                                                                                                                                                                                                                                               |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Release Version: v5.1.0-alpha-14-gd1b3e4711-dirty
Edition: Community
Git Commit Hash: d1b3e47111a34a2d3e9ca9aec94292f822c2f5a4
Git Branch: master
UTC Build Time: 2021-05-25 02:44:30
GoVersion: go1.13
Race Enabled: false
TiKV Min Version: v3.0.0-60965b006877ca7234adaced7890d7b029ed1306
Check Table Before Drop: false |
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

```




Discussion:
I do not think it is critical, reporting an error does not lead to any wrong data/data corruption.
MySQL reports a warning instead(because of 'IGNORE'):
```
mysql> insert ignore into IDT_HP23902 partition(p0, p1)(col1, col3) values(-10355, 1930590137900568573), (13810, -1332233145730692137);                                                                             
Query OK, 0 rows affected, 2 warnings (0.00 sec)
Records: 2  Duplicates: 2  Warnings: 2

mysql> show warnings;                                                                                     
+---------+------+--------------------------------------------------+
| Level   | Code | Message                                          |
+---------+------+--------------------------------------------------+
| Warning | 1748 | Found a row not matching the given partition set |
| Warning | 1748 | Found a row not matching the given partition set |
+---------+------+--------------------------------------------------+
2 rows in set (0.00 sec)

mysql> select * from IDT_HP23902;                                                                         
Empty set (0.01 sec)
```

So I will treat it as a 'major' bug.
A minimal reproducible case:
```
create table t (
  a int
) partition by range(a) (
  partition p0 values less than (10),
  partition p1 values less than (20)
);
insert ignore into t partition(p0)(a) values(12);
```
The root cause is that the `ignore` key is not working in TiDB.
We can potentially handle this in the documentation. It is not currently described under 'MySQL Compatibility' on
https://docs.pingcap.com/tidb/stable/sql-statement-insert
> We can potentially handle this in the documentation. It is not currently described under 'MySQL Compatibility' on
> https://docs.pingcap.com/tidb/stable/sql-statement-insert

Oh thx, but after investigating, I found this issue can be solved by a one-line bugfix.
Please help me review [my PR]() at your convenience~
## Please edit this comment or add a new comment to complete the following information

### Not a bug

1. Remove the 'type/bug' label
2. Add notes to indicate why it is not a bug

### Duplicate bug

1. Add the 'type/duplicate' label
2. Add the link to the original bug

### Bug

Note: Make Sure that 'component', and 'severity' labels are added
Example for how to fill out the template: https://github.com/pingcap/tidb/issues/20100

#### 1. Root Cause Analysis (RCA) (optional) 
<!-- Write down the reason why this bug occurs -->

#### 2. Symptom (optional)

<!-- What will the user see when this bug occurs. The error message may be in the terminal, log or monitoring -->

#### 3. All Trigger Conditions (optional)

<!-- All the user scenarios that may trigger this bug -->

#### 4. Workaround (optional)

#### 5. Affected versions

<!--
In the format of [start_version:end_version], multiple version ranges are
accepted. If the bug only affects the unreleased version, please input:
"unreleased". For example:

Notes:
  1. Do not use any white spaces in '[]'.
  2. The range in '[]' is a closed interval
  3. The version format is `v$Major.$Minor.$Patch`, the $Majoy and $Minor
     number in a version range should be the same. [v3.0.1:v3.1.2] is
     invalid because the $Minor number of the version range is different.

Example 1: [v3.0.1:v3.0.5], [v4.0.1:v4.0.5]
Example 2: unreleased
-->

#### 6. Fixed versions

<!--
The first released version that contains this fix in each minor version. If the bug's affected version has been released, the fixed version should be a detailed version number; If the bug doesn't affect any released version, the fixed version can be "master";  

Example 1: v3.0.13, v4.0.5
Example 2: master
-->



Patch:
diff --git a/executor/batch_checker.go b/executor/batch_checker.go
index 713496a6cfb6c..ed454a899bd52 100644
--- a/executor/batch_checker.go
+++ b/executor/batch_checker.go
@@ -98,7 +98,7 @@ func getKeysNeedCheckOneRow(ctx sessionctx.Context, t table.Table, row []types.D
 	if p, ok := t.(table.PartitionedTable); ok {
 		t, err = p.GetPartitionByRow(ctx, row)
 		if err != nil {
-			if terr, ok := errors.Cause(err).(*terror.Error); ctx.GetSessionVars().StmtCtx.IgnoreNoPartition && ok && terr.Code() == errno.ErrNoPartitionForGivenValue {
+			if terr, ok := errors.Cause(err).(*terror.Error); ctx.GetSessionVars().StmtCtx.IgnoreNoPartition && ok && (terr.Code() == errno.ErrNoPartitionForGivenValue || terr.Code() == errno.ErrRowDoesNotMatchGivenPartitionSet) {
 				ctx.GetSessionVars().StmtCtx.AppendWarning(err)
 				result = append(result, toBeCheckedRow{ignored: true})
 				return result, nil


Test patch:
diff --git a/executor/partition_table_test.go b/executor/partition_table_test.go
index 114b12000bdfe..5eba30576416c 100644
--- a/executor/partition_table_test.go
+++ b/executor/partition_table_test.go
@@ -1680,6 +1680,37 @@ func (s *partitionTableSuite) PartitionPruningInTransaction(c *C) {
 	tk.MustExec(`rollback`)
 }
 
+func (s *partitionTableSuite) TestIssue25253(c *C) {
+	tk := testkit.NewTestKitWithInit(c, s.store)
+	tk.MustExec("create database issue25253")
+	defer tk.MustExec("drop database issue25253")
+	tk.MustExec("use issue25253")
+
+	tk.MustExec(`CREATE TABLE IDT_HP23902 (
+	  COL1 smallint DEFAULT NULL,
+	  COL2 varchar(20) DEFAULT NULL,
+	  COL4 datetime DEFAULT NULL,
+	  COL3 bigint DEFAULT NULL,
+	  COL5 float DEFAULT NULL,
+	  KEY UK_COL1 (COL1)
+	) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
+	PARTITION BY HASH( COL1+30 )
+	PARTITIONS 6`)
+	tk.MustExec(`insert ignore into IDT_HP23902 partition(p0, p1)(col1, col3) values(-10355, 1930590137900568573), (13810, -1332233145730692137)`)
+	tk.MustQuery(`show warnings`).Check(testkit.Rows("Warning 1748 Found a row not matching the given partition set",
+		"Warning 1748 Found a row not matching the given partition set"))
+	tk.MustQuery(`select * from IDT_HP23902`).Check(testkit.Rows())
+
+	tk.MustExec(`create table t (
+	  a int
+	) partition by range(a) (
+	  partition p0 values less than (10),
+	  partition p1 values less than (20))`)
+	tk.MustExec(`insert ignore into t partition(p0)(a) values(12)`)
+	tk.MustQuery(`show warnings`).Check(testkit.Rows("Warning 1748 Found a row not matching the given partition set"))
+	tk.MustQuery(`select * from t`).Check(testkit.Rows())
+}
+
 func (s *partitionTableSuite) TestDML(c *C) {
 	if israce.RaceEnabled {
 		c.Skip("exhaustive types test, skip race test")