mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 05:22:25 +01:00
Merge jlindstrom@bk-internal.mysql.com:/home/bk/mysql-4.1
into hundin.mysql.fi:/home/jan/mysql-4.1
This commit is contained in:
commit
2f65c531a8
13 changed files with 208 additions and 30 deletions
|
@ -27,12 +27,20 @@
|
|||
|
||||
const char *config_file="my"; /* Default config file */
|
||||
uint verbose= 0, opt_defaults_file_used= 0;
|
||||
const char *default_dbug_option="d:t:o,/tmp/my_print_defaults.trace";
|
||||
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
{"config-file", 'c', "The config file to be used.",
|
||||
(gptr*) &config_file, (gptr*) &config_file, 0, GET_STR, REQUIRED_ARG,
|
||||
0, 0, 0, 0, 0, 0},
|
||||
#ifdef DBUG_OFF
|
||||
{"debug", '#', "This is a non-debug version. Catch this and exit",
|
||||
0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#else
|
||||
{"debug", '#', "Output debug log", (gptr*) &default_dbug_option,
|
||||
(gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#endif
|
||||
{"defaults-file", 'c', "Synonym for --config-file.",
|
||||
(gptr*) &config_file, (gptr*) &config_file, 0, GET_STR, REQUIRED_ARG,
|
||||
0, 0, 0, 0, 0, 0},
|
||||
|
@ -95,6 +103,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||
case 'V':
|
||||
usage(1);
|
||||
exit(0);
|
||||
case '#':
|
||||
DBUG_PUSH(argument ? argument : default_dbug_option);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -118,7 +129,7 @@ static int get_options(int *argc,char ***argv)
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
int count, error;
|
||||
char **load_default_groups, *tmp_arguments[2],
|
||||
char **load_default_groups, *tmp_arguments[3],
|
||||
**argument, **arguments;
|
||||
char *defaults, *extra_defaults;
|
||||
MY_INIT(argv[0]);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
void Querycache_stream::store_char(char c)
|
||||
{
|
||||
if (data_end == cur_data)
|
||||
use_next_block();
|
||||
use_next_block(TRUE);
|
||||
*(cur_data++)= c;
|
||||
#ifndef DBUG_OFF
|
||||
stored_size++;
|
||||
|
@ -42,13 +42,13 @@ void Querycache_stream::store_short(ushort s)
|
|||
}
|
||||
if (data_end == cur_data)
|
||||
{
|
||||
use_next_block();
|
||||
use_next_block(TRUE);
|
||||
int2store(cur_data, s);
|
||||
cur_data+= 2;
|
||||
return;
|
||||
}
|
||||
*cur_data= ((byte *)(&s))[0];
|
||||
use_next_block();
|
||||
use_next_block(TRUE);
|
||||
*(cur_data++)= ((byte *)(&s))[1];
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ void Querycache_stream::store_int(uint i)
|
|||
}
|
||||
if (!rest_len)
|
||||
{
|
||||
use_next_block();
|
||||
use_next_block(TRUE);
|
||||
int4store(cur_data, i);
|
||||
cur_data+= 4;
|
||||
return;
|
||||
|
@ -74,7 +74,7 @@ void Querycache_stream::store_int(uint i)
|
|||
char buf[4];
|
||||
int4store(buf, i);
|
||||
memcpy(cur_data, buf, rest_len);
|
||||
use_next_block();
|
||||
use_next_block(TRUE);
|
||||
memcpy(cur_data, buf+rest_len, 4-rest_len);
|
||||
cur_data+= 4-rest_len;
|
||||
}
|
||||
|
@ -93,13 +93,13 @@ void Querycache_stream::store_ll(ulonglong ll)
|
|||
}
|
||||
if (!rest_len)
|
||||
{
|
||||
use_next_block();
|
||||
use_next_block(TRUE);
|
||||
int8store(cur_data, ll);
|
||||
cur_data+= 8;
|
||||
return;
|
||||
}
|
||||
memcpy(cur_data, &ll, rest_len);
|
||||
use_next_block();
|
||||
use_next_block(TRUE);
|
||||
memcpy(cur_data, ((byte*)&ll)+rest_len, 8-rest_len);
|
||||
cur_data+= 8-rest_len;
|
||||
}
|
||||
|
@ -112,14 +112,14 @@ void Querycache_stream::store_str_only(const char *str, uint str_len)
|
|||
do
|
||||
{
|
||||
size_t rest_len= data_end - cur_data;
|
||||
if (rest_len > str_len)
|
||||
if (rest_len >= str_len)
|
||||
{
|
||||
memcpy(cur_data, str, str_len);
|
||||
cur_data+= str_len;
|
||||
return;
|
||||
}
|
||||
memcpy(cur_data, str, rest_len);
|
||||
use_next_block();
|
||||
use_next_block(TRUE);
|
||||
str_len-= rest_len;
|
||||
str+= rest_len;
|
||||
} while(str_len);
|
||||
|
@ -145,7 +145,7 @@ void Querycache_stream::store_safe_str(const char *str, uint str_len)
|
|||
char Querycache_stream::load_char()
|
||||
{
|
||||
if (cur_data == data_end)
|
||||
use_next_block();
|
||||
use_next_block(FALSE);
|
||||
return *(cur_data++);
|
||||
}
|
||||
|
||||
|
@ -160,13 +160,13 @@ ushort Querycache_stream::load_short()
|
|||
}
|
||||
if (data_end == cur_data)
|
||||
{
|
||||
use_next_block();
|
||||
use_next_block(FALSE);
|
||||
result= uint2korr(cur_data);
|
||||
cur_data+= 2;
|
||||
return result;
|
||||
}
|
||||
((byte*)&result)[0]= *cur_data;
|
||||
use_next_block();
|
||||
use_next_block(FALSE);
|
||||
((byte*)&result)[1]= *(cur_data++);
|
||||
return result;
|
||||
}
|
||||
|
@ -183,14 +183,14 @@ uint Querycache_stream::load_int()
|
|||
}
|
||||
if (!rest_len)
|
||||
{
|
||||
use_next_block();
|
||||
use_next_block(FALSE);
|
||||
result= uint4korr(cur_data);
|
||||
cur_data+= 4;
|
||||
return result;
|
||||
}
|
||||
char buf[4];
|
||||
memcpy(buf, cur_data, rest_len);
|
||||
use_next_block();
|
||||
use_next_block(FALSE);
|
||||
memcpy(buf+rest_len, cur_data, 4-rest_len);
|
||||
cur_data+= 4-rest_len;
|
||||
result= uint4korr(buf);
|
||||
|
@ -209,13 +209,13 @@ ulonglong Querycache_stream::load_ll()
|
|||
}
|
||||
if (!rest_len)
|
||||
{
|
||||
use_next_block();
|
||||
use_next_block(FALSE);
|
||||
result= uint8korr(cur_data);
|
||||
cur_data+= 8;
|
||||
return result;
|
||||
}
|
||||
memcpy(&result, cur_data, rest_len);
|
||||
use_next_block();
|
||||
use_next_block(FALSE);
|
||||
memcpy(((byte*)&result)+rest_len, cur_data, 8-rest_len);
|
||||
cur_data+= 8-rest_len;
|
||||
return result;
|
||||
|
@ -226,7 +226,7 @@ void Querycache_stream::load_str_only(char *buffer, uint str_len)
|
|||
do
|
||||
{
|
||||
size_t rest_len= data_end - cur_data;
|
||||
if (rest_len > str_len)
|
||||
if (rest_len >= str_len)
|
||||
{
|
||||
memcpy(buffer, cur_data, str_len);
|
||||
cur_data+= str_len;
|
||||
|
@ -234,7 +234,7 @@ void Querycache_stream::load_str_only(char *buffer, uint str_len)
|
|||
break;
|
||||
}
|
||||
memcpy(buffer, cur_data, rest_len);
|
||||
use_next_block();
|
||||
use_next_block(FALSE);
|
||||
str_len-= rest_len;
|
||||
buffer+= rest_len;
|
||||
} while(str_len);
|
||||
|
|
|
@ -22,18 +22,39 @@ class Querycache_stream
|
|||
uint headers_len;
|
||||
public:
|
||||
#ifndef DBUG_OFF
|
||||
Query_cache_block *first_block;
|
||||
uint stored_size;
|
||||
#endif
|
||||
Querycache_stream(Query_cache_block *ini_block, uint ini_headers_len) :
|
||||
block(ini_block), headers_len(ini_headers_len)
|
||||
{
|
||||
use_next_block();
|
||||
cur_data= ((byte*)block)+headers_len;
|
||||
data_end= cur_data + (block->used-headers_len);
|
||||
#ifndef DBUG_OFF
|
||||
first_block= ini_block;
|
||||
stored_size= 0;
|
||||
#endif
|
||||
}
|
||||
void use_next_block()
|
||||
void use_next_block(bool writing)
|
||||
{
|
||||
/*
|
||||
This shouldn't be called if there is only one block, or to loop
|
||||
around to the first block again. That means we're trying to write
|
||||
more data than we allocated space for.
|
||||
*/
|
||||
DBUG_ASSERT(block->next != block);
|
||||
DBUG_ASSERT(block->next != first_block);
|
||||
|
||||
block= block->next;
|
||||
/*
|
||||
While writing, update the type of each block as we write to it.
|
||||
While reading, make sure that the block is of the expected type.
|
||||
*/
|
||||
if (writing)
|
||||
block->type= Query_cache_block::RES_CONT;
|
||||
else
|
||||
DBUG_ASSERT(block->type == Query_cache_block::RES_CONT);
|
||||
|
||||
cur_data= ((byte*)block)+headers_len;
|
||||
data_end= cur_data + (block->used-headers_len);
|
||||
}
|
||||
|
|
|
@ -685,6 +685,12 @@ then
|
|||
fi
|
||||
|
||||
MYSQL_CLIENT_TEST="$MYSQL_CLIENT_TEST --no-defaults --testcase --user=root --socket=$MASTER_MYSOCK --port=$MYSQL_TCP_PORT --silent $EXTRA_MYSQL_CLIENT_TEST_OPT"
|
||||
# Need to pass additional arguments to MYSQL_CLIENT_TEST for embedded server
|
||||
# -A marks each argument for passing to the function which initializes the
|
||||
# embedded library
|
||||
if [ "x$USE_EMBEDDED_SERVER" = "x1" ]; then
|
||||
MYSQL_CLIENT_TEST="$MYSQL_CLIENT_TEST -A --language=$LANGUAGE -A --datadir=$SLAVE_MYDDIR -A --character-sets-dir=$CHARSETSDIR"
|
||||
fi
|
||||
MYSQL_DUMP="$MYSQL_DUMP --no-defaults -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLDUMP_OPT"
|
||||
MYSQL_BINLOG="$MYSQL_BINLOG --no-defaults --local-load=$MYSQL_TMP_DIR $EXTRA_MYSQLBINLOG_OPT"
|
||||
MYSQL_FIX_SYSTEM_TABLES="$MYSQL_FIX_SYSTEM_TABLES --no-defaults --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --user=root --password=$DBPASSWD --basedir=$BASEDIR --bindir=$CLIENT_BINDIR --verbose"
|
||||
|
|
|
@ -78,5 +78,8 @@ ERROR 42000: Not unique table/alias: 'C'
|
|||
select C.a, c.a from t1 c, t2 C;
|
||||
ERROR 42000: Not unique table/alias: 'C'
|
||||
drop table t1, t2;
|
||||
create table t1 (a int);
|
||||
create table t2 like T1;
|
||||
drop table t1, t2;
|
||||
show tables;
|
||||
Tables_in_test
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -73,4 +73,12 @@ select * from t1 c, t2 C;
|
|||
select C.a, c.a from t1 c, t2 C;
|
||||
drop table t1, t2;
|
||||
|
||||
#
|
||||
# Bug #9761: CREATE TABLE ... LIKE ... not handled correctly when
|
||||
# lower_case_table_names is set
|
||||
|
||||
create table t1 (a int);
|
||||
create table t2 like T1;
|
||||
drop table t1, t2;
|
||||
|
||||
show tables;
|
||||
|
|
|
@ -685,4 +685,49 @@ repair table t1;
|
|||
show status like 'qcache_queries_in_cache';
|
||||
drop table t1;
|
||||
|
||||
# Bug #9549: Make sure cached queries that span more than one cache block
|
||||
# are handled properly in the embedded server.
|
||||
|
||||
# We just want a small query cache, so we can fragment it easily
|
||||
set GLOBAL query_cache_size=64*1024;
|
||||
# This actually gives us a usable cache size of about 48K
|
||||
|
||||
# Each table is about 14K
|
||||
create table t1 (a text);
|
||||
insert into t1 values (repeat('abcdefghijklmnopqrstuvwxyz', 550));
|
||||
create table t2 (a text);
|
||||
insert into t2 values (repeat('ijklmnopqrstuvwxyzabcdefgh', 550));
|
||||
|
||||
# Load a query from each table into the query cache
|
||||
--disable_result_log
|
||||
select a from t1; # Q1
|
||||
select a from t2; # Q2
|
||||
--enable_result_log
|
||||
show status like 'Qcache_%_blocks';
|
||||
|
||||
# Now the cache looks like (14K for Q1)(14K for Q2)(20K free)
|
||||
|
||||
# Flush Q1 from the cache by adding an out-of-order chunk to t1
|
||||
insert into t1 select reverse(a) from t1;
|
||||
show status like 'Qcache_%_blocks';
|
||||
|
||||
# Now the cache looks like (14K free)(14K for Q2)(20K free)
|
||||
|
||||
# Load our new data into the query cache
|
||||
--disable_result_log
|
||||
select a from t1; # Q3
|
||||
--enable_result_log
|
||||
show status like 'Qcache_%_blocks';
|
||||
|
||||
# Now the cache should be like (14K for Q3)(14K for Q2)(14K for Q3)(6K free)
|
||||
|
||||
# Note that Q3 is split across two chunks!
|
||||
|
||||
# Load Q3 from the cache, and actually pay attention to the results
|
||||
select a from t1;
|
||||
|
||||
flush query cache;
|
||||
|
||||
drop table t1, t2;
|
||||
|
||||
set GLOBAL query_cache_size=0;
|
||||
|
|
|
@ -144,7 +144,7 @@ int load_defaults(const char *conf_file, const char **groups,
|
|||
int *argc, char ***argv)
|
||||
{
|
||||
DYNAMIC_ARRAY args;
|
||||
const char **dirs, *forced_default_file;
|
||||
const char **dirs, *forced_default_file, *forced_extra_defaults;
|
||||
TYPELIB group;
|
||||
my_bool found_print_defaults=0;
|
||||
uint args_used=0;
|
||||
|
@ -174,13 +174,14 @@ int load_defaults(const char *conf_file, const char **groups,
|
|||
}
|
||||
|
||||
get_defaults_files(*argc, *argv,
|
||||
(char **)&forced_default_file, &defaults_extra_file);
|
||||
(char **)&forced_default_file,
|
||||
(char **)&forced_extra_defaults);
|
||||
if (forced_default_file)
|
||||
forced_default_file= strchr(forced_default_file,'=')+1;
|
||||
if (defaults_extra_file)
|
||||
defaults_extra_file= strchr(defaults_extra_file,'=')+1;
|
||||
if (forced_extra_defaults)
|
||||
defaults_extra_file= strchr(forced_extra_defaults,'=')+1;
|
||||
|
||||
args_used+= (forced_default_file ? 1 : 0) + (defaults_extra_file ? 1 : 0);
|
||||
args_used+= (forced_default_file ? 1 : 0) + (forced_extra_defaults ? 1 : 0);
|
||||
|
||||
group.count=0;
|
||||
group.name= "defaults";
|
||||
|
|
|
@ -1933,6 +1933,11 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block,
|
|||
type = Query_cache_block::RES_CONT;
|
||||
} while (block != *result_block);
|
||||
#else
|
||||
/*
|
||||
Set type of first block, emb_store_querycache_result() will handle
|
||||
the others.
|
||||
*/
|
||||
(*result_block)->type= type;
|
||||
Querycache_stream qs(*result_block, headers_len);
|
||||
emb_store_querycache_result(&qs, (THD*)data);
|
||||
#endif /*!EMBEDDED_LIBRARY*/
|
||||
|
|
|
@ -449,7 +449,7 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
|
|||
uc->user_resources.connections <= uc->conn_per_hour)
|
||||
{
|
||||
net_printf(thd, ER_USER_LIMIT_REACHED, uc->user,
|
||||
"max_connections",
|
||||
"max_connections_per_hour",
|
||||
(long) uc->user_resources.connections);
|
||||
error=1;
|
||||
goto end;
|
||||
|
|
|
@ -2281,6 +2281,8 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
|||
reg_ext, NullS);
|
||||
/* Resolve symlinks (for windows) */
|
||||
fn_format(src_path, src_path, "", "", MYF(MY_UNPACK_FILENAME));
|
||||
if (lower_case_table_names)
|
||||
my_casedn_str(files_charset_info, src_path);
|
||||
if (access(src_path, F_OK))
|
||||
{
|
||||
my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#define VER "2.1"
|
||||
#define MAX_TEST_QUERY_LENGTH 300 /* MAX QUERY BUFFER LENGTH */
|
||||
#define MAX_SERVER_ARGS 64
|
||||
|
||||
/* set default options */
|
||||
static int opt_testcase = 0;
|
||||
|
@ -48,6 +49,18 @@ static unsigned int test_count= 0;
|
|||
static unsigned int opt_count= 0;
|
||||
static unsigned int iter_count= 0;
|
||||
|
||||
static const char *opt_basedir= "./";
|
||||
|
||||
static int embedded_server_arg_count= 0;
|
||||
static char *embedded_server_args[MAX_SERVER_ARGS];
|
||||
|
||||
static const char *embedded_server_groups[]= {
|
||||
"server",
|
||||
"embedded",
|
||||
"mysql_client_test_SERVER",
|
||||
NullS
|
||||
};
|
||||
|
||||
static time_t start_time, end_time;
|
||||
static double total_time;
|
||||
|
||||
|
@ -93,6 +106,8 @@ static void client_disconnect();
|
|||
|
||||
#define DIE_UNLESS(expr) \
|
||||
((void) ((expr) ? 0 : (die(__FILE__, __LINE__, #expr), 0)))
|
||||
#define DIE(expr) \
|
||||
die(__FILE__, __LINE__, #expr)
|
||||
|
||||
void die(const char *file, int line, const char *expr)
|
||||
{
|
||||
|
@ -11617,7 +11632,7 @@ static void test_bug7990()
|
|||
|
||||
static void test_bug8378()
|
||||
{
|
||||
#ifdef HAVE_CHARSET_gbk
|
||||
#if defined(HAVE_CHARSET_gbk) && !defined(EMBEDDED_LIBRARY)
|
||||
MYSQL *lmysql;
|
||||
char out[9]; /* strlen(TEST_BUG8378)*2+1 */
|
||||
int len;
|
||||
|
@ -11664,6 +11679,8 @@ static char **defaults_argv;
|
|||
|
||||
static struct my_option client_test_long_options[] =
|
||||
{
|
||||
{"basedir", 'b', "Basedir for tests.", (gptr*) &opt_basedir,
|
||||
(gptr*) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"count", 't', "Number of times test to be executed", (char **) &opt_count,
|
||||
(char **) &opt_count, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0},
|
||||
{"database", 'D', "Database to use", (char **) &opt_db, (char **) &opt_db,
|
||||
|
@ -11679,6 +11696,8 @@ static struct my_option client_test_long_options[] =
|
|||
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"port", 'P', "Port number to use for connection", (char **) &opt_port,
|
||||
(char **) &opt_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"server-arg", 'A', "Send embedded server this as a parameter.",
|
||||
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"show-tests", 'T', "Show all tests' names", 0, 0, 0, GET_NO_ARG, NO_ARG,
|
||||
0, 0, 0, 0, 0, 0},
|
||||
{"silent", 's', "Be more silent", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0,
|
||||
|
@ -11899,6 +11918,25 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||
else
|
||||
opt_silent++;
|
||||
break;
|
||||
case 'A':
|
||||
/*
|
||||
When the embedded server is being tested, the test suite needs to be
|
||||
able to pass command-line arguments to the embedded server so it can
|
||||
locate the language files and data directory. The test suite
|
||||
(mysql-test-run) never uses config files, just command-line options.
|
||||
*/
|
||||
if (!embedded_server_arg_count)
|
||||
{
|
||||
embedded_server_arg_count= 1;
|
||||
embedded_server_args[0]= (char*) "";
|
||||
}
|
||||
if (embedded_server_arg_count == MAX_SERVER_ARGS-1 ||
|
||||
!(embedded_server_args[embedded_server_arg_count++]=
|
||||
my_strdup(argument, MYF(MY_FAE))))
|
||||
{
|
||||
DIE("Can't use server argument");
|
||||
}
|
||||
break;
|
||||
case 'T':
|
||||
{
|
||||
struct my_tests_st *fptr;
|
||||
|
@ -11967,6 +12005,11 @@ int main(int argc, char **argv)
|
|||
defaults_argv= argv;
|
||||
get_options(&argc, &argv);
|
||||
|
||||
if (mysql_server_init(embedded_server_arg_count,
|
||||
embedded_server_args,
|
||||
(char**) embedded_server_groups))
|
||||
DIE("Can't initialize MySQL server");
|
||||
|
||||
client_connect(); /* connect to server */
|
||||
|
||||
total_time= 0;
|
||||
|
@ -12019,6 +12062,12 @@ int main(int argc, char **argv)
|
|||
client_disconnect(); /* disconnect from server */
|
||||
free_defaults(defaults_argv);
|
||||
print_test_output();
|
||||
|
||||
while (embedded_server_arg_count > 1)
|
||||
my_free(embedded_server_args[--embedded_server_arg_count],MYF(0));
|
||||
|
||||
mysql_server_end();
|
||||
|
||||
my_end(0);
|
||||
|
||||
exit(0);
|
||||
|
|
Loading…
Reference in a new issue