Commit 052264b3 authored by stewart@willster.(none)'s avatar stewart@willster.(none)

Merge bk-internal.mysql.com:/home/bk/mysql-5.0

into  willster.(none):/home/stewart/Documents/MySQL/5.0/ndb
parents 03e297aa c43a3328
...@@ -577,13 +577,13 @@ static struct my_option my_long_options[] = ...@@ -577,13 +577,13 @@ static struct my_option my_long_options[] =
{"force", 'f', "Continue even if we get an sql error.", {"force", 'f', "Continue even if we get an sql error.",
(gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0, (gptr*) &ignore_errors, (gptr*) &ignore_errors, 0, GET_BOOL, NO_ARG, 0, 0,
0, 0, 0, 0}, 0, 0, 0, 0},
{"no-named-commands", 'g',
"Named commands are disabled. Use \\* form only, or use named commands only in the beginning of a line ending with a semicolon (;) Since version 10.9 the client now starts with this option ENABLED by default! Disable with '-G'. Long format commands still work from the first line. WARNING: option deprecated; use --disable-named-commands instead.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"named-commands", 'G', {"named-commands", 'G',
"Enable named commands. Named commands mean this program's internal commands; see mysql> help . When enabled, the named commands can be used from any line of the query, otherwise only from the first line, before an enter. Disable with --disable-named-commands. This option is disabled by default.", "Enable named commands. Named commands mean this program's internal commands; see mysql> help . When enabled, the named commands can be used from any line of the query, otherwise only from the first line, before an enter. Disable with --disable-named-commands. This option is disabled by default.",
(gptr*) &named_cmds, (gptr*) &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, (gptr*) &named_cmds, (gptr*) &named_cmds, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0}, 0, 0},
{"no-named-commands", 'g',
"Named commands are disabled. Use \\* form only, or use named commands only in the beginning of a line ending with a semicolon (;) Since version 10.9 the client now starts with this option ENABLED by default! Disable with '-G'. Long format commands still work from the first line. WARNING: option deprecated; use --disable-named-commands instead.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"ignore-spaces", 'i', "Ignore space after function names.", 0, 0, 0, {"ignore-spaces", 'i', "Ignore space after function names.", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.", {"local-infile", OPT_LOCAL_INFILE, "Enable/disable LOAD DATA LOCAL INFILE.",
...@@ -602,13 +602,6 @@ static struct my_option my_long_options[] = ...@@ -602,13 +602,6 @@ static struct my_option my_long_options[] =
NO_ARG, 1, 0, 0, 0, 0, 0}, NO_ARG, 1, 0, 0, 0, 0, 0},
{"skip-line-numbers", 'L', "Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead.", 0, 0, 0, GET_NO_ARG, {"skip-line-numbers", 'L', "Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0}, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef USE_POPEN
{"no-pager", OPT_NOPAGER,
"Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"no-tee", OPT_NOTEE, "Disable outfile. See interactive help (\\h) also. WARNING: option deprecated; use --disable-tee instead", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"unbuffered", 'n', "Flush buffer after each query.", (gptr*) &unbuffered, {"unbuffered", 'n', "Flush buffer after each query.", (gptr*) &unbuffered,
(gptr*) &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, (gptr*) &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"column-names", OPT_COLUMN_NAMES, "Write column names in results.", {"column-names", OPT_COLUMN_NAMES, "Write column names in results.",
...@@ -628,8 +621,11 @@ static struct my_option my_long_options[] = ...@@ -628,8 +621,11 @@ static struct my_option my_long_options[] =
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef USE_POPEN #ifdef USE_POPEN
{"pager", OPT_PAGER, {"pager", OPT_PAGER,
"Pager to use to display results. If you don't supply an option the default pager is taken from your ENV variable PAGER. Valid pagers are less, more, cat [> filename], etc. See interactive help (\\h) also. This option does not work in batch mode.", "Pager to use to display results. If you don't supply an option the default pager is taken from your ENV variable PAGER. Valid pagers are less, more, cat [> filename], etc. See interactive help (\\h) also. This option does not work in batch mode. Disable with --disable-pager. This option is disabled by default.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"no-pager", OPT_NOPAGER,
"Disable pager and print to stdout. See interactive help (\\h) also. WARNING: option deprecated; use --disable-pager instead.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif #endif
{"password", 'p', {"password", 'p',
"Password to use when connecting to server. If password is not given it's asked from the tty.", "Password to use when connecting to server. If password is not given it's asked from the tty.",
...@@ -670,8 +666,10 @@ static struct my_option my_long_options[] = ...@@ -670,8 +666,10 @@ static struct my_option my_long_options[] =
{"debug-info", 'T', "Print some debug info at exit.", (gptr*) &info_flag, {"debug-info", 'T', "Print some debug info at exit.", (gptr*) &info_flag,
(gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, (gptr*) &info_flag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"tee", OPT_TEE, {"tee", OPT_TEE,
"Append everything into outfile. See interactive help (\\h) also. Does not work in batch mode.", "Append everything into outfile. See interactive help (\\h) also. Does not work in batch mode. Disable with --disable-tee. This option is disabled by default.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"no-tee", OPT_NOTEE, "Disable outfile. See interactive help (\\h) also. WARNING: option deprecated; use --disable-tee instead", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DONT_ALLOW_USER_CHANGE #ifndef DONT_ALLOW_USER_CHANGE
{"user", 'u', "User for login if not current user.", (gptr*) &current_user, {"user", 'u', "User for login if not current user.", (gptr*) &current_user,
(gptr*) &current_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, (gptr*) &current_user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
...@@ -1795,7 +1793,14 @@ static int com_server_help(String *buffer __attribute__((unused)), ...@@ -1795,7 +1793,14 @@ static int com_server_help(String *buffer __attribute__((unused)),
if (help_arg[0] != '\'') if (help_arg[0] != '\'')
{ {
(void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NullS); char *end_arg= strend(help_arg);
if(--end_arg)
{
while (my_isspace(charset_info,*end_arg))
end_arg--;
*++end_arg= '\0';
}
(void) strxnmov(cmd_buf, sizeof(cmd_buf), "help '", help_arg, "'", NullS);
server_cmd= cmd_buf; server_cmd= cmd_buf;
} }
...@@ -1881,9 +1886,13 @@ com_help(String *buffer __attribute__((unused)), ...@@ -1881,9 +1886,13 @@ com_help(String *buffer __attribute__((unused)),
{ {
reg1 int i, j; reg1 int i, j;
char * help_arg= strchr(line,' '), buff[32], *end; char * help_arg= strchr(line,' '), buff[32], *end;
if (help_arg) if (help_arg)
return com_server_help(buffer,line,help_arg+1); {
while (my_isspace(charset_info,*help_arg))
help_arg++;
if (*help_arg)
return com_server_help(buffer,line,help_arg);
}
put_info("\nFor information about MySQL products and services, visit:\n" put_info("\nFor information about MySQL products and services, visit:\n"
" http://www.mysql.com/\n" " http://www.mysql.com/\n"
......
...@@ -73,7 +73,10 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, ...@@ -73,7 +73,10 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
int res; int res;
if (flag) if (flag)
{
info->last_pos= NULL; /* For heap_rnext/heap_rprev */ info->last_pos= NULL; /* For heap_rnext/heap_rprev */
info->lastkey_len= 0;
}
custom_arg.keyseg= keyinfo->seg; custom_arg.keyseg= keyinfo->seg;
custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos); custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos);
......
...@@ -172,7 +172,17 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec) ...@@ -172,7 +172,17 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_AKTIV | info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_AKTIV |
key_changed); key_changed);
myisam_log_record(MI_LOG_UPDATE,info,newrec,info->lastpos,0); myisam_log_record(MI_LOG_UPDATE,info,newrec,info->lastpos,0);
VOID(_mi_writeinfo(info,key_changed ? WRITEINFO_UPDATE_KEYFILE : 0)); /*
Every myisam function that updates myisam table must end with
call to _mi_writeinfo(). If operation (second param of
_mi_writeinfo()) is not 0 it sets share->changed to 1, that is
flags that data has changed. If operation is 0, this function
equals to no-op in this case.
mi_update() must always pass !0 value as operation, since even if
there is no index change there could be data change.
*/
VOID(_mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE));
allow_break(); /* Allow SIGHUP & SIGINT */ allow_break(); /* Allow SIGHUP & SIGINT */
if (info->invalidator != 0) if (info->invalidator != 0)
{ {
......
...@@ -483,13 +483,6 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) ...@@ -483,13 +483,6 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
if (!got_error) if (!got_error)
{ {
mi_set_key_active(share->state.key_map, sinfo->key); mi_set_key_active(share->state.key_map, sinfo->key);
if (param->testflag & T_STATISTICS)
update_key_parts(sinfo->keyinfo, rec_per_key_part, sinfo->unique,
param->stats_method == MI_STATS_METHOD_IGNORE_NULLS?
sinfo->notnull: NULL,
(ulonglong) info->state->records);
if (!sinfo->buffpek.elements) if (!sinfo->buffpek.elements)
{ {
if (param->testflag & T_VERBOSE) if (param->testflag & T_VERBOSE)
...@@ -501,6 +494,11 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) ...@@ -501,6 +494,11 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
flush_ft_buf(sinfo) || flush_pending_blocks(sinfo)) flush_ft_buf(sinfo) || flush_pending_blocks(sinfo))
got_error=1; got_error=1;
} }
if (!got_error && param->testflag & T_STATISTICS)
update_key_parts(sinfo->keyinfo, rec_per_key_part, sinfo->unique,
param->stats_method == MI_STATS_METHOD_IGNORE_NULLS?
sinfo->notnull: NULL,
(ulonglong) info->state->records);
} }
my_free((gptr) sinfo->sort_keys,MYF(0)); my_free((gptr) sinfo->sort_keys,MYF(0));
my_free(mi_get_rec_buff_ptr(info, sinfo->rec_buff), my_free(mi_get_rec_buff_ptr(info, sinfo->rec_buff),
......
...@@ -426,6 +426,7 @@ revoke all on mysqltest_2.t1 from mysqltest_3@localhost; ...@@ -426,6 +426,7 @@ revoke all on mysqltest_2.t1 from mysqltest_3@localhost;
revoke all on mysqltest_2.t2 from mysqltest_3@localhost; revoke all on mysqltest_2.t2 from mysqltest_3@localhost;
grant all on mysqltest_2.* to mysqltest_3@localhost; grant all on mysqltest_2.* to mysqltest_3@localhost;
grant select on *.* to mysqltest_3@localhost; grant select on *.* to mysqltest_3@localhost;
grant select on mysqltest_2.t1 to mysqltest_3@localhost;
flush privileges; flush privileges;
use mysqltest_1; use mysqltest_1;
update mysqltest_2.t1, mysqltest_2.t2 set c=500,d=600; update mysqltest_2.t1, mysqltest_2.t2 set c=500,d=600;
......
...@@ -118,6 +118,16 @@ flush privileges; ...@@ -118,6 +118,16 @@ flush privileges;
drop user mysqltest_3@host3; drop user mysqltest_3@host3;
drop user mysqltest_1@host1, mysqltest_2@host2, mysqltest_4@host4, drop user mysqltest_1@host1, mysqltest_2@host2, mysqltest_4@host4,
mysqltest_5@host5, mysqltest_6@host6, mysqltest_7@host7; mysqltest_5@host5, mysqltest_6@host6, mysqltest_7@host7;
create database mysqltest_1;
grant select, insert, update on `mysqltest\_1`.* to mysqltest_1@localhost;
set sql_log_off = 1;
ERROR 42000: Access denied; you need the SUPER privilege for this operation
set sql_log_bin = 0;
ERROR 42000: Access denied; you need the SUPER privilege for this operation
delete from mysql.user where user like 'mysqltest\_1';
delete from mysql.db where user like 'mysqltest\_1';
drop database mysqltest_1;
flush privileges;
set sql_mode='maxdb'; set sql_mode='maxdb';
drop table if exists t1, t2; drop table if exists t1, t2;
create table t1(c1 int); create table t1(c1 int);
......
...@@ -246,6 +246,41 @@ DELETE from t1 where a < 100; ...@@ -246,6 +246,41 @@ DELETE from t1 where a < 100;
SELECT * from t1; SELECT * from t1;
a a
DROP TABLE t1; DROP TABLE t1;
create table t1(a int not null, key using btree(a)) engine=heap;
insert into t1 values (2), (2), (2), (1), (1), (3), (3), (3), (3);
select a from t1 where a > 2 order by a;
a
3
3
3
3
delete from t1 where a < 4;
select a from t1 order by a;
a
insert into t1 values (2), (2), (2), (1), (1), (3), (3), (3), (3);
select a from t1 where a > 4 order by a;
a
delete from t1 where a > 4;
select a from t1 order by a;
a
1
1
2
2
2
3
3
3
3
select a from t1 where a > 3 order by a;
a
delete from t1 where a >= 2;
select a from t1 order by a;
a
1
1
drop table t1;
End of 4.1 tests
CREATE TABLE t1(val INT, KEY USING BTREE(val)) ENGINE=memory; CREATE TABLE t1(val INT, KEY USING BTREE(val)) ENGINE=memory;
INSERT INTO t1 VALUES(0); INSERT INTO t1 VALUES(0);
SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1'; SELECT INDEX_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='t1';
......
...@@ -2,6 +2,54 @@ ...@@ -2,6 +2,54 @@
1 1
ERROR 1064 (42000) at line 3: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 ERROR 1064 (42000) at line 3: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
ERROR at line 1: USE must be followed by a database name ERROR at line 1: USE must be followed by a database name
? (\?) Synonym for `help'.
clear (\c) Clear command.
connect (\r) Reconnect to the server. Optional arguments are db and host.
delimiter (\d) Set statement delimiter. NOTE: Takes the rest of the line as new delimiter.
edit (\e) Edit command with $EDITOR.
ego (\G) Send command to mysql server, display result vertically.
exit (\q) Exit mysql. Same as quit.
go (\g) Send command to mysql server.
help (\h) Display this help.
nopager (\n) Disable pager, print to stdout.
notee (\t) Don't write into outfile.
pager (\P) Set PAGER [to_pager]. Print the query results via PAGER.
print (\p) Print current command.
prompt (\R) Change your mysql prompt.
quit (\q) Quit mysql.
rehash (\#) Rebuild completion hash.
source (\.) Execute an SQL script file. Takes a file name as an argument.
status (\s) Get status information from the server.
system (\!) Execute a system shell command.
tee (\T) Set outfile [to_outfile]. Append everything into given outfile.
use (\u) Use another database. Takes database name as argument.
charset (\C) Switch to another charset. Might be needed for processing binlog with multi-byte charsets.
warnings (\W) Show warnings after every statement.
nowarning (\w) Don't show warnings after every statement.
? (\?) Synonym for `help'.
clear (\c) Clear command.
connect (\r) Reconnect to the server. Optional arguments are db and host.
delimiter (\d) Set statement delimiter. NOTE: Takes the rest of the line as new delimiter.
edit (\e) Edit command with $EDITOR.
ego (\G) Send command to mysql server, display result vertically.
exit (\q) Exit mysql. Same as quit.
go (\g) Send command to mysql server.
help (\h) Display this help.
nopager (\n) Disable pager, print to stdout.
notee (\t) Don't write into outfile.
pager (\P) Set PAGER [to_pager]. Print the query results via PAGER.
print (\p) Print current command.
prompt (\R) Change your mysql prompt.
quit (\q) Quit mysql.
rehash (\#) Rebuild completion hash.
source (\.) Execute an SQL script file. Takes a file name as an argument.
status (\s) Get status information from the server.
system (\!) Execute a system shell command.
tee (\T) Set outfile [to_outfile]. Append everything into given outfile.
use (\u) Use another database. Takes database name as argument.
charset (\C) Switch to another charset. Might be needed for processing binlog with multi-byte charsets.
warnings (\W) Show warnings after every statement.
nowarning (\w) Don't show warnings after every statement.
\ \
\\ \\
'; ';
......
...@@ -2876,7 +2876,7 @@ drop view v1; ...@@ -2876,7 +2876,7 @@ drop view v1;
drop table t1; drop table t1;
drop database mysqldump_dbb; drop database mysqldump_dbb;
use test; use test;
create user mysqltest_1; create user mysqltest_1@localhost;
create table t1(a int, b varchar(34)); create table t1(a int, b varchar(34));
reset master; reset master;
mysqldump: Couldn't execute 'FLUSH TABLES': Access denied; you need the RELOAD privilege for this operation (1227) mysqldump: Couldn't execute 'FLUSH TABLES': Access denied; you need the RELOAD privilege for this operation (1227)
...@@ -2891,4 +2891,4 @@ CREATE TABLE `t1` ( ...@@ -2891,4 +2891,4 @@ CREATE TABLE `t1` (
`b` varchar(34) default NULL `b` varchar(34) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1; ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
drop table t1; drop table t1;
drop user mysqltest_1; drop user mysqltest_1@localhost;
...@@ -41,3 +41,14 @@ Table Op Msg_type Msg_text ...@@ -41,3 +41,14 @@ Table Op Msg_type Msg_text
test.t1 repair warning Number of rows changed from 0 to 1 test.t1 repair warning Number of rows changed from 0 to 1
test.t1 repair status OK test.t1 repair status OK
drop table t1; drop table t1;
CREATE TABLE t1(a INT, KEY(a));
INSERT INTO t1 VALUES(1),(2),(3),(4),(5);
SET myisam_repair_threads=2;
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
SHOW INDEX FROM t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A 5 NULL NULL YES BTREE
SET myisam_repair_threads=@@global.myisam_repair_threads;
DROP TABLE t1;
...@@ -362,6 +362,8 @@ revoke all on mysqltest_2.t2 from mysqltest_3@localhost; ...@@ -362,6 +362,8 @@ revoke all on mysqltest_2.t2 from mysqltest_3@localhost;
#test the db/table level privileges #test the db/table level privileges
grant all on mysqltest_2.* to mysqltest_3@localhost; grant all on mysqltest_2.* to mysqltest_3@localhost;
grant select on *.* to mysqltest_3@localhost; grant select on *.* to mysqltest_3@localhost;
# Next grant is needed to trigger bug#7391. Do not optimize!
grant select on mysqltest_2.t1 to mysqltest_3@localhost;
flush privileges; flush privileges;
disconnect conn1; disconnect conn1;
connect (conn2,localhost,mysqltest_3,,); connect (conn2,localhost,mysqltest_3,,);
......
...@@ -188,6 +188,24 @@ disconnect con9; ...@@ -188,6 +188,24 @@ disconnect con9;
connection default; connection default;
# #
# Bug# 16180 - Setting SQL_LOG_OFF without SUPER privilege is silently ignored
#
create database mysqltest_1;
grant select, insert, update on `mysqltest\_1`.* to mysqltest_1@localhost;
connect (con10,localhost,mysqltest_1,,);
connection con10;
--error 1227
set sql_log_off = 1;
--error 1227
set sql_log_bin = 0;
disconnect con10;
connection default;
delete from mysql.user where user like 'mysqltest\_1';
delete from mysql.db where user like 'mysqltest\_1';
drop database mysqltest_1;
flush privileges;
# End of 4.1 tests
# Create and drop user # Create and drop user
# #
set sql_mode='maxdb'; set sql_mode='maxdb';
......
...@@ -164,6 +164,26 @@ DELETE from t1 where a < 100; ...@@ -164,6 +164,26 @@ DELETE from t1 where a < 100;
SELECT * from t1; SELECT * from t1;
DROP TABLE t1; DROP TABLE t1;
#
# Bug #9719: problem with delete
#
create table t1(a int not null, key using btree(a)) engine=heap;
insert into t1 values (2), (2), (2), (1), (1), (3), (3), (3), (3);
select a from t1 where a > 2 order by a;
delete from t1 where a < 4;
select a from t1 order by a;
insert into t1 values (2), (2), (2), (1), (1), (3), (3), (3), (3);
select a from t1 where a > 4 order by a;
delete from t1 where a > 4;
select a from t1 order by a;
select a from t1 where a > 3 order by a;
delete from t1 where a >= 2;
select a from t1 order by a;
drop table t1;
--echo End of 4.1 tests
# #
# BUG#18160 - Memory-/HEAP Table endless growing indexes # BUG#18160 - Memory-/HEAP Table endless growing indexes
# #
...@@ -184,4 +204,3 @@ CREATE TABLE t1 (a INT, UNIQUE USING BTREE(a)) ENGINE=MEMORY; ...@@ -184,4 +204,3 @@ CREATE TABLE t1 (a INT, UNIQUE USING BTREE(a)) ENGINE=MEMORY;
INSERT INTO t1 VALUES(NULL),(NULL); INSERT INTO t1 VALUES(NULL),(NULL);
DROP TABLE t1; DROP TABLE t1;
# End of 4.1 tests
...@@ -28,6 +28,12 @@ ...@@ -28,6 +28,12 @@
--exec echo "use" > $MYSQLTEST_VARDIR/tmp/bug20432.sql --exec echo "use" > $MYSQLTEST_VARDIR/tmp/bug20432.sql
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1 --exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20432.sql 2>&1
#
# Bug #20328: mysql client interprets commands in comments
#
--exec echo 'help' | $MYSQL
--exec echo 'help ' | $MYSQL
# #
# Bug #20103: Escaping with backslash does not work # Bug #20103: Escaping with backslash does not work
# #
......
...@@ -1273,7 +1273,7 @@ drop database mysqldump_dbb; ...@@ -1273,7 +1273,7 @@ drop database mysqldump_dbb;
use test; use test;
# Create user without sufficient privs to perform the requested operation # Create user without sufficient privs to perform the requested operation
create user mysqltest_1; create user mysqltest_1@localhost;
create table t1(a int, b varchar(34)); create table t1(a int, b varchar(34));
# To get consistent output, reset the master, starts over from first log # To get consistent output, reset the master, starts over from first log
...@@ -1308,4 +1308,4 @@ grant REPLICATION CLIENT on *.* to mysqltest_1@localhost; ...@@ -1308,4 +1308,4 @@ grant REPLICATION CLIENT on *.* to mysqltest_1@localhost;
# Clean up # Clean up
drop table t1; drop table t1;
drop user mysqltest_1; drop user mysqltest_1@localhost;
...@@ -34,4 +34,15 @@ repair table t1; ...@@ -34,4 +34,15 @@ repair table t1;
repair table t1 use_frm; repair table t1 use_frm;
drop table t1; drop table t1;
#
# BUG#18874 - Setting myisam_repair_threads > 1, index cardinality always 1
#
CREATE TABLE t1(a INT, KEY(a));
INSERT INTO t1 VALUES(1),(2),(3),(4),(5);
SET myisam_repair_threads=2;
REPAIR TABLE t1;
SHOW INDEX FROM t1;
SET myisam_repair_threads=@@global.myisam_repair_threads;
DROP TABLE t1;
# End of 4.1 tests # End of 4.1 tests
#!/usr/bin/perl #!@PERL@
#
# Copyright (C) 2003 MySQL AB
# For a more info consult the file COPYRIGHT distributed with this file.
#
# fill_func_tables - parse ../Docs/manual.texi # fill_func_tables - parse ../Docs/manual.texi
#
# Original version by vva # Original version by Victor Vagin <vva@mysql.com>
#
my $cat_name= ""; my $cat_name= "";
my $func_name= ""; my $func_name= "";
......
#!/bin/sh #!/bin/sh
# Copyright (C) 2002-2003 MySQL AB # Copyright (C) 2002-2003 MySQL AB
# For a more info consult the file COPYRIGHT distributed with this file. # For a more info consult the file COPYRIGHT distributed with this file.
......
...@@ -6412,6 +6412,11 @@ void Field_varstring::sql_type(String &res) const ...@@ -6412,6 +6412,11 @@ void Field_varstring::sql_type(String &res) const
} }
uint Field_varstring::data_length(const char *from)
{
return length_bytes == 1 ? (uint) (uchar) *ptr : uint2korr(ptr);
}
/* /*
Functions to create a packed row. Functions to create a packed row.
Here the number of length bytes are depending on the given max_length Here the number of length bytes are depending on the given max_length
......
...@@ -144,6 +144,11 @@ public: ...@@ -144,6 +144,11 @@ public:
table, which is located on disk). table, which is located on disk).
*/ */
virtual uint32 pack_length_in_rec() const { return pack_length(); } virtual uint32 pack_length_in_rec() const { return pack_length(); }
/*
data_length() return the "real size" of the data in memory.
*/
virtual uint32 data_length(const char *from) { return pack_length(); }
virtual uint32 sort_length() const { return pack_length(); } virtual uint32 sort_length() const { return pack_length(); }
virtual void reset(void) { bzero(ptr,pack_length()); } virtual void reset(void) { bzero(ptr,pack_length()); }
virtual void reset_fields() {} virtual void reset_fields() {}
...@@ -1102,6 +1107,7 @@ public: ...@@ -1102,6 +1107,7 @@ public:
int key_cmp(const byte *str, uint length); int key_cmp(const byte *str, uint length);
uint packed_col_length(const char *to, uint length); uint packed_col_length(const char *to, uint length);
uint max_packed_col_length(uint max_length); uint max_packed_col_length(uint max_length);
uint data_length(const char *from);
uint size_of() const { return sizeof(*this); } uint size_of() const { return sizeof(*this); }
enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; } enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; }
bool has_charset(void) const bool has_charset(void) const
......
...@@ -710,6 +710,28 @@ int ha_archive::write_row(byte *buf) ...@@ -710,6 +710,28 @@ int ha_archive::write_row(byte *buf)
if (init_archive_writer()) if (init_archive_writer())
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
/*
Varchar structures are constant in size but are not cleaned up request
to request. The following sets all unused space to null to improve
compression.
*/
for (Field **field=table->field ; *field ; field++)
{
DBUG_PRINT("archive",("Pack is %d\n", (*field)->pack_length()));
DBUG_PRINT("archive",("MyPack is %d\n", (*field)->data_length((char*) buf + (*field)->offset())));
if ((*field)->real_type() == MYSQL_TYPE_VARCHAR)
{
uint actual_length= (*field)->data_length((char*) buf + (*field)->offset());
uint offset= (*field)->offset() + actual_length +
(actual_length > 255 ? 2 : 1);
DBUG_PRINT("archive",("Offset is %d -> %d\n", actual_length, offset));
/*
if ((*field)->pack_length() + (*field)->offset() != offset)
bzero(buf + offset, (size_t)((*field)->pack_length() + (actual_length > 255 ? 2 : 1) - (*field)->data_length));
*/
}
}
share->rows_recorded++; share->rows_recorded++;
rc= real_write_row(buf, share->archive_write); rc= real_write_row(buf, share->archive_write);
pthread_mutex_unlock(&share->mutex); pthread_mutex_unlock(&share->mutex);
......
...@@ -509,7 +509,8 @@ static sys_var_thd_bit sys_sql_big_tables("sql_big_tables", 0, ...@@ -509,7 +509,8 @@ static sys_var_thd_bit sys_sql_big_tables("sql_big_tables", 0,
static sys_var_thd_bit sys_big_selects("sql_big_selects", 0, static sys_var_thd_bit sys_big_selects("sql_big_selects", 0,
set_option_bit, set_option_bit,
OPTION_BIG_SELECTS); OPTION_BIG_SELECTS);
static sys_var_thd_bit sys_log_off("sql_log_off", 0, static sys_var_thd_bit sys_log_off("sql_log_off",
check_log_update,
set_option_bit, set_option_bit,
OPTION_LOG_OFF); OPTION_LOG_OFF);
static sys_var_thd_bit sys_log_update("sql_log_update", static sys_var_thd_bit sys_log_update("sql_log_update",
......
...@@ -34,7 +34,8 @@ HASH open_cache; /* Used by mysql_test */ ...@@ -34,7 +34,8 @@ HASH open_cache; /* Used by mysql_test */
static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
const char *name, const char *alias, const char *name, const char *alias,
TABLE_LIST *table_list, MEM_ROOT *mem_root); TABLE_LIST *table_list, MEM_ROOT *mem_root,
uint flags);
static void free_cache_entry(TABLE *entry); static void free_cache_entry(TABLE *entry);
static void mysql_rm_tmp_tables(void); static void mysql_rm_tmp_tables(void);
static bool open_new_frm(THD *thd, const char *path, const char *alias, static bool open_new_frm(THD *thd, const char *path, const char *alias,
...@@ -1108,7 +1109,7 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list) ...@@ -1108,7 +1109,7 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1; key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
if (open_unireg_entry(thd, table, db, table_name, table_name, 0, if (open_unireg_entry(thd, table, db, table_name, table_name, 0,
thd->mem_root) || thd->mem_root, 0) ||
!(table->s->table_cache_key= memdup_root(&table->mem_root, (char*) key, !(table->s->table_cache_key= memdup_root(&table->mem_root, (char*) key,
key_length))) key_length)))
{ {
...@@ -1311,7 +1312,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, ...@@ -1311,7 +1312,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
if (!open_unireg_entry(thd, table, table_list->db, if (!open_unireg_entry(thd, table, table_list->db,
table_list->table_name, table_list->table_name,
alias, table_list, mem_root)) alias, table_list, mem_root, 0))
{ {
DBUG_ASSERT(table_list->view != 0); DBUG_ASSERT(table_list->view != 0);
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
...@@ -1391,6 +1392,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, ...@@ -1391,6 +1392,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
else else
{ {
TABLE_SHARE *share; TABLE_SHARE *share;
int error;
/* Free cache if too big */ /* Free cache if too big */
while (open_cache.records > table_cache_size && unused_tables) while (open_cache.records > table_cache_size && unused_tables)
VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */ VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */
...@@ -1401,9 +1403,12 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, ...@@ -1401,9 +1403,12 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
if (open_unireg_entry(thd, table, table_list->db, table_list->table_name, error= open_unireg_entry(thd, table, table_list->db,
alias, table_list, mem_root) || table_list->table_name,
(!table_list->view && alias, table_list, mem_root,
(flags & OPEN_VIEW_NO_PARSE));
if ((error > 0) ||
(!table_list->view && !error &&
!(table->s->table_cache_key= memdup_root(&table->mem_root, !(table->s->table_cache_key= memdup_root(&table->mem_root,
(char*) key, (char*) key,
key_length)))) key_length))))
...@@ -1413,8 +1418,15 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, ...@@ -1413,8 +1418,15 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
if (table_list->view) if (table_list->view || error < 0)
{ {
/*
VIEW not really opened, only frm were read.
Set 1 as a flag here
*/
if (error < 0)
table_list->view= (st_lex*)1;
my_free((gptr)table, MYF(0)); my_free((gptr)table, MYF(0));
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(0); // VIEW DBUG_RETURN(0); // VIEW
...@@ -1521,7 +1533,7 @@ bool reopen_table(TABLE *table,bool locked) ...@@ -1521,7 +1533,7 @@ bool reopen_table(TABLE *table,bool locked)
safe_mutex_assert_owner(&LOCK_open); safe_mutex_assert_owner(&LOCK_open);
if (open_unireg_entry(table->in_use, &tmp, db, table_name, if (open_unireg_entry(table->in_use, &tmp, db, table_name,
table->alias, 0, table->in_use->mem_root)) table->alias, 0, table->in_use->mem_root, 0))
goto end; goto end;
free_io_cache(table); free_io_cache(table);
...@@ -1851,6 +1863,8 @@ void abort_locked_tables(THD *thd,const char *db, const char *table_name) ...@@ -1851,6 +1863,8 @@ void abort_locked_tables(THD *thd,const char *db, const char *table_name)
alias Alias name alias Alias name
table_desc TABLE_LIST descriptor (used with views) table_desc TABLE_LIST descriptor (used with views)
mem_root temporary mem_root for parsing mem_root temporary mem_root for parsing
flags the OPEN_VIEW_NO_PARSE flag to be passed to
openfrm()/open_new_frm()
NOTES NOTES
Extra argument for open is taken from thd->open_options Extra argument for open is taken from thd->open_options
...@@ -1861,7 +1875,8 @@ void abort_locked_tables(THD *thd,const char *db, const char *table_name) ...@@ -1861,7 +1875,8 @@ void abort_locked_tables(THD *thd,const char *db, const char *table_name)
*/ */
static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
const char *name, const char *alias, const char *name, const char *alias,
TABLE_LIST *table_desc, MEM_ROOT *mem_root) TABLE_LIST *table_desc, MEM_ROOT *mem_root,
uint flags)
{ {
char path[FN_REFLEN]; char path[FN_REFLEN];
int error; int error;
...@@ -1873,14 +1888,16 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, ...@@ -1873,14 +1888,16 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
HA_GET_INDEX | HA_TRY_READ_ONLY | HA_GET_INDEX | HA_TRY_READ_ONLY |
NO_ERR_ON_NEW_FRM), NO_ERR_ON_NEW_FRM),
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD |
(flags & OPEN_VIEW_NO_PARSE),
thd->open_options, entry)) && thd->open_options, entry)) &&
(error != 5 || (error != 5 ||
(fn_format(path, path, 0, reg_ext, MY_UNPACK_FILENAME), (fn_format(path, path, 0, reg_ext, MY_UNPACK_FILENAME),
open_new_frm(thd, path, alias, db, name, open_new_frm(thd, path, alias, db, name,
(uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
HA_GET_INDEX | HA_TRY_READ_ONLY), HA_GET_INDEX | HA_TRY_READ_ONLY),
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD, READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD |
(flags & OPEN_VIEW_NO_PARSE),
thd->open_options, entry, table_desc, mem_root)))) thd->open_options, entry, table_desc, mem_root))))
{ {
...@@ -1962,7 +1979,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, ...@@ -1962,7 +1979,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
} }
if (error == 5) if (error == 5)
DBUG_RETURN(0); // we have just opened VIEW DBUG_RETURN((flags & OPEN_VIEW_NO_PARSE)? -1 : 0); // we have just opened VIEW
/* /*
We can't mark all tables in 'mysql' database as system since we don't We can't mark all tables in 'mysql' database as system since we don't
...@@ -5379,7 +5396,8 @@ open_new_frm(THD *thd, const char *path, const char *alias, ...@@ -5379,7 +5396,8 @@ open_new_frm(THD *thd, const char *path, const char *alias,
my_error(ER_WRONG_OBJECT, MYF(0), db, table_name, "BASE TABLE"); my_error(ER_WRONG_OBJECT, MYF(0), db, table_name, "BASE TABLE");
goto err; goto err;
} }
if (mysql_make_view(thd, parser, table_desc)) if (mysql_make_view(thd, parser, table_desc,
(prgflag & OPEN_VIEW_NO_PARSE)))
goto err; goto err;
} }
else else
......
...@@ -375,7 +375,7 @@ public: ...@@ -375,7 +375,7 @@ public:
friend class st_select_lex_unit; friend class st_select_lex_unit;
friend bool mysql_new_select(struct st_lex *lex, bool move_down); friend bool mysql_new_select(struct st_lex *lex, bool move_down);
friend bool mysql_make_view(THD *thd, File_parser *parser, friend bool mysql_make_view(THD *thd, File_parser *parser,
TABLE_LIST *table); TABLE_LIST *table, uint flags);
private: private:
void fast_exclude(); void fast_exclude();
}; };
......
...@@ -179,22 +179,16 @@ static bool ...@@ -179,22 +179,16 @@ static bool
fill_defined_view_parts (THD *thd, TABLE_LIST *view) fill_defined_view_parts (THD *thd, TABLE_LIST *view)
{ {
LEX *lex= thd->lex; LEX *lex= thd->lex;
bool free_view= 1; bool not_used;
TABLE_LIST decoy; TABLE_LIST decoy;
if (view->view)
free_view= 0;
memcpy (&decoy, view, sizeof (TABLE_LIST)); memcpy (&decoy, view, sizeof (TABLE_LIST));
if ((decoy.table= open_table(thd, &decoy, thd->mem_root, NULL, 0))) if (!open_table(thd, &decoy, thd->mem_root, &not_used, OPEN_VIEW_NO_PARSE) &&
!decoy.view)
{ {
/* It's a table */ /* It's a table */
my_free((gptr)decoy.table, MYF(0));
my_error(ER_WRONG_OBJECT, MYF(0), view->db, view->table_name, "VIEW");
return TRUE; return TRUE;
} }
if (!decoy.view)
/* An error while opening the view occurs, caller will handle it */
return FALSE;
if (!lex->definer) if (!lex->definer)
{ {
...@@ -207,11 +201,6 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view) ...@@ -207,11 +201,6 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view)
if (lex->create_view_suid == VIEW_SUID_DEFAULT) if (lex->create_view_suid == VIEW_SUID_DEFAULT)
lex->create_view_suid= decoy.view_suid ? lex->create_view_suid= decoy.view_suid ?
VIEW_SUID_DEFINER : VIEW_SUID_INVOKER; VIEW_SUID_DEFINER : VIEW_SUID_INVOKER;
if (free_view)
{
delete decoy.view;
lex->cleanup_after_one_table_open();
}
return FALSE; return FALSE;
} }
...@@ -830,13 +819,14 @@ loop_out: ...@@ -830,13 +819,14 @@ loop_out:
thd Thread handler thd Thread handler
parser parser object parser parser object
table TABLE_LIST structure for filling table TABLE_LIST structure for filling
flags flags
RETURN RETURN
0 ok 0 ok
1 error 1 error
*/ */
bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table) bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
uint flags)
{ {
SELECT_LEX *end, *view_select; SELECT_LEX *end, *view_select;
LEX *old_lex, *lex; LEX *old_lex, *lex;
...@@ -927,6 +917,10 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table) ...@@ -927,6 +917,10 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
table->db, table->table_name); table->db, table->table_name);
get_default_definer(thd, &table->definer); get_default_definer(thd, &table->definer);
} }
if (flags & OPEN_VIEW_NO_PARSE)
{
DBUG_RETURN(FALSE);
}
/* /*
Save VIEW parameters, which will be wiped out by derived table Save VIEW parameters, which will be wiped out by derived table
......
...@@ -19,7 +19,8 @@ ...@@ -19,7 +19,8 @@
bool mysql_create_view(THD *thd, bool mysql_create_view(THD *thd,
enum_view_create_mode mode); enum_view_create_mode mode);
bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table); bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
uint flags);
bool mysql_drop_view(THD *thd, TABLE_LIST *view, enum_drop_mode drop_mode); bool mysql_drop_view(THD *thd, TABLE_LIST *view, enum_drop_mode drop_mode);
......
...@@ -121,6 +121,8 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, ...@@ -121,6 +121,8 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
// caller can't process new .frm // caller can't process new .frm
goto err; goto err;
} }
if (prgflag & OPEN_VIEW_NO_PARSE)
goto err;
share->blob_ptr_size= sizeof(char*); share->blob_ptr_size= sizeof(char*);
outparam->db_stat= db_stat; outparam->db_stat= db_stat;
......
...@@ -147,7 +147,8 @@ ...@@ -147,7 +147,8 @@
#define READ_SCREENS 1024 /* Read screens, info and helpfile */ #define READ_SCREENS 1024 /* Read screens, info and helpfile */
#define DELAYED_OPEN 4096 /* Open table later */ #define DELAYED_OPEN 4096 /* Open table later */
#define NO_ERR_ON_NEW_FRM 8192 /* stop error sending on new format */ #define NO_ERR_ON_NEW_FRM 8192 /* stop error sending on new format */
#define OPEN_VIEW_NO_PARSE 16384 /* Open frm only if it's a view,
but do not parse view itself */
#define SC_INFO_LENGTH 4 /* Form format constant */ #define SC_INFO_LENGTH 4 /* Form format constant */
#define TE_INFO_LENGTH 3 #define TE_INFO_LENGTH 3
#define MTYP_NOEMPTY_BIT 128 #define MTYP_NOEMPTY_BIT 128
......
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