Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
d7285006
Commit
d7285006
authored
Dec 17, 2004
by
unknown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bit type
parent
eaec00b1
Changes
27
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
1050 additions
and
40 deletions
+1050
-40
include/m_ctype.h
include/m_ctype.h
+1
-1
include/my_base.h
include/my_base.h
+2
-1
include/my_handler.h
include/my_handler.h
+17
-0
include/mysql_com.h
include/mysql_com.h
+2
-0
myisam/mi_key.c
myisam/mi_key.c
+33
-0
myisam/mi_open.c
myisam/mi_open.c
+12
-4
mysql-test/r/type_bit.result
mysql-test/r/type_bit.result
+364
-0
mysql-test/t/type_bit.test
mysql-test/t/type_bit.test
+106
-0
mysys/my_handler.c
mysys/my_handler.c
+1
-0
sql/field.cc
sql/field.cc
+247
-0
sql/field.h
sql/field.h
+48
-1
sql/field_conv.cc
sql/field_conv.cc
+3
-0
sql/ha_myisam.cc
sql/ha_myisam.cc
+7
-0
sql/ha_myisam.h
sql/ha_myisam.h
+1
-1
sql/handler.h
sql/handler.h
+1
-0
sql/item.cc
sql/item.cc
+47
-8
sql/item.h
sql/item.h
+10
-3
sql/key.cc
sql/key.cc
+30
-0
sql/protocol.cc
sql/protocol.cc
+2
-0
sql/sql_lex.cc
sql/sql_lex.cc
+33
-2
sql/sql_parse.cc
sql/sql_parse.cc
+13
-0
sql/sql_select.cc
sql/sql_select.cc
+5
-1
sql/sql_table.cc
sql/sql_table.cc
+13
-1
sql/sql_yacc.yy
sql/sql_yacc.yy
+35
-7
sql/table.cc
sql/table.cc
+14
-9
sql/unireg.cc
sql/unireg.cc
+1
-1
sql/unireg.h
sql/unireg.h
+2
-0
No files found.
include/m_ctype.h
View file @
d7285006
...
...
@@ -85,7 +85,7 @@ enum my_lex_states
{
MY_LEX_START
,
MY_LEX_CHAR
,
MY_LEX_IDENT
,
MY_LEX_IDENT_SEP
,
MY_LEX_IDENT_START
,
MY_LEX_REAL
,
MY_LEX_HEX_NUMBER
,
MY_LEX_REAL
,
MY_LEX_HEX_NUMBER
,
MY_LEX_BIN_NUMBER
,
MY_LEX_CMP_OP
,
MY_LEX_LONG_CMP_OP
,
MY_LEX_STRING
,
MY_LEX_COMMENT
,
MY_LEX_END
,
MY_LEX_OPERATOR_OR_IDENT
,
MY_LEX_NUMBER_IDENT
,
MY_LEX_INT_OR_REAL
,
MY_LEX_REAL_OR_POINT
,
MY_LEX_BOOL
,
MY_LEX_EOL
,
MY_LEX_ESCAPE
,
...
...
include/my_base.h
View file @
d7285006
...
...
@@ -182,7 +182,8 @@ enum ha_base_keytype {
HA_KEYTYPE_UINT24
=
13
,
HA_KEYTYPE_INT8
=
14
,
HA_KEYTYPE_VARTEXT
=
15
,
/* Key is sorted as letters */
HA_KEYTYPE_VARBINARY
=
16
/* Key is sorted as unsigned chars */
HA_KEYTYPE_VARBINARY
=
16
,
/* Key is sorted as unsigned chars */
HA_KEYTYPE_BIT
=
17
};
#define HA_MAX_KEYTYPE 31
/* Must be log2-1 */
...
...
include/my_handler.h
View file @
d7285006
...
...
@@ -34,6 +34,8 @@ typedef struct st_HA_KEYSEG /* Key-portion */
uint32
start
;
/* Start of key in record */
uint32
null_pos
;
/* position to NULL indicator */
CHARSET_INFO
*
charset
;
uint8
bit_length
;
/* Length of bit part */
uint16
bit_pos
;
/* Position to bit part */
}
HA_KEYSEG
;
#define get_key_length(length,key) \
...
...
@@ -64,6 +66,21 @@ typedef struct st_HA_KEYSEG /* Key-portion */
{ *(key)=255; mi_int2store((key)+1,(length)); (key)+=3; } \
}
#define get_rec_bits(bit_ptr, bit_ofs, bit_len) \
(((((uint16) (bit_ptr)[1] << 8) | (uint16) (bit_ptr)[0]) >> (bit_ofs)) & \
((1 << (bit_len)) - 1))
#define set_rec_bits(bits, bit_ptr, bit_ofs, bit_len) \
{ \
(bit_ptr)[0]= ((bit_ptr)[0] & ((1 << (bit_ofs)) - 1)) | \
((bits) << (bit_ofs)); \
if ((bit_ofs) + (bit_len) > 8) \
(bit_ptr)[1]= ((bits) & ((1 << (bit_len)) - 1)) >> (8 - (bit_ofs)); \
}
#define clr_rec_bits(bit_ptr, bit_ofs, bit_len) \
set_rec_bits(0, bit_ptr, bit_ofs, bit_len)
extern
int
mi_compare_text
(
CHARSET_INFO
*
,
uchar
*
,
uint
,
uchar
*
,
uint
,
my_bool
,
my_bool
);
extern
int
ha_key_cmp
(
register
HA_KEYSEG
*
keyseg
,
register
uchar
*
a
,
...
...
include/mysql_com.h
View file @
d7285006
...
...
@@ -210,6 +210,7 @@ enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
MYSQL_TYPE_DATE
,
MYSQL_TYPE_TIME
,
MYSQL_TYPE_DATETIME
,
MYSQL_TYPE_YEAR
,
MYSQL_TYPE_NEWDATE
,
MYSQL_TYPE_VARCHAR
,
MYSQL_TYPE_BIT
,
MYSQL_TYPE_ENUM
=
247
,
MYSQL_TYPE_SET
=
248
,
MYSQL_TYPE_TINY_BLOB
=
249
,
...
...
@@ -250,6 +251,7 @@ enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
#define FIELD_TYPE_CHAR MYSQL_TYPE_TINY
#define FIELD_TYPE_INTERVAL MYSQL_TYPE_ENUM
#define FIELD_TYPE_GEOMETRY MYSQL_TYPE_GEOMETRY
#define FIELD_TYPE_BIT MYSQL_TYPE_BIT
/* Shutdown/kill enums and constants */
...
...
myisam/mi_key.c
View file @
d7285006
...
...
@@ -82,6 +82,19 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
length
);
pos
=
(
byte
*
)
record
+
keyseg
->
start
;
if
(
type
==
HA_KEYTYPE_BIT
)
{
if
(
keyseg
->
bit_length
)
{
uchar
bits
=
get_rec_bits
((
uchar
*
)
record
+
keyseg
->
bit_pos
,
keyseg
->
bit_start
,
keyseg
->
bit_length
);
*
key
++=
bits
;
length
--
;
}
memcpy
((
byte
*
)
key
,
pos
,
length
);
key
+=
length
;
continue
;
}
if
(
keyseg
->
flag
&
HA_SPACE_PACK
)
{
end
=
pos
+
length
;
...
...
@@ -333,6 +346,26 @@ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
}
record
[
keyseg
->
null_pos
]
&=
~
keyseg
->
null_bit
;
}
if
(
keyseg
->
type
==
HA_KEYTYPE_BIT
)
{
uint
length
=
keyseg
->
length
;
if
(
keyseg
->
bit_length
)
{
uchar
bits
=
*
key
++
;
set_rec_bits
(
bits
,
record
+
keyseg
->
bit_pos
,
keyseg
->
bit_start
,
keyseg
->
bit_length
);
length
--
;
}
else
{
clr_rec_bits
(
record
+
keyseg
->
bit_pos
,
keyseg
->
bit_start
,
keyseg
->
bit_length
);
}
memcpy
(
record
+
keyseg
->
start
,
(
byte
*
)
key
,
length
);
key
+=
length
;
continue
;
}
if
(
keyseg
->
flag
&
HA_SPACE_PACK
)
{
uint
length
;
...
...
myisam/mi_open.c
View file @
d7285006
...
...
@@ -1049,12 +1049,13 @@ int mi_keyseg_write(File file, const HA_KEYSEG *keyseg)
*
ptr
++
=
keyseg
->
null_bit
;
*
ptr
++
=
keyseg
->
bit_start
;
*
ptr
++
=
keyseg
->
bit_end
;
*
ptr
++
=
0
;
/* Not used */
*
ptr
++
=
keyseg
->
bit_length
;
mi_int2store
(
ptr
,
keyseg
->
flag
);
ptr
+=
2
;
mi_int2store
(
ptr
,
keyseg
->
length
);
ptr
+=
2
;
mi_int4store
(
ptr
,
keyseg
->
start
);
ptr
+=
4
;
mi_int4store
(
ptr
,
keyseg
->
null_pos
);
ptr
+=
4
;
mi_int4store
(
ptr
,
keyseg
->
null_bit
?
keyseg
->
null_pos
:
keyseg
->
bit_pos
);
ptr
+=
4
;
return
my_write
(
file
,(
char
*
)
buff
,
(
uint
)
(
ptr
-
buff
),
MYF
(
MY_NABP
));
}
...
...
@@ -1066,12 +1067,19 @@ char *mi_keyseg_read(char *ptr, HA_KEYSEG *keyseg)
keyseg
->
null_bit
=
*
ptr
++
;
keyseg
->
bit_start
=
*
ptr
++
;
keyseg
->
bit_end
=
*
ptr
++
;
ptr
++
;
keyseg
->
bit_length
=
*
ptr
++
;
keyseg
->
flag
=
mi_uint2korr
(
ptr
);
ptr
+=
2
;
keyseg
->
length
=
mi_uint2korr
(
ptr
);
ptr
+=
2
;
keyseg
->
start
=
mi_uint4korr
(
ptr
);
ptr
+=
4
;
keyseg
->
null_pos
=
mi_uint4korr
(
ptr
);
ptr
+=
4
;
keyseg
->
charset
=
0
;
/* Will be filled in later */
if
(
keyseg
->
null_bit
)
keyseg
->
bit_pos
=
keyseg
->
null_pos
+
(
keyseg
->
null_bit
==
7
);
else
{
keyseg
->
bit_pos
=
keyseg
->
null_pos
;
keyseg
->
null_pos
=
0
;
}
return
ptr
;
}
...
...
mysql-test/r/type_bit.result
0 → 100644
View file @
d7285006
select 0 + b'1';
0 + b'1'
1
select 0 + b'0';
0 + b'0'
0
select 0 + b'000001';
0 + b'000001'
1
select 0 + b'000011';
0 + b'000011'
3
select 0 + b'000101';
0 + b'000101'
5
select 0 + b'000000';
0 + b'000000'
0
select 0 + b'10000000';
0 + b'10000000'
128
select 0 + b'11111111';
0 + b'11111111'
255
select 0 + b'10000001';
0 + b'10000001'
129
select 0 + b'1000000000000000';
0 + b'1000000000000000'
32768
select 0 + b'1111111111111111';
0 + b'1111111111111111'
65535
select 0 + b'1000000000000001';
0 + b'1000000000000001'
32769
drop table if exists t1;
create table t1 (a bit(65));
ERROR 42000: Column length too big for column 'a' (max = 64); use BLOB instead
create table t1 (a bit(0));
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a bit, key(a)) engine=innodb;
ERROR 42000: The storage engine for the table doesn't support BIT FIELD
create table t1 (a bit(64));
insert into t1 values
(b'1111111111111111111111111111111111111111111111111111111111111111'),
(b'1000000000000000000000000000000000000000000000000000000000000000'),
(b'0000000000000000000000000000000000000000000000000000000000000001'),
(b'1010101010101010101010101010101010101010101010101010101010101010'),
(b'0101010101010101010101010101010101010101010101010101010101010101');
select hex(a) from t1;
hex(a)
FFFFFFFFFFFFFFFF
8000000000000000
1
AAAAAAAAAAAAAAAA
5555555555555555
drop table t1;
create table t1 (a bit);
insert into t1 values (b'0'), (b'1'), (b'000'), (b'100'), (b'001');
Warnings:
Warning 1264 Out of range value adjusted for column 'a' at row 4
select hex(a) from t1;
hex(a)
0
1
0
1
1
alter table t1 add unique (a);
ERROR 23000: Duplicate entry '' for key 1
drop table t1;
create table t1 (a bit(2));
insert into t1 values (b'00'), (b'01'), (b'10'), (b'100');
Warnings:
Warning 1264 Out of range value adjusted for column 'a' at row 4
select a+0 from t1;
a+0
0
1
2
3
alter table t1 add key (a);
explain select a+0 from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 2 NULL 4 Using index
select a+0 from t1;
a+0
0
1
2
3
drop table t1;
create table t1 (a bit(7), b bit(9), key(a, b));
insert into t1 values
(94, 46), (31, 438), (61, 152), (78, 123), (88, 411), (122, 118), (0, 177),
(75, 42), (108, 67), (79, 349), (59, 188), (68, 206), (49, 345), (118, 380),
(111, 368), (94, 468), (56, 379), (77, 133), (29, 399), (9, 363), (23, 36),
(116, 390), (119, 368), (87, 351), (123, 411), (24, 398), (34, 202), (28, 499),
(30, 83), (5, 178), (60, 343), (4, 245), (104, 280), (106, 446), (127, 403),
(44, 307), (68, 454), (57, 135);
explain select a+0 from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 38 Using index
select a+0 from t1;
a+0
0
4
5
9
23
24
28
29
30
31
34
44
49
56
57
59
60
61
68
68
75
77
78
79
87
88
94
94
104
106
108
111
116
118
119
122
123
127
explain select b+0 from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 38 Using index
select b+0 from t1;
b+0
177
245
178
363
36
398
499
399
83
438
202
307
345
379
135
188
343
152
206
454
42
133
123
349
351
411
46
468
280
446
67
368
390
380
368
118
411
403
explain select a+0, b+0 from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 38 Using index
select a+0, b+0 from t1;
a+0 b+0
0 177
4 245
5 178
9 363
23 36
24 398
28 499
29 399
30 83
31 438
34 202
44 307
49 345
56 379
57 135
59 188
60 343
61 152
68 206
68 454
75 42
77 133
78 123
79 349
87 351
88 411
94 46
94 468
104 280
106 446
108 67
111 368
116 390
118 380
119 368
122 118
123 411
127 403
explain select a+0, b+0 from t1 where a > 40 and b > 200 order by 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 2 NULL 27 Using where; Using index; Using filesort
select a+0, b+0 from t1 where a > 40 and b > 200 order by 1;
a+0 b+0
44 307
49 345
56 379
60 343
68 206
68 454
79 349
87 351
88 411
94 468
104 280
106 446
111 368
116 390
118 380
119 368
123 411
127 403
explain select a+0, b+0 from t1 where a > 40 and a < 70 order by 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 2 NULL 8 Using where; Using index; Using filesort
select a+0, b+0 from t1 where a > 40 and a < 70 order by 2;
a+0 b+0
57 135
61 152
59 188
68 206
44 307
60 343
49 345
56 379
68 454
set @@max_length_for_sort_data=0;
select a+0, b+0 from t1 where a > 40 and a < 70 order by 2;
a+0 b+0
57 135
61 152
59 188
68 206
44 307
60 343
49 345
56 379
68 454
select hex(min(a)) from t1;
hex(min(a))
0
select hex(min(b)) from t1;
hex(min(b))
24
select hex(min(a)), hex(max(a)), hex(min(b)), hex(max(b)) from t1;
hex(min(a)) hex(max(a)) hex(min(b)) hex(max(b))
0 7F 24 1F3
drop table t1;
create table t1 (a int not null, b bit, c bit(9), key(a, b, c));
insert into t1 values
(4, NULL, 1), (4, 0, 3), (2, 1, 4), (1, 1, 100), (4, 0, 23), (4, 0, 54),
(56, 0, 22), (4, 1, 100), (23, 0, 1), (4, 0, 34);
select a+0, b+0, c+0 from t1;
a+0 b+0 c+0
1 1 100
2 1 4
4 NULL 1
4 0 3
4 0 23
4 0 34
4 0 54
4 1 100
23 0 1
56 0 22
select hex(min(b)) from t1 where a = 4;
hex(min(b))
0
select hex(min(c)) from t1 where a = 4 and b = 0;
hex(min(c))
3
select hex(max(b)) from t1;
hex(max(b))
1
select a+0, b+0, c+0 from t1 where a = 4 and b = 0 limit 2;
a+0 b+0 c+0
4 0 3
4 0 23
select a+0, b+0, c+0 from t1 order by b desc;
a+0 b+0 c+0
2 1 4
1 1 100
4 1 100
4 0 3
4 0 23
4 0 54
56 0 22
23 0 1
4 0 34
4 NULL 1
select a+0, b+0, c+0 from t1 order by c;
a+0 b+0 c+0
4 NULL 1
23 0 1
4 0 3
2 1 4
56 0 22
4 0 23
4 0 34
4 0 54
1 1 100
4 1 100
drop table t1;
create table t1(a bit(2), b bit(2));
insert into t1 (a) values (0x01), (0x03), (0x02);
update t1 set b= concat(a);
select a+0, b+0 from t1;
a+0 b+0
1 1
3 3
2 2
drop table t1;
create table t1 (a bit(7), key(a));
insert into t1 values (44), (57);
select a+0 from t1;
a+0
44
57
drop table t1;
mysql-test/t/type_bit.test
0 → 100644
View file @
d7285006
#
# testing of the BIT column type
#
select
0
+
b
'1'
;
select
0
+
b
'0'
;
select
0
+
b
'000001'
;
select
0
+
b
'000011'
;
select
0
+
b
'000101'
;
select
0
+
b
'000000'
;
select
0
+
b
'10000000'
;
select
0
+
b
'11111111'
;
select
0
+
b
'10000001'
;
select
0
+
b
'1000000000000000'
;
select
0
+
b
'1111111111111111'
;
select
0
+
b
'1000000000000001'
;
--
disable_warnings
drop
table
if
exists
t1
;
--
enable_warnings
--
error
1074
create
table
t1
(
a
bit
(
65
));
create
table
t1
(
a
bit
(
0
));
show
create
table
t1
;
drop
table
t1
;
--
error
1178
create
table
t1
(
a
bit
,
key
(
a
))
engine
=
innodb
;
create
table
t1
(
a
bit
(
64
));
insert
into
t1
values
(
b
'1111111111111111111111111111111111111111111111111111111111111111'
),
(
b
'1000000000000000000000000000000000000000000000000000000000000000'
),
(
b
'0000000000000000000000000000000000000000000000000000000000000001'
),
(
b
'1010101010101010101010101010101010101010101010101010101010101010'
),
(
b
'0101010101010101010101010101010101010101010101010101010101010101'
);
select
hex
(
a
)
from
t1
;
drop
table
t1
;
create
table
t1
(
a
bit
);
insert
into
t1
values
(
b
'0'
),
(
b
'1'
),
(
b
'000'
),
(
b
'100'
),
(
b
'001'
);
select
hex
(
a
)
from
t1
;
--
error
1062
alter
table
t1
add
unique
(
a
);
drop
table
t1
;
create
table
t1
(
a
bit
(
2
));
insert
into
t1
values
(
b
'00'
),
(
b
'01'
),
(
b
'10'
),
(
b
'100'
);
select
a
+
0
from
t1
;
alter
table
t1
add
key
(
a
);
explain
select
a
+
0
from
t1
;
select
a
+
0
from
t1
;
drop
table
t1
;
create
table
t1
(
a
bit
(
7
),
b
bit
(
9
),
key
(
a
,
b
));
insert
into
t1
values
(
94
,
46
),
(
31
,
438
),
(
61
,
152
),
(
78
,
123
),
(
88
,
411
),
(
122
,
118
),
(
0
,
177
),
(
75
,
42
),
(
108
,
67
),
(
79
,
349
),
(
59
,
188
),
(
68
,
206
),
(
49
,
345
),
(
118
,
380
),
(
111
,
368
),
(
94
,
468
),
(
56
,
379
),
(
77
,
133
),
(
29
,
399
),
(
9
,
363
),
(
23
,
36
),
(
116
,
390
),
(
119
,
368
),
(
87
,
351
),
(
123
,
411
),
(
24
,
398
),
(
34
,
202
),
(
28
,
499
),
(
30
,
83
),
(
5
,
178
),
(
60
,
343
),
(
4
,
245
),
(
104
,
280
),
(
106
,
446
),
(
127
,
403
),
(
44
,
307
),
(
68
,
454
),
(
57
,
135
);
explain
select
a
+
0
from
t1
;
select
a
+
0
from
t1
;
explain
select
b
+
0
from
t1
;
select
b
+
0
from
t1
;
explain
select
a
+
0
,
b
+
0
from
t1
;
select
a
+
0
,
b
+
0
from
t1
;
explain
select
a
+
0
,
b
+
0
from
t1
where
a
>
40
and
b
>
200
order
by
1
;
select
a
+
0
,
b
+
0
from
t1
where
a
>
40
and
b
>
200
order
by
1
;
explain
select
a
+
0
,
b
+
0
from
t1
where
a
>
40
and
a
<
70
order
by
2
;
select
a
+
0
,
b
+
0
from
t1
where
a
>
40
and
a
<
70
order
by
2
;
set
@@
max_length_for_sort_data
=
0
;
select
a
+
0
,
b
+
0
from
t1
where
a
>
40
and
a
<
70
order
by
2
;
select
hex
(
min
(
a
))
from
t1
;
select
hex
(
min
(
b
))
from
t1
;
select
hex
(
min
(
a
)),
hex
(
max
(
a
)),
hex
(
min
(
b
)),
hex
(
max
(
b
))
from
t1
;
drop
table
t1
;
create
table
t1
(
a
int
not
null
,
b
bit
,
c
bit
(
9
),
key
(
a
,
b
,
c
));
insert
into
t1
values
(
4
,
NULL
,
1
),
(
4
,
0
,
3
),
(
2
,
1
,
4
),
(
1
,
1
,
100
),
(
4
,
0
,
23
),
(
4
,
0
,
54
),
(
56
,
0
,
22
),
(
4
,
1
,
100
),
(
23
,
0
,
1
),
(
4
,
0
,
34
);
select
a
+
0
,
b
+
0
,
c
+
0
from
t1
;
select
hex
(
min
(
b
))
from
t1
where
a
=
4
;
select
hex
(
min
(
c
))
from
t1
where
a
=
4
and
b
=
0
;
select
hex
(
max
(
b
))
from
t1
;
select
a
+
0
,
b
+
0
,
c
+
0
from
t1
where
a
=
4
and
b
=
0
limit
2
;
select
a
+
0
,
b
+
0
,
c
+
0
from
t1
order
by
b
desc
;
select
a
+
0
,
b
+
0
,
c
+
0
from
t1
order
by
c
;
drop
table
t1
;
create
table
t1
(
a
bit
(
2
),
b
bit
(
2
));
insert
into
t1
(
a
)
values
(
0x01
),
(
0x03
),
(
0x02
);
update
t1
set
b
=
concat
(
a
);
select
a
+
0
,
b
+
0
from
t1
;
drop
table
t1
;
# Some magic numbers
create
table
t1
(
a
bit
(
7
),
key
(
a
));
insert
into
t1
values
(
44
),
(
57
);
select
a
+
0
from
t1
;
drop
table
t1
;
mysys/my_handler.c
View file @
d7285006
...
...
@@ -178,6 +178,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a,
}
break
;
case
HA_KEYTYPE_BINARY
:
case
HA_KEYTYPE_BIT
:
if
(
keyseg
->
flag
&
HA_SPACE_PACK
)
{
int
a_length
,
b_length
,
pack_length
;
...
...
sql/field.cc
View file @
d7285006
...
...
@@ -6048,6 +6048,227 @@ bool Field_num::eq_def(Field *field)
}
/*
Bit field.
We store the first 0 - 6 uneven bits among the null bits
at the start of the record. The rest bytes are stored in
the record itself.
For example:
CREATE TABLE t1 (a int, b bit(17), c bit(21) not null, d bit(8));
We would store data as follows in the record:
Byte Bit
1 7 - reserve for delete
6 - null bit for 'a'
5 - null bit for 'b'
4 - first (high) bit of 'b'
3 - first (high) bit of 'c'
2 - second bit of 'c'
1 - third bit of 'c'
0 - forth bit of 'c'
2 7 - firth bit of 'c'
6 - null bit for 'd'
3 - 6 four bytes for 'a'
7 - 8 two bytes for 'b'
9 - 10 two bytes for 'c'
11 one byte for 'd'
*/
void
Field_bit
::
make_field
(
Send_field
*
field
)
{
/* table_cache_key is not set for temp tables */
field
->
db_name
=
(
orig_table
->
table_cache_key
?
orig_table
->
table_cache_key
:
""
);
field
->
org_table_name
=
orig_table
->
real_name
;
field
->
table_name
=
orig_table
->
table_name
;
field
->
col_name
=
field
->
org_col_name
=
field_name
;
field
->
charsetnr
=
charset
()
->
number
;
field
->
length
=
field_length
;
field
->
type
=
type
();
field
->
flags
=
table
->
maybe_null
?
(
flags
&
~
NOT_NULL_FLAG
)
:
flags
;
field
->
decimals
=
0
;
}
int
Field_bit
::
store
(
const
char
*
from
,
uint
length
,
CHARSET_INFO
*
cs
)
{
int
delta
;
for
(;
!*
from
&&
length
;
from
++
,
length
--
);
// skip left 0's
delta
=
field_length
-
length
;
if
(
delta
<
-
1
||
(
delta
==
-
1
&&
(
uchar
)
*
from
>
((
1
<<
bit_len
)
-
1
))
||
(
!
bit_len
&&
delta
<
0
))
{
set_rec_bits
(
0xff
,
bit_ptr
,
bit_ofs
,
bit_len
);
memset
(
ptr
,
0xff
,
field_length
);
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_WARN_DATA_OUT_OF_RANGE
,
1
);
return
1
;
}
/* delta is >= -1 here */
if
(
delta
>
0
)
{
if
(
bit_len
)
clr_rec_bits
(
bit_ptr
,
bit_ofs
,
bit_len
);
bzero
(
ptr
,
delta
);
memcpy
(
ptr
+
delta
,
from
,
length
);
}
else
if
(
delta
==
0
)
{
if
(
bit_len
)
clr_rec_bits
(
bit_ptr
,
bit_ofs
,
bit_len
);
memcpy
(
ptr
,
from
,
length
);
}
else
{
if
(
bit_len
)
{
set_rec_bits
((
uchar
)
*
from
,
bit_ptr
,
bit_ofs
,
bit_len
);
from
++
;
}
memcpy
(
ptr
,
from
,
field_length
);
}
return
0
;
}
int
Field_bit
::
store
(
double
nr
)
{
return
(
Field_bit
::
store
((
longlong
)
nr
));
}
int
Field_bit
::
store
(
longlong
nr
)
{
char
buf
[
8
];
mi_int8store
(
buf
,
nr
);
return
store
(
buf
,
8
,
NULL
);
}
double
Field_bit
::
val_real
(
void
)
{
return
(
double
)
Field_bit
::
val_int
();
}
longlong
Field_bit
::
val_int
(
void
)
{
ulonglong
bits
=
0
;
if
(
bit_len
)
bits
=
get_rec_bits
(
bit_ptr
,
bit_ofs
,
bit_len
);
bits
<<=
(
field_length
*
8
);
switch
(
field_length
)
{
case
0
:
return
bits
;
case
1
:
return
bits
|
(
ulonglong
)
(
uchar
)
ptr
[
0
];
case
2
:
return
bits
|
mi_uint2korr
(
ptr
);
case
3
:
return
bits
|
mi_uint3korr
(
ptr
);
case
4
:
return
bits
|
mi_uint4korr
(
ptr
);
case
5
:
return
bits
|
mi_uint5korr
(
ptr
);
case
6
:
return
bits
|
mi_uint6korr
(
ptr
);
case
7
:
return
bits
|
mi_uint7korr
(
ptr
);
default:
return
mi_uint8korr
(
ptr
+
field_length
-
sizeof
(
longlong
));
}
}
String
*
Field_bit
::
val_str
(
String
*
val_buffer
,
String
*
val_ptr
__attribute__
((
unused
)))
{
uint
length
=
min
(
pack_length
(),
sizeof
(
longlong
));
ulonglong
bits
=
val_int
();
val_buffer
->
alloc
(
length
);
memcpy_fixed
((
char
*
)
val_buffer
->
ptr
(),
(
char
*
)
&
bits
,
length
);
val_buffer
->
length
(
length
);
val_buffer
->
set_charset
(
&
my_charset_bin
);
return
val_buffer
;
}
int
Field_bit
::
key_cmp
(
const
byte
*
str
,
uint
length
)
{
if
(
bit_len
)
{
int
flag
;
uchar
bits
=
get_rec_bits
(
bit_ptr
,
bit_ofs
,
bit_len
);
if
((
flag
=
(
int
)
(
bits
-
*
str
)))
return
flag
;
str
++
;
length
--
;
}
return
bcmp
(
ptr
,
str
,
length
);
}
int
Field_bit
::
cmp_offset
(
uint
row_offset
)
{
if
(
bit_len
)
{
int
flag
;
uchar
bits_a
=
get_rec_bits
(
bit_ptr
,
bit_ofs
,
bit_len
);
uchar
bits_b
=
get_rec_bits
(
bit_ptr
+
row_offset
,
bit_ofs
,
bit_len
);
if
((
flag
=
(
int
)
(
bits_a
-
bits_b
)))
return
flag
;
}
return
bcmp
(
ptr
,
ptr
+
row_offset
,
field_length
);
}
void
Field_bit
::
get_key_image
(
char
*
buff
,
uint
length
,
imagetype
type
)
{
if
(
bit_len
)
{
uchar
bits
=
get_rec_bits
(
bit_ptr
,
bit_ofs
,
bit_len
);
*
buff
++=
bits
;
length
--
;
}
memcpy
(
buff
,
ptr
,
min
(
length
,
field_length
));
}
void
Field_bit
::
sql_type
(
String
&
res
)
const
{
CHARSET_INFO
*
cs
=
res
.
charset
();
ulong
length
=
cs
->
cset
->
snprintf
(
cs
,
(
char
*
)
res
.
ptr
(),
res
.
alloced_length
(),
"bit(%d)"
,
(
int
)
field_length
*
8
+
bit_len
);
res
.
length
((
uint
)
length
);
}
char
*
Field_bit
::
pack
(
char
*
to
,
const
char
*
from
,
uint
max_length
)
{
uint
length
=
min
(
field_length
+
(
bit_len
>
0
),
max_length
);
if
(
bit_len
)
{
uchar
bits
=
get_rec_bits
(
bit_ptr
,
bit_ofs
,
bit_len
);
*
to
++=
bits
;
length
--
;
}
memcpy
(
to
,
from
,
length
);
return
to
+
length
;
}
const
char
*
Field_bit
::
unpack
(
char
*
to
,
const
char
*
from
)
{
if
(
bit_len
)
{
set_rec_bits
(
*
from
,
bit_ptr
,
bit_ofs
,
bit_len
);
from
++
;
}
memcpy
(
to
,
from
,
field_length
);
return
from
+
field_length
;
}
/*****************************************************************************
Handling of field and create_field
*****************************************************************************/
...
...
@@ -6124,6 +6345,7 @@ uint32 calc_pack_length(enum_field_types type,uint32 length)
case
FIELD_TYPE_GEOMETRY
:
return
4
+
portable_sizeof_char_ptr
;
case
FIELD_TYPE_SET
:
case
FIELD_TYPE_ENUM
:
abort
();
return
0
;
// This shouldn't happen
case
FIELD_TYPE_BIT
:
return
length
/
8
;
default:
return
0
;
}
return
0
;
// Keep compiler happy
...
...
@@ -6154,11 +6376,30 @@ Field *make_field(char *ptr, uint32 field_length,
const
char
*
field_name
,
struct
st_table
*
table
)
{
uchar
*
bit_ptr
;
uchar
bit_offset
;
LINT_INIT
(
bit_ptr
);
LINT_INIT
(
bit_offset
);
if
(
field_type
==
FIELD_TYPE_BIT
)
{
bit_ptr
=
null_pos
;
bit_offset
=
null_bit
;
if
(
f_maybe_null
(
pack_flag
))
// if null field
{
bit_ptr
+=
(
null_bit
==
7
);
// shift bit_ptr and bit_offset
bit_offset
=
(
bit_offset
+
1
)
&
7
;
}
}
if
(
!
f_maybe_null
(
pack_flag
))
{
null_pos
=
0
;
null_bit
=
0
;
}
else
{
null_bit
=
((
uchar
)
1
)
<<
null_bit
;
}
switch
(
field_type
)
{
...
...
@@ -6280,6 +6521,9 @@ Field *make_field(char *ptr, uint32 field_length,
unireg_check
,
field_name
,
table
,
field_charset
);
case
FIELD_TYPE_NULL
:
return
new
Field_null
(
ptr
,
field_length
,
unireg_check
,
field_name
,
table
,
field_charset
);
case
FIELD_TYPE_BIT
:
return
new
Field_bit
(
ptr
,
field_length
,
null_pos
,
null_bit
,
bit_ptr
,
bit_offset
,
unireg_check
,
field_name
,
table
);
default:
// Impossible (Wrong version)
break
;
}
...
...
@@ -6338,6 +6582,9 @@ create_field::create_field(Field *old_field,Field *orig_field)
geom_type
=
((
Field_geom
*
)
old_field
)
->
geom_type
;
break
;
#endif
case
FIELD_TYPE_BIT
:
length
=
((
Field_bit
*
)
old_field
)
->
bit_len
+
length
*
8
;
break
;
default:
break
;
}
...
...
sql/field.h
View file @
d7285006
...
...
@@ -80,7 +80,7 @@ class Field
FIELD_CAST_TIMESTAMP
,
FIELD_CAST_YEAR
,
FIELD_CAST_DATE
,
FIELD_CAST_NEWDATE
,
FIELD_CAST_TIME
,
FIELD_CAST_DATETIME
,
FIELD_CAST_STRING
,
FIELD_CAST_VARSTRING
,
FIELD_CAST_BLOB
,
FIELD_CAST_GEOM
,
FIELD_CAST_ENUM
,
FIELD_CAST_SET
FIELD_CAST_GEOM
,
FIELD_CAST_ENUM
,
FIELD_CAST_SET
,
FIELD_CAST_BIT
};
utype
unireg_check
;
...
...
@@ -1173,6 +1173,53 @@ class Field_set :public Field_enum {
};
class
Field_bit
:
public
Field
{
public:
uchar
*
bit_ptr
;
// position in record where 'uneven' bits store
uchar
bit_ofs
;
// offset to 'uneven' high bits
uint
bit_len
;
// number of 'uneven' high bits
Field_bit
(
char
*
ptr_arg
,
uint32
len_arg
,
uchar
*
null_ptr_arg
,
uchar
null_bit_arg
,
uchar
*
bit_ptr_arg
,
uchar
bit_ofs_arg
,
enum
utype
unireg_check_arg
,
const
char
*
field_name_arg
,
struct
st_table
*
table_arg
)
:
Field
(
ptr_arg
,
len_arg
>>
3
,
null_ptr_arg
,
null_bit_arg
,
unireg_check_arg
,
field_name_arg
,
table_arg
),
bit_ptr
(
bit_ptr_arg
),
bit_ofs
(
bit_ofs_arg
),
bit_len
(
len_arg
&
7
)
{
}
enum_field_types
type
()
const
{
return
FIELD_TYPE_BIT
;
}
enum
ha_base_keytype
key_type
()
const
{
return
HA_KEYTYPE_BIT
;
}
uint32
key_length
()
const
{
return
(
uint32
)
field_length
+
(
bit_len
>
0
);
}
uint32
max_length
()
{
return
(
uint32
)
field_length
+
(
bit_len
>
0
);
}
uint
size_of
()
const
{
return
sizeof
(
*
this
);
}
Item_result
result_type
()
const
{
return
INT_RESULT
;
}
void
make_field
(
Send_field
*
);
void
reset
(
void
)
{
bzero
(
ptr
,
field_length
);
}
int
store
(
const
char
*
to
,
uint
length
,
CHARSET_INFO
*
charset
);
int
store
(
double
nr
);
int
store
(
longlong
nr
);
double
val_real
(
void
);
longlong
val_int
(
void
);
String
*
val_str
(
String
*
,
String
*
);
int
cmp
(
const
char
*
a
,
const
char
*
b
)
{
return
cmp_binary
(
a
,
b
);
}
int
key_cmp
(
const
byte
*
a
,
const
byte
*
b
)
{
return
cmp_binary
(
a
,
b
);
}
int
key_cmp
(
const
byte
*
str
,
uint
length
);
int
cmp_offset
(
uint
row_offset
);
void
get_key_image
(
char
*
buff
,
uint
length
,
imagetype
type
);
void
set_key_image
(
char
*
buff
,
uint
length
)
{
Field_bit
::
store
(
buff
,
length
,
&
my_charset_bin
);
}
void
sort_string
(
char
*
buff
,
uint
length
)
{
get_key_image
(
buff
,
length
,
itRAW
);
}
uint32
pack_length
()
const
{
return
(
uint32
)
field_length
+
(
bit_len
>
0
);
}
void
sql_type
(
String
&
str
)
const
;
field_cast_enum
field_cast_type
()
{
return
FIELD_CAST_BIT
;
}
char
*
pack
(
char
*
to
,
const
char
*
from
,
uint
max_length
=~
(
uint
)
0
);
const
char
*
unpack
(
char
*
to
,
const
char
*
from
);
};
/*
Create field class for CREATE TABLE
*/
...
...
sql/field_conv.cc
View file @
d7285006
...
...
@@ -485,6 +485,9 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*)
}
else
{
if
(
to
->
real_type
()
==
FIELD_TYPE_BIT
||
from
->
real_type
()
==
FIELD_TYPE_BIT
)
return
do_field_int
;
// Check if identical fields
if
(
from
->
result_type
()
==
STRING_RESULT
)
{
...
...
sql/ha_myisam.cc
View file @
d7285006
...
...
@@ -1428,6 +1428,13 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
keydef
[
i
].
seg
[
j
].
bit_start
=
(
uint
)
(
field
->
pack_length
()
-
table_arg
->
blob_ptr_size
);
}
else
if
(
field
->
type
()
==
FIELD_TYPE_BIT
)
{
keydef
[
i
].
seg
[
j
].
bit_length
=
((
Field_bit
*
)
field
)
->
bit_len
;
keydef
[
i
].
seg
[
j
].
bit_start
=
((
Field_bit
*
)
field
)
->
bit_ofs
;
keydef
[
i
].
seg
[
j
].
bit_pos
=
(
uint
)
(((
Field_bit
*
)
field
)
->
bit_ptr
-
(
uchar
*
)
table_arg
->
record
[
0
]);
}
}
keyseg
+=
pos
->
key_parts
;
}
...
...
sql/ha_myisam.h
View file @
d7285006
...
...
@@ -47,7 +47,7 @@ class ha_myisam: public handler
int_table_flags
(
HA_NULL_IN_KEY
|
HA_CAN_FULLTEXT
|
HA_CAN_SQL_HANDLER
|
HA_DUPP_POS
|
HA_CAN_INDEX_BLOBS
|
HA_AUTO_PART_KEY
|
HA_FILE_BASED
|
HA_CAN_GEOMETRY
|
HA_READ_RND_SAME
|
HA_CAN_INSERT_DELAYED
),
HA_CAN_INSERT_DELAYED
|
HA_CAN_BIT_FIELD
),
can_enable_indexes
(
1
)
{}
~
ha_myisam
()
{}
...
...
sql/handler.h
View file @
d7285006
...
...
@@ -75,6 +75,7 @@
/* Table data are stored in separate files (for lower_case_table_names) */
#define HA_FILE_BASED (1 << 26)
#define HA_NO_VARCHAR (1 << 27)
#define HA_CAN_BIT_FIELD (1 << 28)
/* supports bit fields */
/* bits in index_flags(index_number) for what you can do with index */
...
...
sql/item.cc
View file @
d7285006
...
...
@@ -2573,11 +2573,11 @@ void Item_real::print(String *str)
}
/*
***************************************************************************
** varbinary
item
** In string context this is a binary string
**
In number context this is a longlong value.
*
***************************************************************************
/
/*
hex
item
In string context this is a binary string.
In number context this is a longlong value.
*/
inline
uint
char_val
(
char
X
)
{
...
...
@@ -2587,7 +2587,7 @@ inline uint char_val(char X)
}
Item_
varbinary
::
Item_varbinary
(
const
char
*
str
,
uint
str_length
)
Item_
hex_string
::
Item_hex_string
(
const
char
*
str
,
uint
str_length
)
{
name
=
(
char
*
)
str
-
2
;
// Lex makes this start with 0x
max_length
=
(
str_length
+
1
)
/
2
;
...
...
@@ -2608,7 +2608,7 @@ Item_varbinary::Item_varbinary(const char *str, uint str_length)
fixed
=
1
;
}
longlong
Item_
varbinary
::
val_int
()
longlong
Item_
hex_string
::
val_int
()
{
// following assert is redundant, because fixed=1 assigned in constructor
DBUG_ASSERT
(
fixed
==
1
);
...
...
@@ -2622,7 +2622,7 @@ longlong Item_varbinary::val_int()
}
int
Item_
varbinary
::
save_in_field
(
Field
*
field
,
bool
no_conversions
)
int
Item_
hex_string
::
save_in_field
(
Field
*
field
,
bool
no_conversions
)
{
int
error
;
field
->
set_notnull
();
...
...
@@ -2639,6 +2639,44 @@ int Item_varbinary::save_in_field(Field *field, bool no_conversions)
}
/*
bin item.
In string context this is a binary string.
In number context this is a longlong value.
*/
Item_bin_string
::
Item_bin_string
(
const
char
*
str
,
uint
str_length
)
{
const
char
*
end
=
str
+
str_length
-
1
;
uchar
bits
=
0
;
uint
power
=
1
;
name
=
(
char
*
)
str
-
2
;
max_length
=
(
str_length
+
7
)
>>
3
;
char
*
ptr
=
(
char
*
)
sql_alloc
(
max_length
+
1
);
if
(
!
ptr
)
return
;
str_value
.
set
(
ptr
,
max_length
,
&
my_charset_bin
);
ptr
+=
max_length
-
1
;
ptr
[
1
]
=
0
;
// Set end null for string
for
(;
end
>=
str
;
end
--
)
{
if
(
power
==
256
)
{
power
=
1
;
*
ptr
--=
bits
;
bits
=
0
;
}
if
(
*
end
==
'1'
)
bits
|=
power
;
power
<<=
1
;
}
*
ptr
=
(
char
)
bits
;
collation
.
set
(
&
my_charset_bin
,
DERIVATION_COERCIBLE
);
fixed
=
1
;
}
/*
Pack data in buffer for sending
*/
...
...
@@ -2672,6 +2710,7 @@ bool Item::send(Protocol *protocol, String *buffer)
case
MYSQL_TYPE_STRING
:
case
MYSQL_TYPE_VAR_STRING
:
case
MYSQL_TYPE_VARCHAR
:
case
MYSQL_TYPE_BIT
:
{
String
*
res
;
if
((
res
=
val_str
(
buffer
)))
...
...
sql/item.h
View file @
d7285006
...
...
@@ -959,13 +959,14 @@ class Item_return_int :public Item_int
};
class
Item_
varbinary
:
public
Item
class
Item_
hex_string
:
public
Item
{
public:
Item_varbinary
(
const
char
*
str
,
uint
str_length
);
Item_hex_string
()
:
Item
()
{}
Item_hex_string
(
const
char
*
str
,
uint
str_length
);
enum
Type
type
()
const
{
return
VARBIN_ITEM
;
}
double
val_real
()
{
DBUG_ASSERT
(
fixed
==
1
);
return
(
double
)
Item_
varbinary
::
val_int
();
}
{
DBUG_ASSERT
(
fixed
==
1
);
return
(
double
)
Item_
hex_string
::
val_int
();
}
longlong
val_int
();
bool
basic_const_item
()
const
{
return
1
;
}
String
*
val_str
(
String
*
)
{
DBUG_ASSERT
(
fixed
==
1
);
return
&
str_value
;
}
...
...
@@ -977,6 +978,12 @@ class Item_varbinary :public Item
};
class
Item_bin_string
:
public
Item_hex_string
{
public:
Item_bin_string
(
const
char
*
str
,
uint
str_length
);
};
class
Item_result_field
:
public
Item
/* Item with result field */
{
public:
...
...
sql/key.cc
View file @
d7285006
...
...
@@ -102,6 +102,19 @@ void key_copy(byte *to_key, byte *from_record, KEY *key_info, uint key_length)
key_part
->
null_bit
);
key_length
--
;
}
if
(
key_part
->
type
==
HA_KEYTYPE_BIT
)
{
Field_bit
*
field
=
(
Field_bit
*
)
(
key_part
->
field
);
if
(
field
->
bit_len
)
{
uchar
bits
=
get_rec_bits
((
uchar
*
)
from_record
+
key_part
->
null_offset
+
(
key_part
->
null_bit
==
128
),
field
->
bit_ofs
,
field
->
bit_len
);
*
to_key
++=
bits
;
key_length
--
;
}
}
if
(
key_part
->
key_part_flag
&
HA_BLOB_PART
)
{
char
*
pos
;
...
...
@@ -170,6 +183,23 @@ void key_restore(byte *to_record, byte *from_key, KEY *key_info,
to_record
[
key_part
->
null_offset
]
&=
~
key_part
->
null_bit
;
key_length
--
;
}
if
(
key_part
->
type
==
HA_KEYTYPE_BIT
)
{
Field_bit
*
field
=
(
Field_bit
*
)
(
key_part
->
field
);
if
(
field
->
bit_len
)
{
uchar
bits
=
*
(
from_key
+
key_part
->
length
-
field
->
field_length
-
1
);
set_rec_bits
(
bits
,
to_record
+
key_part
->
null_offset
+
(
key_part
->
null_bit
==
128
),
field
->
bit_ofs
,
field
->
bit_len
);
}
else
{
clr_rec_bits
(
to_record
+
key_part
->
null_offset
+
(
key_part
->
null_bit
==
128
),
field
->
bit_ofs
,
field
->
bit_len
);
}
}
if
(
key_part
->
key_part_flag
&
HA_BLOB_PART
)
{
uint
blob_length
=
uint2korr
(
from_key
);
...
...
sql/protocol.cc
View file @
d7285006
...
...
@@ -726,6 +726,7 @@ bool Protocol_simple::store(const char *from, uint length,
#ifndef DEBUG_OFF
DBUG_ASSERT
(
field_types
==
0
||
field_types
[
field_pos
]
==
MYSQL_TYPE_DECIMAL
||
field_types
[
field_pos
]
==
MYSQL_TYPE_BIT
||
(
field_types
[
field_pos
]
>=
MYSQL_TYPE_ENUM
&&
field_types
[
field_pos
]
<=
MYSQL_TYPE_GEOMETRY
));
field_pos
++
;
...
...
@@ -741,6 +742,7 @@ bool Protocol_simple::store(const char *from, uint length,
#ifndef DEBUG_OFF
DBUG_ASSERT
(
field_types
==
0
||
field_types
[
field_pos
]
==
MYSQL_TYPE_DECIMAL
||
field_types
[
field_pos
]
==
MYSQL_TYPE_BIT
||
(
field_types
[
field_pos
]
>=
MYSQL_TYPE_ENUM
&&
field_types
[
field_pos
]
<=
MYSQL_TYPE_GEOMETRY
));
field_pos
++
;
...
...
sql/sql_lex.cc
View file @
d7285006
...
...
@@ -567,8 +567,12 @@ int yylex(void *arg, void *yythd)
state
=
MY_LEX_HEX_NUMBER
;
break
;
}
/* Fall through */
case
MY_LEX_IDENT_OR_BIN
:
// TODO: Add binary string handling
case
MY_LEX_IDENT_OR_BIN
:
if
(
yyPeek
()
==
'\''
)
{
// Found b'bin-number'
state
=
MY_LEX_BIN_NUMBER
;
break
;
}
case
MY_LEX_IDENT
:
uchar
*
start
;
#if defined(USE_MB) && defined(USE_MB_IDENT)
...
...
@@ -689,6 +693,20 @@ int yylex(void *arg, void *yythd)
}
yyUnget
();
}
else
if
(
c
==
'b'
&&
(
lex
->
ptr
-
lex
->
tok_start
)
==
2
&&
lex
->
tok_start
[
0
]
==
'0'
)
{
// b'bin-number'
while
(
my_isxdigit
(
cs
,(
c
=
yyGet
())))
;
if
((
lex
->
ptr
-
lex
->
tok_start
)
>=
4
&&
!
ident_map
[
c
])
{
yylval
->
lex_str
=
get_token
(
lex
,
yyLength
());
yylval
->
lex_str
.
str
+=
2
;
// Skip 0x
yylval
->
lex_str
.
length
-=
2
;
lex
->
yytoklen
-=
2
;
return
(
BIN_NUM
);
}
yyUnget
();
}
// fall through
case
MY_LEX_IDENT_START
:
// We come here after '.'
result_state
=
IDENT
;
...
...
@@ -801,6 +819,19 @@ int yylex(void *arg, void *yythd)
lex
->
yytoklen
-=
3
;
return
(
HEX_NUM
);
case
MY_LEX_BIN_NUMBER
:
// Found b'bin-string'
yyGet
();
// Skip '
while
((
c
=
yyGet
())
==
'0'
||
c
==
'1'
);
length
=
(
lex
->
ptr
-
lex
->
tok_start
);
// Length of bin-num + 3
if
(
c
!=
'\''
)
return
(
ABORT_SYM
);
// Illegal hex constant
yyGet
();
// get_token makes an unget
yylval
->
lex_str
=
get_token
(
lex
,
length
);
yylval
->
lex_str
.
str
+=
2
;
// Skip b'
yylval
->
lex_str
.
length
-=
3
;
// Don't count b' and last '
lex
->
yytoklen
-=
3
;
return
(
BIN_NUM
);
case
MY_LEX_CMP_OP
:
// Incomplete comparison operator
if
(
state_map
[
yyPeek
()]
==
MY_LEX_CMP_OP
||
state_map
[
yyPeek
()]
==
MY_LEX_LONG_CMP_OP
)
...
...
sql/sql_parse.cc
View file @
d7285006
...
...
@@ -5063,6 +5063,19 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
case
MYSQL_TYPE_VAR_STRING
:
DBUG_ASSERT
(
0
);
// Impossible
break
;
case
MYSQL_TYPE_BIT
:
{
if
(
!
length
)
new_field
->
length
=
1
;
if
(
new_field
->
length
>
MAX_BIT_FIELD_LENGTH
)
{
my_error
(
ER_TOO_BIG_FIELDLENGTH
,
MYF
(
0
),
field_name
,
MAX_BIT_FIELD_LENGTH
);
DBUG_RETURN
(
1
);
}
new_field
->
pack_length
=
(
new_field
->
length
+
7
)
/
8
;
break
;
}
}
if
(
!
(
new_field
->
flags
&
BLOB_FLAG
)
&&
...
...
sql/sql_select.cc
View file @
d7285006
...
...
@@ -7777,6 +7777,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
KEY_PART_INFO
*
key_part_info
;
Item
**
copy_func
;
MI_COLUMNDEF
*
recinfo
;
uint
total_uneven_bit_length
=
0
;
DBUG_ENTER
(
"create_tmp_table"
);
DBUG_PRINT
(
"enter"
,(
"distinct: %d save_sum_fields: %d rows_limit: %lu group: %d"
,
(
int
)
distinct
,
(
int
)
save_sum_fields
,
...
...
@@ -7966,6 +7967,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
reclength
+=
new_field
->
pack_length
();
if
(
!
(
new_field
->
flags
&
NOT_NULL_FLAG
))
null_count
++
;
if
(
new_field
->
type
()
==
FIELD_TYPE_BIT
)
total_uneven_bit_length
+=
new_field
->
field_length
&
7
;
if
(
new_field
->
flags
&
BLOB_FLAG
)
{
*
blob_field
++=
new_field
;
...
...
@@ -8014,7 +8017,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
null_count
++
;
}
hidden_null_pack_length
=
(
hidden_null_count
+
7
)
/
8
;
null_pack_length
=
hidden_null_count
+
(
null_count
+
7
)
/
8
;
null_pack_length
=
hidden_null_count
+
(
null_count
+
total_uneven_bit_length
+
7
)
/
8
;
reclength
+=
null_pack_length
;
if
(
!
reclength
)
reclength
=
1
;
// Dummy select
...
...
sql/sql_table.cc
View file @
d7285006
...
...
@@ -458,6 +458,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
int
field_no
,
dup_no
;
int
select_field_pos
,
auto_increment
=
0
;
List_iterator
<
create_field
>
it
(
fields
),
it2
(
fields
);
uint
total_uneven_bit_length
=
0
;
DBUG_ENTER
(
"mysql_prepare_table"
);
select_field_pos
=
fields
.
elements
-
select_field_count
;
...
...
@@ -614,6 +615,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
if
(
!
(
sql_field
->
flags
&
NOT_NULL_FLAG
))
null_fields
++
;
if
(
sql_field
->
sql_type
==
FIELD_TYPE_BIT
)
total_uneven_bit_length
+=
sql_field
->
length
&
7
;
if
(
check_column_name
(
sql_field
->
field_name
))
{
my_error
(
ER_WRONG_COLUMN_NAME
,
MYF
(
0
),
sql_field
->
field_name
);
...
...
@@ -666,7 +670,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
/* If fixed row records, we need one bit to check for deleted rows */
if
(
!
(
db_options
&
HA_OPTION_PACK_RECORD
))
null_fields
++
;
pos
=
(
null_fields
+
7
)
/
8
;
pos
=
(
null_fields
+
total_uneven_bit_length
+
7
)
/
8
;
it
.
rewind
();
while
((
sql_field
=
it
++
))
...
...
@@ -762,6 +766,14 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
case
FIELD_TYPE_NULL
:
sql_field
->
pack_flag
=
f_settype
((
uint
)
sql_field
->
sql_type
);
break
;
case
FIELD_TYPE_BIT
:
if
(
!
(
file
->
table_flags
()
&
HA_CAN_BIT_FIELD
))
{
my_error
(
ER_CHECK_NOT_IMPLEMENTED
,
MYF
(
0
),
"BIT FIELD"
);
DBUG_RETURN
(
-
1
);
}
sql_field
->
pack_flag
=
FIELDFLAG_NUMBER
;
break
;
case
FIELD_TYPE_TIMESTAMP
:
/* We should replace old TIMESTAMP fields with their newer analogs */
if
(
sql_field
->
unireg_check
==
Field
::
TIMESTAMP_OLD_FIELD
)
...
...
sql/sql_yacc.yy
View file @
d7285006
...
...
@@ -208,6 +208,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token BACKUP_SYM
%token BERKELEY_DB_SYM
%token BINARY
%token BIN_NUM
%token BIT_SYM
%token BOOL_SYM
%token BOOLEAN_SYM
...
...
@@ -664,7 +665,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text
UNDERSCORE_CHARSET IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
NCHAR_STRING opt_component key_cache_name
sp_opt_label
sp_opt_label
BIN_NUM
%type <lex_str_ptr>
opt_table_alias
...
...
@@ -2750,8 +2751,10 @@ type:
int_type opt_len field_options { $$=$1; }
| real_type opt_precision field_options { $$=$1; }
| FLOAT_SYM float_options field_options { $$=FIELD_TYPE_FLOAT; }
| BIT_SYM opt_len { Lex->length=(char*) "1";
$$=FIELD_TYPE_TINY; }
| BIT_SYM { Lex->length= (char*) "1";
$$=FIELD_TYPE_BIT; }
| BIT_SYM '(' NUM ')' { Lex->length= $3.str;
$$=FIELD_TYPE_BIT; }
| BOOL_SYM { Lex->length=(char*) "1";
$$=FIELD_TYPE_TINY; }
| BOOLEAN_SYM { Lex->length=(char*) "1";
...
...
@@ -6458,15 +6461,25 @@ text_string:
{ $$= new (YYTHD->mem_root) String($1.str,$1.length,YYTHD->variables.collation_connection); }
| HEX_NUM
{
Item *tmp
= new Item_varbinary($1.str,
$1.length);
Item *tmp
= new Item_hex_string($1.str,
$1.length);
/*
it is OK only emulate fix_fieds, because we need only
it is OK only emulate fix_fie
l
ds, because we need only
value of constant
*/
$$= tmp ?
tmp->quick_fix_field(), tmp->val_str((String*) 0) :
(String*) 0;
}
| BIN_NUM
{
Item *tmp= new Item_bin_string($1.str, $1.length);
/*
it is OK only emulate fix_fields, because we need only
value of constant
*/
$$= tmp ? tmp->quick_fix_field(), tmp->val_str((String*) 0) :
(String*) 0;
}
;
param_marker:
...
...
@@ -6508,10 +6521,11 @@ literal:
| NUM_literal { $$ = $1; }
| NULL_SYM { $$ = new Item_null();
Lex->next_state=MY_LEX_OPERATOR_OR_IDENT;}
| HEX_NUM { $$ = new Item_varbinary($1.str,$1.length);}
| HEX_NUM { $$ = new Item_hex_string($1.str, $1.length);}
| BIN_NUM { $$= new Item_bin_string($1.str, $1.length); }
| UNDERSCORE_CHARSET HEX_NUM
{
Item *tmp= new Item_
varbinary($2.str,
$2.length);
Item *tmp= new Item_
hex_string($2.str,
$2.length);
/*
it is OK only emulate fix_fieds, because we need only
value of constant
...
...
@@ -6523,6 +6537,20 @@ literal:
str ? str->length() : 0,
Lex->charset);
}
| UNDERSCORE_CHARSET BIN_NUM
{
Item *tmp= new Item_bin_string($2.str, $2.length);
/*
it is OK only emulate fix_fieds, because we need only
value of constant
*/
String *str= tmp ?
tmp->quick_fix_field(), tmp->val_str((String*) 0) :
(String*) 0;
$$= new Item_string(str ? str->ptr() : "",
str ? str->length() : 0,
Lex->charset);
}
| DATE_SYM text_literal { $$ = $2; }
| TIME_SYM text_literal { $$ = $2; }
| TIMESTAMP text_literal { $$ = $2; };
...
...
sql/table.cc
View file @
d7285006
...
...
@@ -81,7 +81,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
KEY
*
keyinfo
;
KEY_PART_INFO
*
key_part
;
uchar
*
null_pos
;
uint
null_bit
,
new_frm_ver
,
field_pack_length
;
uint
null_bit
_pos
,
new_frm_ver
,
field_pack_length
;
SQL_CRYPT
*
crypted
=
0
;
MEM_ROOT
**
root_ptr
,
*
old_root
;
DBUG_ENTER
(
"openfrm"
);
...
...
@@ -409,15 +409,15 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
if
(
null_field_first
)
{
outparam
->
null_flags
=
null_pos
=
(
uchar
*
)
record
+
1
;
null_bit
=
(
db_create_options
&
HA_OPTION_PACK_RECORD
)
?
1
:
2
;
outparam
->
null_bytes
=
(
outparam
->
null_fields
+
null_bit
+
6
)
/
8
;
null_bit
_pos
=
(
db_create_options
&
HA_OPTION_PACK_RECORD
)
?
0
:
1
;
outparam
->
null_bytes
=
(
outparam
->
null_fields
+
null_bit_pos
+
7
)
/
8
;
}
else
{
outparam
->
null_bytes
=
(
outparam
->
null_fields
+
7
)
/
8
;
outparam
->
null_flags
=
null_pos
=
(
uchar
*
)
(
record
+
1
+
outparam
->
reclength
-
outparam
->
null_bytes
);
null_bit
=
1
;
null_bit
_pos
=
0
;
}
use_hash
=
outparam
->
fields
>=
MAX_FIELDS_BEFORE_HASH
;
...
...
@@ -512,7 +512,7 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
*
field_ptr
=
reg_field
=
make_field
(
record
+
recpos
,
(
uint32
)
field_length
,
null_pos
,
null_bit
,
null_pos
,
null_bit_pos
,
pack_flag
,
field_type
,
charset
,
...
...
@@ -529,14 +529,19 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
goto
err_not_open
;
/* purecov: inspected */
}
reg_field
->
comment
=
comment
;
if
(
!
(
reg_field
->
flags
&
NOT_NULL_FLAG
)
)
if
(
field_type
==
FIELD_TYPE_BIT
)
{
if
((
null_bit
<<=
1
)
==
256
)
if
((
null_bit
_pos
+=
field_length
&
7
)
>
7
)
{
null_pos
++
;
null_bit
=
1
;
null_pos
++
;
null_bit_pos
-=
8
;
}
}
if
(
!
(
reg_field
->
flags
&
NOT_NULL_FLAG
))
{
if
(
!
(
null_bit_pos
=
(
null_bit_pos
+
1
)
&
7
))
null_pos
++
;
}
if
(
f_no_default
(
pack_flag
))
reg_field
->
flags
|=
NO_DEFAULT_VALUE_FLAG
;
if
(
reg_field
->
unireg_check
==
Field
::
NEXT_NUMBER
)
...
...
sql/unireg.cc
View file @
d7285006
...
...
@@ -652,7 +652,7 @@ static bool make_empty_rec(File file,enum db_type table_type,
Field
*
regfield
=
make_field
((
char
*
)
buff
+
field
->
offset
,
field
->
length
,
field
->
flags
&
NOT_NULL_FLAG
?
0
:
null_pos
+
null_count
/
8
,
1
<<
(
null_count
&
7
)
,
null_count
&
7
,
field
->
pack_flag
,
field
->
sql_type
,
field
->
charset
,
...
...
sql/unireg.h
View file @
d7285006
...
...
@@ -66,6 +66,8 @@
/* Max column width +1 */
#define MAX_FIELD_WIDTH (MAX_FIELD_CHARLENGTH*MAX_MBWIDTH+1)
#define MAX_BIT_FIELD_LENGTH 64
/* Max length in bits for bit fields */
#define MAX_DATE_WIDTH 10
/* YYYY-MM-DD */
#define MAX_TIME_WIDTH 23
/* -DDDDDD HH:MM:SS.###### */
#define MAX_DATETIME_FULL_WIDTH 29
/* YYYY-MM-DD HH:MM:SS.###### AM */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment