Skip to content

Commit

Permalink
fix the issue that the default value for BIT is wrong
Browse files Browse the repository at this point in the history
Signed-off-by: Yang Keao <yangkeao@chunibyo.icu>
  • Loading branch information
YangKeao committed Nov 11, 2024
1 parent 6528da5 commit 5d0e1cd
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 0 deletions.
15 changes: 15 additions & 0 deletions pkg/ddl/add_column.go
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,21 @@ func checkColumnDefaultValue(ctx exprctx.BuildContext, col *table.Column, value
}
}
}
if value != nil && col.GetType() == mysql.TypeBit {
v, ok := value.(string)
if !ok {
return hasDefaultValue, value, types.ErrInvalidDefault.GenWithStackByArgs(col.Name.O)
}

// FIXME: the length of the original bit literal has been lost and it'll be ceiled to bytes.
// For example, the following DDL will be allowed, because 4 = 32 / 8.
// CREATE TABLE t (a bit(25) default b'111111111111111111111111111111');
//
// The `Flen` is ceiled to make sure the DDL allowed in MySQL is also allowed in TiDB.
if (col.GetFlen()+7)/8 < len(v) {
return hasDefaultValue, value, types.ErrInvalidDefault.GenWithStackByArgs(col.Name.O)
}
}
return hasDefaultValue, value, nil
}

Expand Down
6 changes: 6 additions & 0 deletions pkg/table/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,12 @@ func getColDefaultValue(ctx expression.BuildContext, col *model.ColumnInfo, defa

switch col.GetType() {
case mysql.TypeTimestamp, mysql.TypeDate, mysql.TypeDatetime:
case mysql.TypeBit:
defaultValBytes, ok := defaultVal.(string)
intest.Assert(ok, "the default value type for bit should be string")
if ok {
return types.NewBinaryLiteralDatum(types.BinaryLiteral(defaultValBytes)), nil
}
default:
value, err := CastColumnValue(ctx, types.NewDatum(defaultVal), col, false, false)
if err != nil {
Expand Down
10 changes: 10 additions & 0 deletions tests/integrationtest/r/ddl/column.result
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,13 @@ t CREATE TABLE `t` (
`a` decimal(10,0) DEFAULT NULL,
`b` decimal(10,0) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
drop table if exists t;
create table t(a bit(2) default b'1111111111111111111111111111111');
Error 1067 (42000): Invalid default value for 'a'
create table t(a bit(4) default b'1111111111111111111111111111111');
Error 1067 (42000): Invalid default value for 'a'
create table t(a bit(24) default b'111111111111111111111111111111');
Error 1067 (42000): Invalid default value for 'a'
create table t(a bit(25) default b'111111111111111111111111111111'); -- fix me. TiDB cannot know the accurate bit literal length after parser, so the 25 bits limitation are ceiled to 32.
drop table t;
create table t(a bit(32) default b'1111111111111111111111111111111');
6 changes: 6 additions & 0 deletions tests/integrationtest/r/table/tables.result
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,9 @@ select count(distinct(_tidb_rowid>>48)) from shard_t;
count(distinct(_tidb_rowid>>48))
3
set @@tidb_shard_allocate_step=default;
drop table if exists t;
create table t(a bit(32) default b'1100010001001110011000100100111');
insert into t values ();
select hex(a) from t;
hex(a)
62273127
12 changes: 12 additions & 0 deletions tests/integrationtest/t/ddl/column.test
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,15 @@ alter table t1 add column d date default '2024-10';
drop table if exists t;
create table t(a decimal(0,0), b decimal(0));
show create table t;

# TestTooLongDefaultValueForBit
drop table if exists t;
-- error 1067
create table t(a bit(2) default b'1111111111111111111111111111111');
-- error 1067
create table t(a bit(4) default b'1111111111111111111111111111111');
-- error 1067
create table t(a bit(24) default b'111111111111111111111111111111');
create table t(a bit(25) default b'111111111111111111111111111111'); -- fix me. TiDB cannot know the accurate bit literal length after parser, so the 25 bits limitation are ceiled to 32.
drop table t;
create table t(a bit(32) default b'1111111111111111111111111111111');
6 changes: 6 additions & 0 deletions tests/integrationtest/t/table/tables.test
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ insert into shard_t values (12);
select count(distinct(_tidb_rowid>>48)) from shard_t;

set @@tidb_shard_allocate_step=default;

# TestInsertBitDefaultValue
drop table if exists t;
create table t(a bit(32) default b'1100010001001110011000100100111');
insert into t values ();
select hex(a) from t;

0 comments on commit 5d0e1cd

Please sign in to comment.