Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: fix utf8 charset upgrade compatibility #9820

Merged
merged 24 commits into from
Mar 25, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
3924856
add ignore-column-utf8-charset to toml config file and default is true
crazycs520 Mar 20, 2019
d96be67
make ignore-column-utf8-charset take effect in check no-utf8mb4 and s…
crazycs520 Mar 20, 2019
3a77bc6
add test and fix test
crazycs520 Mar 20, 2019
16494b2
treat utf8 as utf8mb4 for old version table/column
crazycs520 Mar 20, 2019
c8e5b9d
add test and modify/change column should not change column version
crazycs520 Mar 21, 2019
15c43af
update variable name
crazycs520 Mar 21, 2019
18125dc
refine code
crazycs520 Mar 21, 2019
40c68dc
refine code
crazycs520 Mar 21, 2019
e4f71a1
add column version for view column
crazycs520 Mar 21, 2019
1ed6ef6
increase table and column version
crazycs520 Mar 21, 2019
655fc6b
add tidb_treat_old_version_utf8_as_utf8mb4 system variable
crazycs520 Mar 22, 2019
adc67a2
address comment
crazycs520 Mar 22, 2019
786c6e8
address comment
crazycs520 Mar 22, 2019
7c1b4f4
update go.mod for parser
crazycs520 Mar 22, 2019
a612ab9
Merge branch 'master' of https://github.com/pingcap/tidb into fix-cha…
crazycs520 Mar 22, 2019
b0512cf
ConvertOldVersionUTF8AsUTF8MB4IfNeed when load schema, TODO: fix chan…
crazycs520 Mar 25, 2019
99de30a
add comment
crazycs520 Mar 25, 2019
e757f21
*: remove http api modify treat-old-version-utf8-as-utf8mb4 and sessi…
crazycs520 Mar 25, 2019
62d49b8
remove redundancy code
crazycs520 Mar 25, 2019
d6b6280
fix alter table charset
crazycs520 Mar 25, 2019
57f22e6
add comment
crazycs520 Mar 25, 2019
2d226d1
Merge branch 'master' into fix-charset-upgrade
winkyao Mar 25, 2019
e520900
Merge branch 'master' of https://github.com/pingcap/tidb into fix-cha…
crazycs520 Mar 25, 2019
44912c8
Merge branch 'fix-charset-upgrade' of https://github.com/crazycs520/t…
crazycs520 Mar 25, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 28 additions & 26 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,19 @@ type Config struct {
// TODO: We actually only support mode 2, which keeps the original case, but the comparison is case-insensitive.
LowerCaseTableNames int `toml:"lower-case-table-names" json:"lower-case-table-names"`

Log Log `toml:"log" json:"log"`
Security Security `toml:"security" json:"security"`
Status Status `toml:"status" json:"status"`
Performance Performance `toml:"performance" json:"performance"`
PreparedPlanCache PreparedPlanCache `toml:"prepared-plan-cache" json:"prepared-plan-cache"`
OpenTracing OpenTracing `toml:"opentracing" json:"opentracing"`
ProxyProtocol ProxyProtocol `toml:"proxy-protocol" json:"proxy-protocol"`
TiKVClient TiKVClient `toml:"tikv-client" json:"tikv-client"`
Binlog Binlog `toml:"binlog" json:"binlog"`
CompatibleKillQuery bool `toml:"compatible-kill-query" json:"compatible-kill-query"`
Plugin Plugin `toml:"plugin" json:"plugin"`
CheckMb4ValueInUtf8 bool `toml:"check-mb4-value-in-utf8" json:"check-mb4-value-in-utf8"`
Log Log `toml:"log" json:"log"`
Security Security `toml:"security" json:"security"`
Status Status `toml:"status" json:"status"`
Performance Performance `toml:"performance" json:"performance"`
PreparedPlanCache PreparedPlanCache `toml:"prepared-plan-cache" json:"prepared-plan-cache"`
OpenTracing OpenTracing `toml:"opentracing" json:"opentracing"`
ProxyProtocol ProxyProtocol `toml:"proxy-protocol" json:"proxy-protocol"`
TiKVClient TiKVClient `toml:"tikv-client" json:"tikv-client"`
Binlog Binlog `toml:"binlog" json:"binlog"`
CompatibleKillQuery bool `toml:"compatible-kill-query" json:"compatible-kill-query"`
Plugin Plugin `toml:"plugin" json:"plugin"`
CheckMb4ValueInUtf8 bool `toml:"check-mb4-value-in-utf8" json:"check-mb4-value-in-utf8"`
IgnoreColumnUTF8Charset bool `toml:"ignore-column-utf8-charset" json:"ignore-column-utf8-charset"`
}

// Log is the log section of config.
Expand Down Expand Up @@ -267,20 +268,21 @@ type Plugin struct {
}

