Repository: pingcap/tidb (Go)

Issue:
Can't create latin1 enum
## 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. -->
```
mysql root@127.0.0.1:test> create table t1 (a enum(0xE4, '1', '2') not null default 0xE4) character set latin1;
```

### 2. What did you expect to see? (Required)
```
mysql root@127.0.0.1:test> create table t1 (a enum(0xE4, '1', '2') not null default 0xE4) character set latin1;
Query OK, 0 rows affected
Time: 0.024s
mysql root@127.0.0.1:test> show create table t1
+-------+----------------------------------------------+
| Table | Create Table                                 |
+-------+----------------------------------------------+
| t1    | CREATE TABLE `t1` (                          |
|       |   `a` enum('ä','1','2') NOT NULL DEFAULT 'ä' |
|       | ) ENGINE=InnoDB DEFAULT CHARSET=latin1       |
+-------+----------------------------------------------+
1 row in set
Time: 0.016s
```

### 3. What did you see instead (Required)
```
mysql root@127.0.0.1:test> create table t1 (a enum(0xE4, '1', '2') not null default 0xE4) character set latin1;
(1064, 'You have an error in your SQL syntax; check the manual that corresponds to your TiDB version for the right syntax to use line 1 column 28 near "0xE4, \'1\', \'2\') not null default 0xE4) character set latin1" ')
```

### 4. Affected version (Required)

<!-- v3.0.0, v4.0.0, etc -->
```
mysql root@127.0.0.1:test> select tidb_version()
+-------------------------------------------------------------------+
| tidb_version()                                                    |
+-------------------------------------------------------------------+
| Release Version: v4.0.0-beta.2-888-g4645c6582                     |
| Edition: Community                                                |
| Git Commit Hash: 4645c6582d7d57ae256b1bd7a1c18476c56b4d3c         |
| Git Branch: master                                                |
| UTC Build Time: 2020-08-04 07:06:10                               |
| GoVersion: go1.14.4                                               |
| Race Enabled: false                                               |
| TiKV Min Version: v3.0.0-60965b006877ca7234adaced7890d7b029ed1306 |
| Check Table Before Drop: false                                    |
+-------------------------------------------------------------------+
1 row in set
Time: 0.015s
```

### 5. Root Cause Analysis

<!-- should be filled by the investigator before it's closed -->



Discussion:
/label component/DDL
Here is some other try:

```SQL
create table t1 (a enum('ä', '1', '2') not null default 'ä') character set latin1; -- OK
create table t1 (a enum(0xE4, '1', '2') not null default 0xE4); -- NG
create table t1 (a enum('ä', '1', '2') not null default 0xE4); -- OK
```

Thus the reason is that parser takes the `0xE4` as an `hexLit` instead of `stringLit`.

While no specific way to fix has been occurred to...
After pingcap/parser#975 merged, now the error message becomes
```sql
test> create table t1 (a enum(0xE4, '1', '2') not null default 0xE4) character set latin1;                                                                
(1067, "Invalid default value for 'a'")
```

The problem locates in `getDefaultValue()` of `ddl/ddl_api.go`. When the datum kind is `mysql.TypeEnum`, the value should be stored as a string instead of an integer number.
/assign
## Please edit this 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/ddl/ddl_api.go b/ddl/ddl_api.go
index 20a508c8cfbc2..4288b1b145d0d 100644
--- a/ddl/ddl_api.go
+++ b/ddl/ddl_api.go
@@ -742,7 +742,7 @@ func getDefaultValue(ctx sessionctx.Context, col *table.Column, c *ast.ColumnOpt
 		if tp == mysql.TypeBit ||
 			tp == mysql.TypeString || tp == mysql.TypeVarchar || tp == mysql.TypeVarString ||
 			tp == mysql.TypeBlob || tp == mysql.TypeLongBlob || tp == mysql.TypeMediumBlob || tp == mysql.TypeTinyBlob ||
-			tp == mysql.TypeJSON {
+			tp == mysql.TypeJSON || tp == mysql.TypeEnum || tp == mysql.TypeSet {
 			// For BinaryLiteral / string fields, when getting default value we cast the value into BinaryLiteral{}, thus we return
 			// its raw string content here.
 			return v.GetBinaryLiteral().ToString(), false, nil


Test patch:
diff --git a/ddl/db_integration_test.go b/ddl/db_integration_test.go
index c7a385778ef92..aedf79146b1c2 100644
--- a/ddl/db_integration_test.go
+++ b/ddl/db_integration_test.go
@@ -2530,3 +2530,21 @@ func (s *testIntegrationSuite3) TestIssue20490(c *C) {
 
 	tk.MustQuery("select b from issue20490 order by a;").Check(testkit.Rows("1", "1", "<nil>"))
 }
+
+// TestDefaultValueIsLatin1 for issue #18977
+func (s *testIntegrationSuite3) TestEnumAndSetDefaultValue(c *C) {
+	tk := testkit.NewTestKit(c, s.store)
+	tk.MustExec("use test")
+	tk.MustExec("drop table if exists t")
+	defer tk.MustExec("drop table if exists t")
+	tk.MustExec("create table t (a enum(0x61, 'b') not null default 0x61, b set(0x61, 'b') not null default 0x61) character set latin1")
+	tbl := testGetTableByName(c, s.ctx, "test", "t")
+	c.Assert(tbl.Meta().Columns[0].DefaultValue, Equals, "a")
+	c.Assert(tbl.Meta().Columns[1].DefaultValue, Equals, "a")
+
+	tk.MustExec("drop table t")
+	tk.MustExec("create table t (a enum(0x61, 'b') not null default 0x61, b set(0x61, 'b') not null default 0x61) character set utf8mb4")
+	tbl = testGetTableByName(c, s.ctx, "test", "t")
+	c.Assert(tbl.Meta().Columns[0].DefaultValue, Equals, "a")
+	c.Assert(tbl.Meta().Columns[1].DefaultValue, Equals, "a")
+}