Repository: pingcap/tidb (Go)

Issue:
Wrong result when we filter on the partition column of the partition table
## Bug Report

Please answer these questions before submitting your issue. Thanks!

### 1. Minimal reproduce step (Required)
<!-- a step by step guide for reproducing the bug. -->
```
DROP TABLE IF EXISTS t4;
CREATE TABLE `t4` (
  a bit(1) DEFAULT NULL,
  b int(11) DEFAULT NULL
) PARTITION BY HASH(a)
PARTITIONS 3;
INSERT INTO t4 VALUES(0, 0), (1, 1);
SELECT * FROM t4 WHERE a = 1;
```

### 2. What did you expect to see? (Required)
In mysql8.0
```
mysql> DROP TABLE IF EXISTS t4;
Query OK, 0 rows affected (0.07 sec)

mysql> CREATE TABLE `t4` (
    ->   a bit(1) DEFAULT NULL,
    ->   b int(11) DEFAULT NULL
    -> ) PARTITION BY HASH(a)
    -> PARTITIONS 3;
Query OK, 0 rows affected, 1 warning (0.06 sec)

mysql> INSERT INTO t4 VALUES(0, 0), (1, 1);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM t4 WHERE a = 1;
+------------+------+
| a          | b    |
+------------+------+
| 0x01       |    1 |
+------------+------+
1 row in set (0.00 sec)
```

### 3. What did you see instead (Required)
```
mysql> CREATE TABLE `t4` (
    ->   a bit(1) DEFAULT NULL,
    ->   b int(11) DEFAULT NULL
    -> ) PARTITION BY HASH(a)
    -> PARTITIONS 3;
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO t4 VALUES(0, 0), (1, 1);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM t4 WHERE a = 1;
Empty set (0.01 sec)
```

### 4. What is your TiDB version? (Required)

<!-- Paste the output of SELECT tidb_version() -->
master,4.0
git commit hash: eca1ce192b0a5aae1626c9eb005cd83ee670520f



Discussion:
By the way, if the SQL is `select * from t4 where a = 0`. The result of TiDB is correct.
## 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/table/tables/partition.go b/table/tables/partition.go
index 80b4cf10fa3f2..63e4bba7e2cb1 100644
--- a/table/tables/partition.go
+++ b/table/tables/partition.go
@@ -734,7 +734,18 @@ func (t *partitionedTable) locateRangePartition(ctx sessionctx.Context, pi *mode
 // TODO: supports linear hashing
 func (t *partitionedTable) locateHashPartition(ctx sessionctx.Context, pi *model.PartitionInfo, r []types.Datum) (int, error) {
 	if col, ok := t.partitionExpr.Expr.(*expression.Column); ok {
-		ret := r[col.Index].GetInt64()
+		var data types.Datum
+		switch r[col.Index].Kind() {
+		case types.KindInt64, types.KindUint64:
+			data = r[col.Index]
+		default:
+			var err error
+			data, err = r[col.Index].ConvertTo(ctx.GetSessionVars().StmtCtx, types.NewFieldType(mysql.TypeLong))
+			if err != nil {
+				return 0, err
+			}
+		}
+		ret := data.GetInt64()
 		ret = ret % int64(t.meta.Partition.Num)
 		if ret < 0 {
 			ret = -ret


Test patch:
diff --git a/table/tables/partition_test.go b/table/tables/partition_test.go
index 51287e0f222a4..72b880736a961 100644
--- a/table/tables/partition_test.go
+++ b/table/tables/partition_test.go
@@ -502,3 +502,19 @@ func (ts *testSuite) TestHashPartitionAndConditionConflict(c *C) {
 
 	tk.MustQuery("select * from t2 partition (p1) where t2.a = 6;").Check(testkit.Rows())
 }
+
+func (ts *testSuite) TestHashPartitionInsertValue(c *C) {
+	tk := testkit.NewTestKitWithInit(c, ts.store)
+	tk.MustExec("use test")
+	tk.MustExec("drop tables if exists t4")
+	tk.MustExec(`CREATE TABLE t4(
+	a bit(1) DEFAULT NULL,
+	b int(11) DEFAULT NULL
+	) PARTITION BY HASH(a)
+	PARTITIONS 3`)
+	defer tk.MustExec("drop tables if exists t4")
+	tk.MustExec("INSERT INTO t4 VALUES(0, 0)")
+	tk.MustExec("INSERT INTO t4 VALUES(1, 1)")
+	result := tk.MustQuery("SELECT * FROM t4 WHERE a = 1")
+	result.Check(testkit.Rows("\x01 1"))
+}