var defaultConf = Config{
Host: "0.0.0.0",
AdvertiseAddress: "",
Port: 4000,
Cors: "",
Store: "mocktikv",
Path: "/tmp/tidb",
RunDDL: true,
SplitTable: true,
Lease: "45s",
TokenLimit: 1000,
OOMAction: "log",
MemQuotaQuery: 32 << 30,
EnableStreaming: false,
CheckMb4ValueInUtf8: true,
Host: "0.0.0.0",
AdvertiseAddress: "",
Port: 4000,
Cors: "",
Store: "mocktikv",
Path: "/tmp/tidb",
RunDDL: true,
SplitTable: true,
Lease: "45s",
TokenLimit: 1000,
OOMAction: "log",
MemQuotaQuery: 32 << 30,
EnableStreaming: false,
CheckMb4ValueInUtf8: true,
IgnoreColumnUTF8Charset: true,
TxnLocalLatches: TxnLocalLatches{
Enabled: true,
Capacity: 2048000,
Expand Down
3 changes: 3 additions & 0 deletions config/config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ compatible-kill-query = false
# check mb4 value in utf8 is used to control whether to check the mb4 characters when the charset is utf8.
check-mb4-value-in-utf8 = true

# ignore-column-utf8-charset use for upgrade compatibility. Set to true will ignore column charset and use table charset when column charset is UTF8.
ignore-column-utf8-charset = true

[log]
# Log level: debug, info, warn, error, fatal.
level = "info"
Expand Down
29 changes: 27 additions & 2 deletions ddl/db_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/pingcap/parser/mysql"
tmysql "github.com/pingcap/parser/mysql"
"github.com/pingcap/parser/terror"
"github.com/pingcap/tidb/config"
"github.com/pingcap/tidb/ddl"
"github.com/pingcap/tidb/domain"
"github.com/pingcap/tidb/infoschema"
Expand Down Expand Up @@ -1221,8 +1222,7 @@ func (s *testIntegrationSuite) assertAlterErrorExec(c *C, sql string) {
func (s *testIntegrationSuite) TestAlterAlgorithm(c *C) {
s.tk = testkit.NewTestKit(c, s.store)
s.tk.MustExec("use test")
s.tk.MustExec("drop table if exists t")
s.tk.MustExec("drop table if exists t1")
s.tk.MustExec("drop table if exists t, t1")
defer s.tk.MustExec("drop table if exists t")

s.tk.MustExec(`create table t(
Expand Down Expand Up @@ -1282,3 +1282,28 @@ func (s *testIntegrationSuite) TestAlterAlgorithm(c *C) {
s.assertAlterErrorExec(c, "alter table t default charset = utf8mb4, ALGORITHM=INPLACE")
s.tk.MustExec("alter table t default charset = utf8mb4, ALGORITHM=INSTANT")
}

func (s *testIntegrationSuite) TestIgnoreColumnUTF8Charset(c *C) {
s.tk = testkit.NewTestKit(c, s.store)
s.tk.MustExec("use test")
s.tk.MustExec("drop table if exists t")
defer s.tk.MustExec("drop table if exists t")

s.tk.MustExec("create table t (a varchar(10) character set utf8, b varchar(10) character set ascii) charset=utf8mb4;")
c.Assert(config.GetGlobalConfig().IgnoreColumnUTF8Charset, IsTrue)
c.Assert(config.GetGlobalConfig().CheckMb4ValueInUtf8, IsTrue)
s.tk.MustExec("insert into t set a= x'f09f8c80'")
s.tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n" +
" `a` varchar(10) DEFAULT NULL,\n" +
" `b` varchar(10) CHARACTER SET ascii COLLATE ascii_bin DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))

config.GetGlobalConfig().IgnoreColumnUTF8Charset = false
assertErrorCode(c, s.tk, "insert into t set a= x'f09f8c80';", mysql.ErrTruncatedWrongValueForField)
s.tk.MustQuery("show create table t").Check(testkit.Rows("t CREATE TABLE `t` (\n" +
" `a` varchar(10) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,\n" +
" `b` varchar(10) CHARACTER SET ascii COLLATE ascii_bin DEFAULT NULL\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin"))

config.GetGlobalConfig().IgnoreColumnUTF8Charset = true
}
2 changes: 2 additions & 0 deletions ddl/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/pingcap/parser/mysql"
tmysql "github.com/pingcap/parser/mysql"
"github.com/pingcap/parser/terror"
"github.com/pingcap/tidb/config"
"github.com/pingcap/tidb/ddl"
testddlutil "github.com/pingcap/tidb/ddl/testutil"
"github.com/pingcap/tidb/domain"
Expand Down Expand Up @@ -2651,6 +2652,7 @@ func (s *testDBSuite) TestModifyColumnCharset(c *C) {
s.tk.MustExec("create table t_mcc(a varchar(8) charset utf8, b varchar(8) charset utf8)")
defer s.mustExec(c, "drop table t_mcc;")

config.GetGlobalConfig().IgnoreColumnUTF8Charset = false
result := s.tk.MustQuery(`show create table t_mcc`)
result.Check(testkit.Rows(
"t_mcc CREATE TABLE `t_mcc` (\n" +
Expand Down
4 changes: 3 additions & 1 deletion executor/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,9 @@ func (e *ShowExec) fetchShowCreateTable() error {
fmt.Fprintf(&buf, " %s %s", escape(col.Name, sqlMode), col.GetTypeDesc())
if col.Charset != "binary" {
if col.Charset != tblCharset || col.Collate != tblCollate {
fmt.Fprintf(&buf, " CHARACTER SET %s COLLATE %s", col.Charset, col.Collate)
if col.Charset != charset.CharsetUTF8 || !config.GetGlobalConfig().IgnoreColumnUTF8Charset {
fmt.Fprintf(&buf, " CHARACTER SET %s COLLATE %s", col.Charset, col.Collate)
}
}
}
if col.IsGenerated() {
Expand Down
1 change: 1 addition & 0 deletions executor/statement_context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ func (s *testSuite1) TestStatementContext(c *C) {
tk.MustExec("drop table if exists t1")
tk.MustExec("create table t1(a varchar(100) charset utf8);")
defer tk.MustExec("drop table if exists t1")
config.GetGlobalConfig().IgnoreColumnUTF8Charset = false
tk.MustExec("insert t1 values (unhex('f09f8c80'))")
c.Assert(tk.Se.GetSessionVars().StmtCtx.WarningCount(), Greater, uint16(0))
tk.MustQuery("select * from t1").Check(testkit.Rows(""))
Expand Down
11 changes: 11 additions & 0 deletions server/http_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,17 @@ func (h settingsHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
}
if ignoreColumnUTF8Charset := req.Form.Get("ignore-column-utf8-charset"); ignoreColumnUTF8Charset != "" {
switch ignoreColumnUTF8Charset {
case "0":
config.GetGlobalConfig().IgnoreColumnUTF8Charset = false
case "1":
config.GetGlobalConfig().IgnoreColumnUTF8Charset = true
default:
writeError(w, errors.New("illegal argument"))
return
}
}
} else {
writeData(w, config.GetGlobalConfig())
}
Expand Down
15 changes: 15 additions & 0 deletions server/http_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,7 @@ func (ts *HTTPHandlerTestSuite) TestPostSettings(c *C) {
c.Assert(config.GetGlobalConfig().CheckMb4ValueInUtf8, Equals, true)
txn1, err := dbt.db.Begin()
c.Assert(err, IsNil)
config.GetGlobalConfig().IgnoreColumnUTF8Charset = false
_, err = txn1.Exec("insert t2 values (unhex('F0A48BAE'));")
c.Assert(err, NotNil)
txn1.Commit()
Expand All @@ -675,6 +676,20 @@ func (ts *HTTPHandlerTestSuite) TestPostSettings(c *C) {
c.Assert(resp.StatusCode, Equals, http.StatusOK)
c.Assert(config.GetGlobalConfig().CheckMb4ValueInUtf8, Equals, false)
dbt.mustExec("insert t2 values (unhex('f09f8c80'));")

// Test enable ignore-column-utf8-charset.
form.Set("ignore-column-utf8-charset", "0")
resp, err = http.PostForm("http://127.0.0.1:10090/settings", form)
c.Assert(err, IsNil)
c.Assert(resp.StatusCode, Equals, http.StatusOK)
c.Assert(config.GetGlobalConfig().IgnoreColumnUTF8Charset, Equals, false)

// Test Disable ignore-column-utf8-charset.
form.Set("ignore-column-utf8-charset", "1")
resp, err = http.PostForm("http://127.0.0.1:10090/settings", form)
c.Assert(err, IsNil)
c.Assert(resp.StatusCode, Equals, http.StatusOK)
c.Assert(config.GetGlobalConfig().IgnoreColumnUTF8Charset, Equals, true)
}

func (ts *HTTPHandlerTestSuite) TestPprof(c *C) {
Expand Down
2 changes: 1 addition & 1 deletion table/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func CastValue(ctx sessionctx.Context, val types.Datum, col *model.ColumnInfo) (
}
casted, err = handleWrongUtf8Value(ctx, col, &casted, str, i)
break
} else if width > 3 && utf8Charset && config.GetGlobalConfig().CheckMb4ValueInUtf8 {
} else if width > 3 && utf8Charset && config.GetGlobalConfig().CheckMb4ValueInUtf8 && !config.GetGlobalConfig().IgnoreColumnUTF8Charset {
zimulala marked this conversation as resolved.
Show resolved Hide resolved
// Handle non-BMP characters.
casted, err = handleWrongUtf8Value(ctx, col, &casted, str, i)
break
Expand Down