Skip to content

Commit d261b6a

Browse files
authored
ddl:In non-strict sql mode, fix column type is text /blob/json default value null not processed. (#7230)
* in non-strict SQL mode,fix column type is text /blob/json default value null not processed.
1 parent 7e48ab1 commit d261b6a

File tree

2 files changed

+78
-10
lines changed

2 files changed

+78
-10
lines changed

ddl/db_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2144,6 +2144,60 @@ func (s *testDBSuite) TestYearTypeCreateTable(c *C) {
21442144
c.Assert(mysql.HasUnsignedFlag(yearCol.Flag), IsFalse)
21452145
}
21462146

2147+
func (s *testDBSuite) TestCheckColumnDefaultValue(c *C) {
2148+
s.tk = testkit.NewTestKit(c, s.store)
2149+
s.tk.MustExec("use test;")
2150+
s.tk.MustExec("drop table if exists text_default_text;")
2151+
s.testErrorCode(c, "create table text_default_text(c1 text not null default '');", tmysql.ErrBlobCantHaveDefault)
2152+
s.testErrorCode(c, "create table text_default_text(c1 text not null default 'scds');", tmysql.ErrBlobCantHaveDefault)
2153+
2154+
s.tk.MustExec("drop table if exists text_default_json;")
2155+
s.testErrorCode(c, "create table text_default_json(c1 json not null default '');", tmysql.ErrBlobCantHaveDefault)
2156+
s.testErrorCode(c, "create table text_default_json(c1 json not null default 'dfew555');", tmysql.ErrBlobCantHaveDefault)
2157+
2158+
s.tk.MustExec("drop table if exists text_default_blob;")
2159+
s.testErrorCode(c, "create table text_default_blob(c1 blob not null default '');", tmysql.ErrBlobCantHaveDefault)
2160+
s.testErrorCode(c, "create table text_default_blob(c1 blob not null default 'scds54');", tmysql.ErrBlobCantHaveDefault)
2161+
2162+
s.tk.MustExec("set sql_mode='';")
2163+
s.tk.MustExec("drop table if exists text_default_text;")
2164+
s.tk.MustExec("create table text_default_text(c1 text not null default '');")
2165+
s.tk.MustQuery(`show create table text_default_text`).Check(testutil.RowsWithSep("|",
2166+
"text_default_text CREATE TABLE `text_default_text` (\n"+
2167+
" `c1` text NOT NULL\n"+
2168+
") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin",
2169+
))
2170+
ctx := s.tk.Se.(sessionctx.Context)
2171+
is := domain.GetDomain(ctx).InfoSchema()
2172+
tblInfo, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("text_default_text"))
2173+
c.Assert(err, IsNil)
2174+
c.Assert(tblInfo.Meta().Columns[0].DefaultValue, Equals, "")
2175+
2176+
s.tk.MustExec("drop table if exists text_default_blob;")
2177+
s.tk.MustExec("create table text_default_blob(c1 blob not null default '');")
2178+
s.tk.MustQuery(`show create table text_default_blob`).Check(testutil.RowsWithSep("|",
2179+
"text_default_blob CREATE TABLE `text_default_blob` (\n"+
2180+
" `c1` blob NOT NULL\n"+
2181+
") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin",
2182+
))
2183+
is = domain.GetDomain(ctx).InfoSchema()
2184+
tblInfo, err = is.TableByName(model.NewCIStr("test"), model.NewCIStr("text_default_blob"))
2185+
c.Assert(err, IsNil)
2186+
c.Assert(tblInfo.Meta().Columns[0].DefaultValue, Equals, "")
2187+
2188+
s.tk.MustExec("drop table if exists text_default_json;")
2189+
s.tk.MustExec("create table text_default_json(c1 json not null default '');")
2190+
s.tk.MustQuery(`show create table text_default_json`).Check(testutil.RowsWithSep("|",
2191+
"text_default_json CREATE TABLE `text_default_json` (\n"+
2192+
" `c1` json NOT NULL DEFAULT 'null'\n"+
2193+
") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin",
2194+
))
2195+
is = domain.GetDomain(ctx).InfoSchema()
2196+
tblInfo, err = is.TableByName(model.NewCIStr("test"), model.NewCIStr("text_default_json"))
2197+
c.Assert(err, IsNil)
2198+
c.Assert(tblInfo.Meta().Columns[0].DefaultValue, Equals, `null`)
2199+
}
2200+
21472201
func (s *testDBSuite) TestCharacterSetInColumns(c *C) {
21482202
s.tk = testkit.NewTestKit(c, s.store)
21492203
s.tk.MustExec("drop database if exists varchar_test;")

ddl/ddl_api.go

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -251,16 +251,32 @@ func buildColumnAndConstraint(ctx sessionctx.Context, offset int,
251251
return col, cts, nil
252252
}
253253

254-
// checkColumnCantHaveDefaultValue checks the column can have value as default or not.
255-
// Now, TEXT/BLOB/JSON can't have not null value as default.
256-
func checkColumnCantHaveDefaultValue(col *table.Column, value interface{}) (err error) {
254+
// checkColumnDefaultValue checks the default value of the column.
255+
// In non-strict SQL mode, if the default value of the column is an empty string, the default value can be ignored.
256+
// In strict SQL mode, TEXT/BLOB/JSON can't have not null default values.
257+
func checkColumnDefaultValue(ctx sessionctx.Context, col *table.Column, value interface{}) (bool, interface{}, error) {
258+
hasDefaultValue := true
257259
if value != nil && (col.Tp == mysql.TypeJSON ||
258260
col.Tp == mysql.TypeTinyBlob || col.Tp == mysql.TypeMediumBlob ||
259261
col.Tp == mysql.TypeLongBlob || col.Tp == mysql.TypeBlob) {
260-
// TEXT/BLOB/JSON can't have not null default values.
261-
return errBlobCantHaveDefault.GenByArgs(col.Name.O)
262+
// In non-strict SQL mode.
263+
if !ctx.GetSessionVars().SQLMode.HasStrictMode() && value == "" {
264+
if col.Tp == mysql.TypeBlob || col.Tp == mysql.TypeLongBlob {
265+
// The TEXT/BLOB default value can be ignored.
266+
hasDefaultValue = false
267+
}
268+
// In non-strict SQL mode, if the column type is json and the default value is null, it is initialized to an empty array.
269+
if col.Tp == mysql.TypeJSON {
270+
value = `null`
271+
}
272+
sc := ctx.GetSessionVars().StmtCtx
273+
sc.AppendWarning(errBlobCantHaveDefault.GenByArgs(col.Name.O))
274+
return hasDefaultValue, value, nil
275+
}
276+
// In strict SQL mode or default value is not an empty string.
277+
return hasDefaultValue, value, errBlobCantHaveDefault.GenByArgs(col.Name.O)
262278
}
263-
return nil
279+
return hasDefaultValue, value, nil
264280
}
265281

266282
// isExplicitTimeStamp is used to check if explicit_defaults_for_timestamp is on or off.
@@ -326,11 +342,10 @@ func columnDefToCol(ctx sessionctx.Context, offset int, colDef *ast.ColumnDef, o
326342
if err != nil {
327343
return nil, nil, ErrColumnBadNull.Gen("invalid default value - %s", err)
328344
}
329-
if err = checkColumnCantHaveDefaultValue(col, value); err != nil {
345+
if hasDefaultValue, value, err = checkColumnDefaultValue(ctx, col, value); err != nil {
330346
return nil, nil, errors.Trace(err)
331347
}
332348
col.DefaultValue = value
333-
hasDefaultValue = true
334349
removeOnUpdateNowFlag(col)
335350
case ast.ColumnOptionOnUpdate:
336351
// TODO: Support other time functions.
@@ -1462,11 +1477,10 @@ func setDefaultAndComment(ctx sessionctx.Context, col *table.Column, options []*
14621477
if err != nil {
14631478
return ErrColumnBadNull.Gen("invalid default value - %s", err)
14641479
}
1465-
if err = checkColumnCantHaveDefaultValue(col, value); err != nil {
1480+
if hasDefaultValue, value, err = checkColumnDefaultValue(ctx, col, value); err != nil {
14661481
return errors.Trace(err)
14671482
}
14681483
col.DefaultValue = value
1469-
hasDefaultValue = true
14701484
case ast.ColumnOptionComment:
14711485
err := setColumnComment(ctx, col, opt)
14721486
if err != nil {

0 commit comments

Comments
 (0)