Commit 4b2312d2 authored by istruewing@stella.local's avatar istruewing@stella.local

Merge stella.local:/home2/mydev/mysql-5.1-amain

into  stella.local:/home2/mydev/mysql-5.1-axmrg
parents dbcd4d9e fba9513c
...@@ -5379,4 +5379,13 @@ SHOW WARNINGS; ...@@ -5379,4 +5379,13 @@ SHOW WARNINGS;
Level Code Message Level Code Message
Error 1178 The storage engine for the table doesn't support nullable columns Error 1178 The storage engine for the table doesn't support nullable columns
Error 1005 Can't create table 'test.t1' (errno: 138) Error 1005 Can't create table 'test.t1' (errno: 138)
create table t1 (c1 tinyblob not null) engine=csv;
insert into t1 values("This");
update t1 set c1="That" where c1="This";
affected rows: 1
info: Rows matched: 1 Changed: 1 Warnings: 0
select * from t1;
c1
That
drop table t1;
End of 5.1 tests End of 5.1 tests
...@@ -21,4 +21,14 @@ INSERT INTO t1 VALUES('A', 'A'), ('B', 'B'), ('C', 'C'); ...@@ -21,4 +21,14 @@ INSERT INTO t1 VALUES('A', 'A'), ('B', 'B'), ('C', 'C');
INSERT INTO t1 VALUES('A ', 'A '); INSERT INTO t1 VALUES('A ', 'A ');
ERROR 23000: Duplicate entry '' for key 'key1' ERROR 23000: Duplicate entry '' for key 'key1'
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (
c1 CHAR(255) CHARACTER SET UCS2 COLLATE UCS2_BIN NOT NULL,
KEY(c1)
) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('marshall\'s');
INSERT INTO t1 VALUES ('marsh');
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
...@@ -2023,4 +2023,185 @@ CHECK TABLE t1; ...@@ -2023,4 +2023,185 @@ CHECK TABLE t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (
c1 CHAR(130),
c2 VARCHAR(1)
) ENGINE=MyISAM;
INSERT INTO t1 VALUES(REPEAT("a",128), 'b');
SELECT COUNT(*) FROM t1;
COUNT(*)
1
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
SELECT COUNT(*) FROM t1;
COUNT(*)
1
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
CREATE TABLE t1 (
c1 CHAR(130),
c2 VARCHAR(1)
) ENGINE=MyISAM;
INSERT INTO t1 VALUES(REPEAT("a",128), 'b');
SELECT COUNT(*) FROM t1;
COUNT(*)
1
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
REPAIR TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 repair status OK
SELECT COUNT(*) FROM t1;
COUNT(*)
1
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
CREATE TABLE t1 (
c1 CHAR(130),
c2 VARCHAR(1)
) ENGINE=MyISAM;
INSERT INTO t1 VALUES(REPEAT("a",128), 'b');
INSERT INTO t1 VALUES('b', 'b');
INSERT INTO t1 VALUES('c', 'b');
DELETE FROM t1 WHERE c1='b';
SELECT COUNT(*) FROM t1;
COUNT(*)
2
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
SELECT COUNT(*) FROM t1;
COUNT(*)
2
DROP TABLE t1;
CREATE TABLE t1 (
c1 CHAR(130),
c2 VARCHAR(1),
KEY (c1)
) ENGINE=MyISAM;
# Insert 100 rows. Query log disabled.
UPDATE t1 SET c1=REPEAT("a",128) LIMIT 90;
SELECT COUNT(*) FROM t1;
COUNT(*)
100
ALTER TABLE t1 ENGINE=MyISAM;
SELECT COUNT(*) FROM t1;
COUNT(*)
100
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
CREATE TABLE t1 (
c1 CHAR(50),
c2 VARCHAR(1)
) ENGINE=MyISAM DEFAULT CHARSET UTF8;
INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b');
SELECT COUNT(*) FROM t1;
COUNT(*)
1
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
SELECT COUNT(*) FROM t1;
COUNT(*)
1
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
CREATE TABLE t1 (
c1 CHAR(50),
c2 VARCHAR(1)
) ENGINE=MyISAM DEFAULT CHARSET UTF8;
INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b');
SELECT COUNT(*) FROM t1;
COUNT(*)
1
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
REPAIR TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 repair status OK
SELECT COUNT(*) FROM t1;
COUNT(*)
1
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
CREATE TABLE t1 (
c1 CHAR(50),
c2 VARCHAR(1)
) ENGINE=MyISAM DEFAULT CHARSET UTF8;
INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b');
INSERT INTO t1 VALUES('b', 'b');
INSERT INTO t1 VALUES('c', 'b');
DELETE FROM t1 WHERE c1='b';
SELECT COUNT(*) FROM t1;
COUNT(*)
2
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
SELECT COUNT(*) FROM t1;
COUNT(*)
2
DROP TABLE t1;
CREATE TABLE t1 (
c1 CHAR(50),
c2 VARCHAR(1),
KEY (c1)
) ENGINE=MyISAM DEFAULT CHARSET UTF8;
# Insert 100 rows. Query log disabled.
UPDATE t1 SET c1=REPEAT(_utf8 x'e0ae85',43) LIMIT 90;
SELECT COUNT(*) FROM t1;
COUNT(*)
100
ALTER TABLE t1 ENGINE=MyISAM;
SELECT COUNT(*) FROM t1;
COUNT(*)
100
CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
CHECK TABLE t1 EXTENDED;
Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
CREATE TABLE t1 (
c1 VARCHAR(10) NOT NULL,
c2 CHAR(10) DEFAULT NULL,
c3 VARCHAR(10) NOT NULL,
KEY (c1),
KEY (c2)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0;
MyISAM file: MYSQLTEST_VARDIR/master-data/test/t1
Record format: Packed
Character set: utf8_general_ci (33)
Data records: 0 Deleted blocks: 0
Recordlength: 94
table description:
Key Start Len Index Type
1 2 30 multip. varchar
2 33 30 multip. char NULL
DROP TABLE t1;
End of 5.1 tests End of 5.1 tests
SELECT @@global.example_enum_var = 'e2';
@@global.example_enum_var = 'e2'
1
...@@ -162,3 +162,11 @@ DROP DATABASE db1; ...@@ -162,3 +162,11 @@ DROP DATABASE db1;
DROP DATABASE db2; DROP DATABASE db2;
USE test; USE test;
End of 5.0 tests End of 5.0 tests
SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE='NO_DIR_IN_CREATE';
CREATE TABLE t1(a INT) DATA DIRECTORY='MYSQLTEST_VARDIR/tmp' INDEX DIRECTORY='MYSQLTEST_VARDIR/tmp';
Warnings:
Warning 0 DATA DIRECTORY option ignored
Warning 0 INDEX DIRECTORY option ignored
DROP TABLE t1;
SET @@SQL_MODE=@OLD_SQL_MODE;
End of 5.1 tests
...@@ -1773,4 +1773,15 @@ drop table t1; ...@@ -1773,4 +1773,15 @@ drop table t1;
CREATE TABLE t1(a INT) ENGINE=CSV; CREATE TABLE t1(a INT) ENGINE=CSV;
SHOW WARNINGS; SHOW WARNINGS;
#
# BUG#33067 - .
#
create table t1 (c1 tinyblob not null) engine=csv;
insert into t1 values("This");
--enable_info
update t1 set c1="That" where c1="This";
--disable_info
select * from t1;
drop table t1;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -39,4 +39,17 @@ INSERT INTO t1 VALUES('A', 'A'), ('B', 'B'), ('C', 'C'); ...@@ -39,4 +39,17 @@ INSERT INTO t1 VALUES('A', 'A'), ('B', 'B'), ('C', 'C');
INSERT INTO t1 VALUES('A ', 'A '); INSERT INTO t1 VALUES('A ', 'A ');
DROP TABLE t1; DROP TABLE t1;
#
# Bug#32705 - myisam corruption: Key in wrong position
# at page 1024 with ucs2_bin
#
CREATE TABLE t1 (
c1 CHAR(255) CHARACTER SET UCS2 COLLATE UCS2_BIN NOT NULL,
KEY(c1)
) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('marshall\'s');
INSERT INTO t1 VALUES ('marsh');
CHECK TABLE t1 EXTENDED;
DROP TABLE t1;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -1278,5 +1278,189 @@ DELETE FROM t1 WHERE c1 >= 10; ...@@ -1278,5 +1278,189 @@ DELETE FROM t1 WHERE c1 >= 10;
CHECK TABLE t1; CHECK TABLE t1;
DROP TABLE t1; DROP TABLE t1;
#
# Bug#33222 - myisam-table drops rows when column is added
# and a char-field > 128 exists
#
# Test #1 - CHECK TABLE sees wrong record, REPAR TABLE deletes it.
# Using a CHAR column that can have > 127 characters.
# Using a VARCHAR to create a table with dynamic row format.
CREATE TABLE t1 (
c1 CHAR(130),
c2 VARCHAR(1)
) ENGINE=MyISAM;
INSERT INTO t1 VALUES(REPEAT("a",128), 'b');
SELECT COUNT(*) FROM t1;
CHECK TABLE t1;
REPAIR TABLE t1;
SELECT COUNT(*) FROM t1;
CHECK TABLE t1;
DROP TABLE t1;
#
# Test #2 - same as test #1, but using EXTENDED.
# Using a CHAR column that can have > 127 characters.
# Using a VARCHAR to create a table with dynamic row format.
CREATE TABLE t1 (
c1 CHAR(130),
c2 VARCHAR(1)
) ENGINE=MyISAM;
INSERT INTO t1 VALUES(REPEAT("a",128), 'b');
SELECT COUNT(*) FROM t1;
CHECK TABLE t1 EXTENDED;
REPAIR TABLE t1 EXTENDED;
SELECT COUNT(*) FROM t1;
CHECK TABLE t1 EXTENDED;
DROP TABLE t1;
#
# Test #3 - same as test #1, but using OPTIMIZE TABLE.
# Using a CHAR column that can have > 127 characters.
# Using a VARCHAR to create a table with dynamic row format.
CREATE TABLE t1 (
c1 CHAR(130),
c2 VARCHAR(1)
) ENGINE=MyISAM;
INSERT INTO t1 VALUES(REPEAT("a",128), 'b');
# Insert more rows and delete one in the middle to force optimize.
INSERT INTO t1 VALUES('b', 'b');
INSERT INTO t1 VALUES('c', 'b');
DELETE FROM t1 WHERE c1='b';
SELECT COUNT(*) FROM t1;
OPTIMIZE TABLE t1;
SELECT COUNT(*) FROM t1;
DROP TABLE t1;
#
# Test #4 - ALTER TABLE deletes rows.
# Using a CHAR column that can have > 127 characters.
# Using a VARCHAR to create a table with dynamic row format.
# Using an index which can be disabled during bulk insert.
CREATE TABLE t1 (
c1 CHAR(130),
c2 VARCHAR(1),
KEY (c1)
) ENGINE=MyISAM;
#
# Insert 100 rows. This turns bulk insert on during the copy phase of
# ALTER TABLE. Bulk insert disables keys before the insert and re-enables
# them by repair after the insert.
--disable_query_log
let $count= 100;
--echo # Insert $count rows. Query log disabled.
while ($count)
{
INSERT INTO t1 VALUES ('a', 'b');
dec $count;
}
--enable_query_log
#
# Change most of the rows into long character values with > 127 characters.
UPDATE t1 SET c1=REPEAT("a",128) LIMIT 90;
SELECT COUNT(*) FROM t1;
ALTER TABLE t1 ENGINE=MyISAM;
#
# With bug present, this shows that all long rows are gone.
SELECT COUNT(*) FROM t1;
CHECK TABLE t1;
CHECK TABLE t1 EXTENDED;
DROP TABLE t1;
#
# Test #5 - same as test #1 but UTF-8.
# Using a CHAR column that can have > 127 characters.
# Using a VARCHAR to create a table with dynamic row format.
CREATE TABLE t1 (
c1 CHAR(50),
c2 VARCHAR(1)
) ENGINE=MyISAM DEFAULT CHARSET UTF8;
# Using Tamil Letter A, Unicode U+0B85
INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b');
SELECT COUNT(*) FROM t1;
CHECK TABLE t1;
REPAIR TABLE t1;
SELECT COUNT(*) FROM t1;
CHECK TABLE t1;
DROP TABLE t1;
#
# Test #6 - same as test #2, but UTF-8.
# Using a CHAR column that can have > 127 characters.
# Using a VARCHAR to create a table with dynamic row format.
CREATE TABLE t1 (
c1 CHAR(50),
c2 VARCHAR(1)
) ENGINE=MyISAM DEFAULT CHARSET UTF8;
# Using Tamil Letter A, Unicode U+0B85
INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b');
SELECT COUNT(*) FROM t1;
CHECK TABLE t1 EXTENDED;
REPAIR TABLE t1 EXTENDED;
SELECT COUNT(*) FROM t1;
CHECK TABLE t1 EXTENDED;
DROP TABLE t1;
#
# Test #7 - same as test #3, but UTF-8.
# Using a CHAR column that can have > 127 characters.
# Using a VARCHAR to create a table with dynamic row format.
CREATE TABLE t1 (
c1 CHAR(50),
c2 VARCHAR(1)
) ENGINE=MyISAM DEFAULT CHARSET UTF8;
# Using Tamil Letter A, Unicode U+0B85
INSERT INTO t1 VALUES(REPEAT(_utf8 x'e0ae85',43), 'b');
# Insert more rows and delete one in the middle to force optimize.
INSERT INTO t1 VALUES('b', 'b');
INSERT INTO t1 VALUES('c', 'b');
DELETE FROM t1 WHERE c1='b';
SELECT COUNT(*) FROM t1;
OPTIMIZE TABLE t1;
SELECT COUNT(*) FROM t1;
DROP TABLE t1;
#
# Test #8 - same as test #4, but UTF-8.
# Using a CHAR column that can have > 42 UTF-8 characters.
# Using a VARCHAR to create a table with dynamic row format.
# Using an index which can be disabled during bulk insert.
CREATE TABLE t1 (
c1 CHAR(50),
c2 VARCHAR(1),
KEY (c1)
) ENGINE=MyISAM DEFAULT CHARSET UTF8;
#
# Insert 100 rows. This turns bulk insert on during the copy phase of
# ALTER TABLE. Bulk insert disables keys before the insert and re-enables
# them by repair after the insert.
--disable_query_log
let $count= 100;
--echo # Insert $count rows. Query log disabled.
while ($count)
{
INSERT INTO t1 VALUES ('a', 'b');
dec $count;
}
--enable_query_log
#
# Change most of the rows into long character values with > 42 characters.
# Using Tamil Letter A, Unicode U+0B85
UPDATE t1 SET c1=REPEAT(_utf8 x'e0ae85',43) LIMIT 90;
SELECT COUNT(*) FROM t1;
ALTER TABLE t1 ENGINE=MyISAM;
#
# With bug present, this shows that all long rows are gone.
SELECT COUNT(*) FROM t1;
CHECK TABLE t1;
CHECK TABLE t1 EXTENDED;
DROP TABLE t1;
#
# Bug#29182 - MyISAMCHK reports wrong character set
#
CREATE TABLE t1 (
c1 VARCHAR(10) NOT NULL,
c2 CHAR(10) DEFAULT NULL,
c3 VARCHAR(10) NOT NULL,
KEY (c1),
KEY (c2)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 PACK_KEYS=0;
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--exec $MYISAMCHK -d $MYSQLTEST_VARDIR/master-data/test/t1
DROP TABLE t1;
--echo End of 5.1 tests --echo End of 5.1 tests
$EXAMPLE_PLUGIN_OPT
"--plugin-load=;EXAMPLE=ha_example.so;"
--loose-plugin-example-enum-var=e2
--source include/have_example_plugin.inc
SELECT @@global.example_enum_var = 'e2';
...@@ -226,3 +226,15 @@ USE test; ...@@ -226,3 +226,15 @@ USE test;
--echo End of 5.0 tests --echo End of 5.0 tests
#
# BUG#25677 - With --skip-symbolic-links option on, DATA DIRECTORY clause is
# silently ignored
#
SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE='NO_DIR_IN_CREATE';
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval CREATE TABLE t1(a INT) DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp' INDEX DIRECTORY='$MYSQLTEST_VARDIR/tmp';
DROP TABLE t1;
SET @@SQL_MODE=@OLD_SQL_MODE;
--echo End of 5.1 tests
...@@ -256,6 +256,7 @@ main(void) ...@@ -256,6 +256,7 @@ main(void)
char * str; char * str;
char * dst; char * dst;
require(src);
for (j= 0; j<src_len; j++) for (j= 0; j<src_len; j++)
{ {
char c= rand(); char c= rand();
...@@ -265,6 +266,7 @@ main(void) ...@@ -265,6 +266,7 @@ main(void)
/* Encode */ /* Encode */
needed_length= base64_needed_encoded_length(src_len); needed_length= base64_needed_encoded_length(src_len);
str= (char *) malloc(needed_length); str= (char *) malloc(needed_length);
require(str);
for (k= 0; k < needed_length; k++) for (k= 0; k < needed_length; k++)
str[k]= 0xff; /* Fill memory to check correct NUL termination */ str[k]= 0xff; /* Fill memory to check correct NUL termination */
require(base64_encode(src, src_len, str) == 0); require(base64_encode(src, src_len, str) == 0);
...@@ -272,7 +274,8 @@ main(void) ...@@ -272,7 +274,8 @@ main(void)
/* Decode */ /* Decode */
dst= (char *) malloc(base64_needed_decoded_length(strlen(str))); dst= (char *) malloc(base64_needed_decoded_length(strlen(str)));
dst_len= base64_decode(str, strlen(str), dst); require(dst);
dst_len= base64_decode(str, strlen(str), dst, NULL);
require(dst_len == src_len); require(dst_len == src_len);
if (memcmp(src, dst, src_len) != 0) if (memcmp(src, dst, src_len) != 0)
......
...@@ -2356,15 +2356,7 @@ mysql_execute_command(THD *thd) ...@@ -2356,15 +2356,7 @@ mysql_execute_command(THD *thd)
/* Might have been updated in create_table_precheck */ /* Might have been updated in create_table_precheck */
create_info.alias= create_table->alias; create_info.alias= create_table->alias;
#ifndef HAVE_READLINK #ifdef HAVE_READLINK
if (create_info.data_file_name)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
"DATA DIRECTORY option ignored");
if (create_info.index_file_name)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
"INDEX DIRECTORY option ignored");
create_info.data_file_name= create_info.index_file_name= NULL;
#else
/* Fix names if symlinked tables */ /* Fix names if symlinked tables */
if (append_file_to_dir(thd, &create_info.data_file_name, if (append_file_to_dir(thd, &create_info.data_file_name,
create_table->table_name) || create_table->table_name) ||
......
...@@ -1181,9 +1181,8 @@ int plugin_init(int *argc, char **argv, int flags) ...@@ -1181,9 +1181,8 @@ int plugin_init(int *argc, char **argv, int flags)
/* Register all dynamic plugins */ /* Register all dynamic plugins */
if (!(flags & PLUGIN_INIT_SKIP_DYNAMIC_LOADING)) if (!(flags & PLUGIN_INIT_SKIP_DYNAMIC_LOADING))
{ {
if (opt_plugin_load && if (opt_plugin_load)
plugin_load_list(&tmp_root, argc, argv, opt_plugin_load)) plugin_load_list(&tmp_root, argc, argv, opt_plugin_load);
goto err;
if (!(flags & PLUGIN_INIT_SKIP_PLUGIN_TABLE)) if (!(flags & PLUGIN_INIT_SKIP_PLUGIN_TABLE))
plugin_load(&tmp_root, argc, argv); plugin_load(&tmp_root, argc, argv);
} }
...@@ -1412,7 +1411,11 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv, ...@@ -1412,7 +1411,11 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
while (list) while (list)
{ {
if (p == buffer + sizeof(buffer) - 1) if (p == buffer + sizeof(buffer) - 1)
break; {
sql_print_error("plugin-load parameter too long");
DBUG_RETURN(TRUE);
}
switch ((*(p++)= *(list++))) { switch ((*(p++)= *(list++))) {
case '\0': case '\0':
list= NULL; /* terminate the loop */ list= NULL; /* terminate the loop */
...@@ -1421,10 +1424,17 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv, ...@@ -1421,10 +1424,17 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
case ':': /* can't use this as delimiter as it may be drive letter */ case ':': /* can't use this as delimiter as it may be drive letter */
#endif #endif
case ';': case ';':
name.str[name.length]= '\0'; str->str[str->length]= '\0';
if (str != &dl) // load all plugins in named module if (str == &name) // load all plugins in named module
{ {
if (!name.length)
{
p--; /* reset pointer */
continue;
}
dl= name; dl= name;
pthread_mutex_lock(&LOCK_plugin);
if ((plugin_dl= plugin_dl_add(&dl, REPORT_TO_LOG))) if ((plugin_dl= plugin_dl_add(&dl, REPORT_TO_LOG)))
{ {
for (plugin= plugin_dl->plugins; plugin->info; plugin++) for (plugin= plugin_dl->plugins; plugin->info; plugin++)
...@@ -1434,7 +1444,10 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv, ...@@ -1434,7 +1444,10 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE)); free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG)) if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
{
pthread_mutex_unlock(&LOCK_plugin);
goto error; goto error;
}
} }
plugin_dl_del(&dl); // reduce ref count plugin_dl_del(&dl); // reduce ref count
} }
...@@ -1442,9 +1455,14 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv, ...@@ -1442,9 +1455,14 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
else else
{ {
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE)); free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
pthread_mutex_lock(&LOCK_plugin);
if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG)) if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
{
pthread_mutex_unlock(&LOCK_plugin);
goto error; goto error;
}
} }
pthread_mutex_unlock(&LOCK_plugin);
name.length= dl.length= 0; name.length= dl.length= 0;
dl.str= NULL; name.str= p= buffer; dl.str= NULL; name.str= p= buffer;
str= &name; str= &name;
...@@ -1453,6 +1471,7 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv, ...@@ -1453,6 +1471,7 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
case '#': case '#':
if (str == &name) if (str == &name)
{ {
name.str[name.length]= '\0';
str= &dl; str= &dl;
str->str= p; str->str= p;
continue; continue;
...@@ -2999,7 +3018,8 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, ...@@ -2999,7 +3018,8 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (opt->flags & PLUGIN_VAR_NOCMDOPT) if ((opt->flags & (PLUGIN_VAR_NOCMDOPT | PLUGIN_VAR_THDLOCAL))
== PLUGIN_VAR_NOCMDOPT)
continue; continue;
if (!opt->name) if (!opt->name)
...@@ -3009,7 +3029,7 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, ...@@ -3009,7 +3029,7 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (!(v= find_bookmark(name, opt->name, opt->flags))) if (!(opt->flags & PLUGIN_VAR_THDLOCAL))
{ {
optnamelen= strlen(opt->name); optnamelen= strlen(opt->name);
optname= (char*) alloc_root(mem_root, namelen + optnamelen + 2); optname= (char*) alloc_root(mem_root, namelen + optnamelen + 2);
...@@ -3017,7 +3037,23 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, ...@@ -3017,7 +3037,23 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
optnamelen= namelen + optnamelen + 1; optnamelen= namelen + optnamelen + 1;
} }
else else
optname= (char*) memdup_root(mem_root, v->key + 1, (optnamelen= v->name_len) + 1); {
/* this should not fail because register_var should create entry */
if (!(v= find_bookmark(name, opt->name, opt->flags)))
{
sql_print_error("Thread local variable '%s' not allocated "
"in plugin '%s'.", opt->name, plugin_name);
DBUG_RETURN(-1);
}
*(int*)(opt + 1)= offset= v->offset;
if (opt->flags & PLUGIN_VAR_NOCMDOPT)
continue;
optname= (char*) memdup_root(mem_root, v->key + 1,
(optnamelen= v->name_len) + 1);
}
/* convert '_' to '-' */ /* convert '_' to '-' */
for (p= optname; *p; p++) for (p= optname; *p; p++)
...@@ -3029,20 +3065,13 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, ...@@ -3029,20 +3065,13 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
options->app_type= opt; options->app_type= opt;
options->id= (options-1)->id + 1; options->id= (options-1)->id + 1;
if (opt->flags & PLUGIN_VAR_THDLOCAL)
*(int*)(opt + 1)= offset= v->offset;
plugin_opt_set_limits(options, opt); plugin_opt_set_limits(options, opt);
if ((opt->flags & PLUGIN_VAR_TYPEMASK) != PLUGIN_VAR_ENUM && if (opt->flags & PLUGIN_VAR_THDLOCAL)
(opt->flags & PLUGIN_VAR_TYPEMASK) != PLUGIN_VAR_SET) options->value= options->u_max_value= (uchar**)
{ (global_system_variables.dynamic_variables_ptr + offset);
if (opt->flags & PLUGIN_VAR_THDLOCAL) else
options->value= options->u_max_value= (uchar**) options->value= options->u_max_value= *(uchar***) (opt + 1);
(global_system_variables.dynamic_variables_ptr + offset);
else
options->value= options->u_max_value= *(uchar***) (opt + 1);
}
options[1]= options[0]; options[1]= options[0];
options[1].name= p= (char*) alloc_root(mem_root, optnamelen + 8); options[1].name= p= (char*) alloc_root(mem_root, optnamelen + 8);
......
...@@ -3480,8 +3480,18 @@ bool mysql_create_table_no_lock(THD *thd, ...@@ -3480,8 +3480,18 @@ bool mysql_create_table_no_lock(THD *thd,
thd_proc_info(thd, "creating table"); thd_proc_info(thd, "creating table");
create_info->table_existed= 0; // Mark that table is created create_info->table_existed= 0; // Mark that table is created
if (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) #ifdef HAVE_READLINK
if (!my_use_symdir || (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
#endif
{
if (create_info->data_file_name)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
"DATA DIRECTORY option ignored");
if (create_info->index_file_name)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 0,
"INDEX DIRECTORY option ignored");
create_info->data_file_name= create_info->index_file_name= 0; create_info->data_file_name= create_info->index_file_name= 0;
}
create_info->table_options=db_options; create_info->table_options=db_options;
path[path_length - reg_ext_length]= '\0'; // Remove .frm extension path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
......
...@@ -892,26 +892,31 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, ...@@ -892,26 +892,31 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
ha_legacy_type(share->db_type()))); ha_legacy_type(share->db_type())));
} }
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
else else if (str_db_type_length == 9 &&
!strncmp((char *) next_chunk + 2, "partition", 9))
{ {
LEX_STRING pname= { C_STRING_WITH_LEN( "partition" ) }; /*
if (str_db_type_length == pname.length && Use partition handler
!strncmp((char *) next_chunk + 2, pname.str, pname.length)) tmp_plugin is locked with a local lock.
{ we unlock the old value of share->db_plugin before
/* replacing it with a globally locked version of tmp_plugin
Use partition handler */
tmp_plugin is locked with a local lock. plugin_unlock(NULL, share->db_plugin);
we unlock the old value of share->db_plugin before share->db_plugin= ha_lock_engine(NULL, partition_hton);
replacing it with a globally locked version of tmp_plugin DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)",
*/ str_db_type_length, next_chunk + 2,
plugin_unlock(NULL, share->db_plugin); ha_legacy_type(share->db_type())));
share->db_plugin= ha_lock_engine(NULL, partition_hton);
DBUG_PRINT("info", ("setting dbtype to '%.*s' (%d)",
str_db_type_length, next_chunk + 2,
ha_legacy_type(share->db_type())));
}
} }
#endif #endif
else if (!tmp_plugin)
{
/* purecov: begin inspected */
error= 8;
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
my_free(buff, MYF(0));
goto err;
/* purecov: end */
}
next_chunk+= str_db_type_length + 2; next_chunk+= str_db_type_length + 2;
} }
if (next_chunk + 5 < buff_end) if (next_chunk + 5 < buff_end)
...@@ -2200,6 +2205,8 @@ void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg) ...@@ -2200,6 +2205,8 @@ void open_table_error(TABLE_SHARE *share, int error, int db_errno, int errarg)
"of MySQL and cannot be read", "of MySQL and cannot be read",
MYF(0), buff); MYF(0), buff);
break; break;
case 8:
break;
default: /* Better wrong error than none */ default: /* Better wrong error than none */
case 4: case 4:
strxmov(buff, share->normalized_path.str, reg_ext, NullS); strxmov(buff, share->normalized_path.str, reg_ext, NullS);
......
...@@ -225,11 +225,17 @@ int get_byte(s) ...@@ -225,11 +225,17 @@ int get_byte(s)
if (s->stream.avail_in == 0) if (s->stream.avail_in == 0)
{ {
errno = 0; errno = 0;
s->stream.avail_in = my_read(s->file, (uchar *)s->inbuf, AZ_BUFSIZE_READ, MYF(0)); s->stream.avail_in= (uInt) my_read(s->file, (uchar *)s->inbuf,
AZ_BUFSIZE_READ, MYF(0));
if (s->stream.avail_in == 0) if (s->stream.avail_in == 0)
{ {
s->z_eof = 1; s->z_eof = 1;
/* if (ferror(s->file)) s->z_err = Z_ERRNO; */ return EOF;
}
else if (s->stream.avail_in == (uInt) -1)
{
s->z_eof= 1;
s->z_err= Z_ERRNO;
return EOF; return EOF;
} }
s->stream.next_in = s->inbuf; s->stream.next_in = s->inbuf;
......
...@@ -56,6 +56,7 @@ TODO: ...@@ -56,6 +56,7 @@ TODO:
#define META_BUFFER_SIZE sizeof(uchar) + sizeof(uchar) + sizeof(ulonglong) \ #define META_BUFFER_SIZE sizeof(uchar) + sizeof(uchar) + sizeof(ulonglong) \
+ sizeof(ulonglong) + sizeof(ulonglong) + sizeof(ulonglong) + sizeof(uchar) + sizeof(ulonglong) + sizeof(ulonglong) + sizeof(ulonglong) + sizeof(uchar)
#define TINA_CHECK_HEADER 254 // The number we use to determine corruption #define TINA_CHECK_HEADER 254 // The number we use to determine corruption
#define BLOB_MEMROOT_ALLOC_SIZE 8192
/* The file extension */ /* The file extension */
#define CSV_EXT ".CSV" // The data file #define CSV_EXT ".CSV" // The data file
...@@ -597,6 +598,8 @@ int ha_tina::find_current_row(uchar *buf) ...@@ -597,6 +598,8 @@ int ha_tina::find_current_row(uchar *buf)
bool read_all; bool read_all;
DBUG_ENTER("ha_tina::find_current_row"); DBUG_ENTER("ha_tina::find_current_row");
free_root(&blobroot, MYF(MY_MARK_BLOCKS_FREE));
/* /*
We do not read further then local_saved_data_file_length in order We do not read further then local_saved_data_file_length in order
not to conflict with undergoing concurrent insert. not to conflict with undergoing concurrent insert.
...@@ -684,6 +687,22 @@ int ha_tina::find_current_row(uchar *buf) ...@@ -684,6 +687,22 @@ int ha_tina::find_current_row(uchar *buf)
if ((*field)->store(buffer.ptr(), buffer.length(), buffer.charset(), if ((*field)->store(buffer.ptr(), buffer.length(), buffer.charset(),
CHECK_FIELD_WARN)) CHECK_FIELD_WARN))
goto err; goto err;
if ((*field)->flags & BLOB_FLAG)
{
Field_blob *blob= *(Field_blob**) field;
uchar *src, *tgt;
uint length, packlength;
packlength= blob->pack_length_no_ptr();
length= blob->get_length(blob->ptr);
memcpy_fixed(&src, blob->ptr + packlength, sizeof(char*));
if (src)
{
tgt= (uchar*) alloc_root(&blobroot, length);
bmove(tgt, src, length);
memcpy_fixed(blob->ptr + packlength, &tgt, sizeof(char*));
}
}
} }
} }
next_position= end_offset + eoln_len; next_position= end_offset + eoln_len;
...@@ -914,9 +933,10 @@ int ha_tina::open_update_temp_file_if_needed() ...@@ -914,9 +933,10 @@ int ha_tina::open_update_temp_file_if_needed()
int ha_tina::update_row(const uchar * old_data, uchar * new_data) int ha_tina::update_row(const uchar * old_data, uchar * new_data)
{ {
int size; int size;
int rc= -1;
DBUG_ENTER("ha_tina::update_row"); DBUG_ENTER("ha_tina::update_row");
ha_statistic_increment(&SSV::ha_read_rnd_next_count); ha_statistic_increment(&SSV::ha_update_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE) if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time(); table->timestamp_field->set_time();
...@@ -931,20 +951,23 @@ int ha_tina::update_row(const uchar * old_data, uchar * new_data) ...@@ -931,20 +951,23 @@ int ha_tina::update_row(const uchar * old_data, uchar * new_data)
The temp_file_length is used to calculate new data file length. The temp_file_length is used to calculate new data file length.
*/ */
if (chain_append()) if (chain_append())
DBUG_RETURN(-1); goto err;
if (open_update_temp_file_if_needed()) if (open_update_temp_file_if_needed())
DBUG_RETURN(-1); goto err;
if (my_write(update_temp_file, (uchar*)buffer.ptr(), size, if (my_write(update_temp_file, (uchar*)buffer.ptr(), size,
MYF(MY_WME | MY_NABP))) MYF(MY_WME | MY_NABP)))
DBUG_RETURN(-1); goto err;
temp_file_length+= size; temp_file_length+= size;
rc= 0;
/* UPDATE should never happen on the log tables */ /* UPDATE should never happen on the log tables */
DBUG_ASSERT(!share->is_log_table); DBUG_ASSERT(!share->is_log_table);
DBUG_RETURN(0); err:
DBUG_PRINT("info",("rc = %d", rc));
DBUG_RETURN(rc);
} }
...@@ -1050,6 +1073,8 @@ int ha_tina::rnd_init(bool scan) ...@@ -1050,6 +1073,8 @@ int ha_tina::rnd_init(bool scan)
records_is_known= 0; records_is_known= 0;
chain_ptr= chain; chain_ptr= chain;
init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -1115,7 +1140,7 @@ void ha_tina::position(const uchar *record) ...@@ -1115,7 +1140,7 @@ void ha_tina::position(const uchar *record)
int ha_tina::rnd_pos(uchar * buf, uchar *pos) int ha_tina::rnd_pos(uchar * buf, uchar *pos)
{ {
DBUG_ENTER("ha_tina::rnd_pos"); DBUG_ENTER("ha_tina::rnd_pos");
ha_statistic_increment(&SSV::ha_read_rnd_next_count); ha_statistic_increment(&SSV::ha_read_rnd_count);
current_position= (off_t)my_get_ptr(pos,ref_length); current_position= (off_t)my_get_ptr(pos,ref_length);
DBUG_RETURN(find_current_row(buf)); DBUG_RETURN(find_current_row(buf));
} }
...@@ -1179,6 +1204,7 @@ int ha_tina::rnd_end() ...@@ -1179,6 +1204,7 @@ int ha_tina::rnd_end()
off_t file_buffer_start= 0; off_t file_buffer_start= 0;
DBUG_ENTER("ha_tina::rnd_end"); DBUG_ENTER("ha_tina::rnd_end");
free_root(&blobroot, MYF(0));
records_is_known= 1; records_is_known= 1;
if ((chain_ptr - chain) > 0) if ((chain_ptr - chain) > 0)
...@@ -1350,6 +1376,8 @@ int ha_tina::repair(THD* thd, HA_CHECK_OPT* check_opt) ...@@ -1350,6 +1376,8 @@ int ha_tina::repair(THD* thd, HA_CHECK_OPT* check_opt)
/* set current position to the beginning of the file */ /* set current position to the beginning of the file */
current_position= next_position= 0; current_position= next_position= 0;
init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0);
/* Read the file row-by-row. If everything is ok, repair is not needed. */ /* Read the file row-by-row. If everything is ok, repair is not needed. */
while (!(rc= find_current_row(buf))) while (!(rc= find_current_row(buf)))
{ {
...@@ -1358,6 +1386,8 @@ int ha_tina::repair(THD* thd, HA_CHECK_OPT* check_opt) ...@@ -1358,6 +1386,8 @@ int ha_tina::repair(THD* thd, HA_CHECK_OPT* check_opt)
current_position= next_position; current_position= next_position;
} }
free_root(&blobroot, MYF(0));
my_free((char*)buf, MYF(0)); my_free((char*)buf, MYF(0));
if (rc == HA_ERR_END_OF_FILE) if (rc == HA_ERR_END_OF_FILE)
...@@ -1535,6 +1565,9 @@ int ha_tina::check(THD* thd, HA_CHECK_OPT* check_opt) ...@@ -1535,6 +1565,9 @@ int ha_tina::check(THD* thd, HA_CHECK_OPT* check_opt)
local_saved_data_file_length= share->saved_data_file_length; local_saved_data_file_length= share->saved_data_file_length;
/* set current position to the beginning of the file */ /* set current position to the beginning of the file */
current_position= next_position= 0; current_position= next_position= 0;
init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0);
/* Read the file row-by-row. If everything is ok, repair is not needed. */ /* Read the file row-by-row. If everything is ok, repair is not needed. */
while (!(rc= find_current_row(buf))) while (!(rc= find_current_row(buf)))
{ {
...@@ -1542,6 +1575,8 @@ int ha_tina::check(THD* thd, HA_CHECK_OPT* check_opt) ...@@ -1542,6 +1575,8 @@ int ha_tina::check(THD* thd, HA_CHECK_OPT* check_opt)
count--; count--;
current_position= next_position; current_position= next_position;
} }
free_root(&blobroot, MYF(0));
my_free((char*)buf, MYF(0)); my_free((char*)buf, MYF(0));
thd_proc_info(thd, old_proc_info); thd_proc_info(thd, old_proc_info);
......
...@@ -82,6 +82,7 @@ class ha_tina: public handler ...@@ -82,6 +82,7 @@ class ha_tina: public handler
uint32 chain_size; uint32 chain_size;
uint local_data_file_version; /* Saved version of the data file used */ uint local_data_file_version; /* Saved version of the data file used */
bool records_is_known; bool records_is_known;
MEM_ROOT blobroot;
private: private:
bool get_write_pos(off_t *end_pos, tina_set *closest_hole); bool get_write_pos(off_t *end_pos, tina_set *closest_hole);
......
...@@ -1859,6 +1859,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, ...@@ -1859,6 +1859,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg,
share->avg_row_length); share->avg_row_length);
create_info.data_file_name= ha_create_info->data_file_name; create_info.data_file_name= ha_create_info->data_file_name;
create_info.index_file_name= ha_create_info->index_file_name; create_info.index_file_name= ha_create_info->index_file_name;
create_info.language= share->table_charset->number;
if (ha_create_info->options & HA_LEX_CREATE_TMP_TABLE) if (ha_create_info->options & HA_LEX_CREATE_TMP_TABLE)
create_flags|= HA_CREATE_TMP_TABLE; create_flags|= HA_CREATE_TMP_TABLE;
......
...@@ -1006,12 +1006,12 @@ uint _mi_rec_pack(MI_INFO *info, register uchar *to, ...@@ -1006,12 +1006,12 @@ uint _mi_rec_pack(MI_INFO *info, register uchar *to,
{ {
if (rec->length > 255 && new_length > 127) if (rec->length > 255 && new_length > 127)
{ {
to[0]=(char) ((new_length & 127)+128); to[0]= (uchar) ((new_length & 127) + 128);
to[1]=(char) (new_length >> 7); to[1]= (uchar) (new_length >> 7);
to+=2; to+=2;
} }
else else
*to++= (char) new_length; *to++= (uchar) new_length;
memcpy((uchar*) to,pos,(size_t) new_length); to+=new_length; memcpy((uchar*) to,pos,(size_t) new_length); to+=new_length;
flag|=bit; flag|=bit;
} }
...@@ -1045,7 +1045,7 @@ uint _mi_rec_pack(MI_INFO *info, register uchar *to, ...@@ -1045,7 +1045,7 @@ uint _mi_rec_pack(MI_INFO *info, register uchar *to,
} }
if ((bit= bit << 1) >= 256) if ((bit= bit << 1) >= 256)
{ {
*packpos++ = (char) (uchar) flag; *packpos++= (uchar) flag;
bit=1; flag=0; bit=1; flag=0;
} }
} }
...@@ -1055,9 +1055,9 @@ uint _mi_rec_pack(MI_INFO *info, register uchar *to, ...@@ -1055,9 +1055,9 @@ uint _mi_rec_pack(MI_INFO *info, register uchar *to,
} }
} }
if (bit != 1) if (bit != 1)
*packpos= (char) (uchar) flag; *packpos= (uchar) flag;
if (info->s->calc_checksum) if (info->s->calc_checksum)
*to++=(char) info->checksum; *to++= (uchar) info->checksum;
DBUG_PRINT("exit",("packed length: %d",(int) (to-startpos))); DBUG_PRINT("exit",("packed length: %d",(int) (to-startpos)));
DBUG_RETURN((uint) (to-startpos)); DBUG_RETURN((uint) (to-startpos));
} /* _mi_rec_pack */ } /* _mi_rec_pack */
...@@ -1128,12 +1128,14 @@ my_bool _mi_rec_check(MI_INFO *info,const uchar *record, uchar *rec_buff, ...@@ -1128,12 +1128,14 @@ my_bool _mi_rec_check(MI_INFO *info,const uchar *record, uchar *rec_buff,
goto err; goto err;
if (rec->length > 255 && new_length > 127) if (rec->length > 255 && new_length > 127)
{ {
if (to[0] != (char) ((new_length & 127)+128) || /* purecov: begin inspected */
to[1] != (char) (new_length >> 7)) if (to[0] != (uchar) ((new_length & 127) + 128) ||
goto err; to[1] != (uchar) (new_length >> 7))
to+=2; goto err;
} to+=2;
else if (*to++ != (char) new_length) /* purecov: end */
}
else if (*to++ != (uchar) new_length)
goto err; goto err;
to+=new_length; to+=new_length;
} }
......
...@@ -815,8 +815,17 @@ static void setup_key_functions(register MI_KEYDEF *keyinfo) ...@@ -815,8 +815,17 @@ static void setup_key_functions(register MI_KEYDEF *keyinfo)
keyinfo->get_key= _mi_get_pack_key; keyinfo->get_key= _mi_get_pack_key;
if (keyinfo->seg[0].flag & HA_PACK_KEY) if (keyinfo->seg[0].flag & HA_PACK_KEY)
{ /* Prefix compression */ { /* Prefix compression */
/*
_mi_prefix_search() compares end-space against ASCII blank (' ').
It cannot be used for character sets, that do not encode the
blank character like ASCII does. UCS2 is an example. All
character sets with a fixed width > 1 or a mimimum width > 1
cannot represent blank like ASCII does. In these cases we have
to use _mi_seq_search() for the search.
*/
if (!keyinfo->seg->charset || use_strnxfrm(keyinfo->seg->charset) || if (!keyinfo->seg->charset || use_strnxfrm(keyinfo->seg->charset) ||
(keyinfo->seg->flag & HA_NULL_PART)) (keyinfo->seg->flag & HA_NULL_PART) ||
(keyinfo->seg->charset->mbminlen > 1))
keyinfo->bin_search=_mi_seq_search; keyinfo->bin_search=_mi_seq_search;
else else
keyinfo->bin_search=_mi_prefix_search; keyinfo->bin_search=_mi_prefix_search;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment