Commit 21bef0ed authored by unknown's avatar unknown

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

into mysql.com:/home/my/mysql-4.1

parents c331a891 b321b7c0
...@@ -227,11 +227,12 @@ typedef struct { ...@@ -227,11 +227,12 @@ typedef struct {
} COMMANDS; } COMMANDS;
static COMMANDS commands[] = { static COMMANDS commands[] = {
{ "help", 'h', com_help, 1, "Display this help." },
{ "?", '?', com_help, 1, "Synonym for `help'." }, { "?", '?', com_help, 1, "Synonym for `help'." },
{ "clear", 'c', com_clear, 0, "Clear command."}, { "clear", 'c', com_clear, 0, "Clear command."},
{ "connect",'r', com_connect,1, { "connect",'r', com_connect,1,
"Reconnect to the server. Optional arguments are db and host." }, "Reconnect to the server. Optional arguments are db and host." },
{ "delimiter", 'd', com_delimiter, 1,
"Set query delimiter. " },
#ifdef USE_POPEN #ifdef USE_POPEN
{ "edit", 'e', com_edit, 0, "Edit command with $EDITOR."}, { "edit", 'e', com_edit, 0, "Edit command with $EDITOR."},
#endif #endif
...@@ -239,6 +240,7 @@ static COMMANDS commands[] = { ...@@ -239,6 +240,7 @@ static COMMANDS commands[] = {
"Send command to mysql server, display result vertically."}, "Send command to mysql server, display result vertically."},
{ "exit", 'q', com_quit, 0, "Exit mysql. Same as quit."}, { "exit", 'q', com_quit, 0, "Exit mysql. Same as quit."},
{ "go", 'g', com_go, 0, "Send command to mysql server." }, { "go", 'g', com_go, 0, "Send command to mysql server." },
{ "help", 'h', com_help, 1, "Display this help." },
#ifdef USE_POPEN #ifdef USE_POPEN
{ "nopager",'n', com_nopager,0, "Disable pager, print to stdout." }, { "nopager",'n', com_nopager,0, "Disable pager, print to stdout." },
#endif #endif
...@@ -261,8 +263,6 @@ static COMMANDS commands[] = { ...@@ -261,8 +263,6 @@ static COMMANDS commands[] = {
"Set outfile [to_outfile]. Append everything into given outfile." }, "Set outfile [to_outfile]. Append everything into given outfile." },
{ "use", 'u', com_use, 1, { "use", 'u', com_use, 1,
"Use another database. Takes database name as argument." }, "Use another database. Takes database name as argument." },
{ "delimiter", 'd', com_delimiter, 1,
"Set query delimiter. " },
/* Get bash-like expansion for some commands */ /* Get bash-like expansion for some commands */
{ "create table", 0, 0, 0, ""}, { "create table", 0, 0, 0, ""},
{ "create database", 0, 0, 0, ""}, { "create database", 0, 0, 0, ""},
...@@ -1577,8 +1577,8 @@ static int ...@@ -1577,8 +1577,8 @@ static int
com_help(String *buffer __attribute__((unused)), com_help(String *buffer __attribute__((unused)),
char *line __attribute__((unused))) char *line __attribute__((unused)))
{ {
reg1 int i; reg1 int i, j;
char * help_arg= strchr(line,' '); char * help_arg= strchr(line,' '), buff[32], *end;
if (help_arg) if (help_arg)
return com_server_help(buffer,line,help_arg+1); return com_server_help(buffer,line,help_arg+1);
...@@ -1591,8 +1591,11 @@ com_help(String *buffer __attribute__((unused)), ...@@ -1591,8 +1591,11 @@ com_help(String *buffer __attribute__((unused)),
put_info("Note that all text commands must be first on line and end with ';'",INFO_INFO); put_info("Note that all text commands must be first on line and end with ';'",INFO_INFO);
for (i = 0; commands[i].name; i++) for (i = 0; commands[i].name; i++)
{ {
end= strmov(buff, commands[i].name);
for (j= strlen(commands[i].name); j < 10; j++)
end= strmov(end, " ");
if (commands[i].func) if (commands[i].func)
tee_fprintf(stdout, "%s\t(\\%c)\t%s\n", commands[i].name, tee_fprintf(stdout, "%s(\\%c) %s\n", buff,
commands[i].cmd_char, commands[i].doc); commands[i].cmd_char, commands[i].doc);
} }
if (connected && mysql_get_server_version(&mysql) >= 40100) if (connected && mysql_get_server_version(&mysql) >= 40100)
...@@ -2433,8 +2436,9 @@ com_delimiter(String *buffer __attribute__((unused)), char *line) ...@@ -2433,8 +2436,9 @@ com_delimiter(String *buffer __attribute__((unused)), char *line)
static int static int
com_use(String *buffer __attribute__((unused)), char *line) com_use(String *buffer __attribute__((unused)), char *line)
{ {
char *tmp; char *tmp, buff[FN_REFLEN + 1];
char buff[256]; MYSQL_RES *res;
MYSQL_ROW row;
bzero(buff, sizeof(buff)); bzero(buff, sizeof(buff));
strmov(buff, line); strmov(buff, line);
...@@ -2444,6 +2448,31 @@ com_use(String *buffer __attribute__((unused)), char *line) ...@@ -2444,6 +2448,31 @@ com_use(String *buffer __attribute__((unused)), char *line)
put_info("USE must be followed by a database name", INFO_ERROR); put_info("USE must be followed by a database name", INFO_ERROR);
return 0; return 0;
} }
/*
We need to recheck the current database, because it may change
under our feet, for example if DROP DATABASE or RENAME DATABASE
(latter one not yet available by the time the comment was written)
*/
current_db= 0; // Let's reset current_db, assume it's gone
/*
We don't care about in case of an error below because current_db
was just set to 0.
*/
if (!mysql_query(&mysql, "SELECT DATABASE()") &&
(res= mysql_use_result(&mysql)))
{
row= mysql_fetch_row(res);
if (row[0] &&
(!current_db || cmp_database(charset_info, current_db, row[0])))
{
my_free(current_db, MYF(MY_ALLOW_ZERO_PTR));
current_db= my_strdup(row[0], MYF(MY_WME));
}
(void) mysql_fetch_row(res); // Read eof
mysql_free_result(res);
}
if (!current_db || cmp_database(charset_info, current_db, tmp)) if (!current_db || cmp_database(charset_info, current_db, tmp))
{ {
if (one_database) if (one_database)
......
...@@ -32,6 +32,4 @@ ...@@ -32,6 +32,4 @@
#undef MYSQL_SERVER_SUFFIX #undef MYSQL_SERVER_SUFFIX
#define MYSQL_SERVER_SUFFIX "-embedded" #define MYSQL_SERVER_SUFFIX "-embedded"
#undef HAVE_QUERY_CACHE /* Cache dosn't work yet */
#endif /* EMBEDDED_LIBRARY */ #endif /* EMBEDDED_LIBRARY */
...@@ -15,6 +15,8 @@ Created 9/20/1997 Heikki Tuuri ...@@ -15,6 +15,8 @@ Created 9/20/1997 Heikki Tuuri
#include "hash0hash.h" #include "hash0hash.h"
#include "log0log.h" #include "log0log.h"
extern ibool recv_replay_file_ops;
/*********************************************************************** /***********************************************************************
Reads the checkpoint info needed in hot backup. */ Reads the checkpoint info needed in hot backup. */
......
...@@ -34,6 +34,11 @@ Created 9/20/1997 Heikki Tuuri ...@@ -34,6 +34,11 @@ Created 9/20/1997 Heikki Tuuri
#include "dict0boot.h" #include "dict0boot.h"
#include "fil0fil.h" #include "fil0fil.h"
/* This is set to FALSE if the backup was originally taken with the
ibbackup --include regexp option: then we do not want to create tables in
directories which were not included */
ibool recv_replay_file_ops = TRUE;
/* Log records are stored in the hash table in chunks at most of this size; /* Log records are stored in the hash table in chunks at most of this size;
this must be less than UNIV_PAGE_SIZE as it is stored in the buffer pool */ this must be less than UNIV_PAGE_SIZE as it is stored in the buffer pool */
#define RECV_DATA_BLOCK_SIZE (MEM_MAX_ALLOC_IN_BUF - sizeof(recv_data_t)) #define RECV_DATA_BLOCK_SIZE (MEM_MAX_ALLOC_IN_BUF - sizeof(recv_data_t))
...@@ -1974,18 +1979,21 @@ recv_parse_log_recs( ...@@ -1974,18 +1979,21 @@ recv_parse_log_recs(
|| type == MLOG_FILE_RENAME || type == MLOG_FILE_RENAME
|| type == MLOG_FILE_DELETE)) { || type == MLOG_FILE_DELETE)) {
#ifdef UNIV_HOTBACKUP #ifdef UNIV_HOTBACKUP
/* In ibbackup --apply-log, replay an .ibd file if (recv_replay_file_ops) {
operation, if possible; note that
fil_path_to_mysql_datadir is set in ibbackup to /* In ibbackup --apply-log, replay an .ibd file
point to the datadir we should use there */ operation, if possible; note that
fil_path_to_mysql_datadir is set in ibbackup to
point to the datadir we should use there */
if (NULL == fil_op_log_parse_or_replay(body, end_ptr, if (NULL == fil_op_log_parse_or_replay(body,
type, TRUE, space)) { end_ptr, type, TRUE, space)) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: file op log record of type %lu space %lu not complete in\n" "InnoDB: Error: file op log record of type %lu space %lu not complete in\n"
"InnoDB: the replay phase. Path %s\n", (ulint)type, space, (char*)(body + 2)); "InnoDB: the replay phase. Path %s\n", (ulint)type, space, (char*)(body + 2));
ut_a(0); ut_a(0);
}
} }
#endif #endif
/* In normal mysqld crash recovery we do not try to /* In normal mysqld crash recovery we do not try to
......
...@@ -1447,7 +1447,7 @@ row_create_table_for_mysql( ...@@ -1447,7 +1447,7 @@ row_create_table_for_mysql(
fprintf(stderr, fprintf(stderr,
" InnoDB: Error: table %s already exists in InnoDB internal\n" " InnoDB: Error: table %s already exists in InnoDB internal\n"
"InnoDB: data dictionary. Have you deleted the .frm file\n" "InnoDB: data dictionary. Have you deleted the .frm file\n"
"InnoDB: and not used DROPT ABLE? Have you used DROP DATABASE\n" "InnoDB: and not used DROP TABLE? Have you used DROP DATABASE\n"
"InnoDB: for InnoDB tables in MySQL version <= 3.23.43?\n" "InnoDB: for InnoDB tables in MySQL version <= 3.23.43?\n"
"InnoDB: See the Restrictions section of the InnoDB manual.\n", "InnoDB: See the Restrictions section of the InnoDB manual.\n",
table->name); table->name);
......
...@@ -534,6 +534,8 @@ row_purge_parse_undo_rec( ...@@ -534,6 +534,8 @@ row_purge_parse_undo_rec(
node->table = NULL; node->table = NULL;
row_mysql_unfreeze_data_dictionary(trx);
return(FALSE); return(FALSE);
} }
......
...@@ -1603,6 +1603,19 @@ NetWare. */ ...@@ -1603,6 +1603,19 @@ NetWare. */
fflush(stderr); fflush(stderr);
if (trx_doublewrite_must_reset_space_ids) { if (trx_doublewrite_must_reset_space_ids) {
/* Actually, we did not change the undo log format between
4.0 and 4.1.1, and we would not need to run purge to
completion. Note also that the purge algorithm in 4.1.1
can process the the history list again even after a full
purge, because our algorithm does not cut the end of the
history list in all cases so that it would become empty
after a full purge. That mean that we may purge 4.0 type
undo log even after this phase.
The insert buffer record format changed between 4.0 and
4.1.1. It is essential that the insert buffer is emptied
here! */
fprintf(stderr, fprintf(stderr,
"InnoDB: You are upgrading to an InnoDB version which allows multiple\n" "InnoDB: You are upgrading to an InnoDB version which allows multiple\n"
"InnoDB: tablespaces. Wait that purge and insert buffer merge run to\n" "InnoDB: tablespaces. Wait that purge and insert buffer merge run to\n"
...@@ -1625,8 +1638,9 @@ NetWare. */ ...@@ -1625,8 +1638,9 @@ NetWare. */
fprintf(stderr, fprintf(stderr,
"InnoDB: You have now successfully upgraded to the multiple tablespaces\n" "InnoDB: You have now successfully upgraded to the multiple tablespaces\n"
"InnoDB: format. You should not downgrade again to an earlier version of\n" "InnoDB: format. You should NOT DOWNGRADE again to an earlier version of\n"
"InnoDB: InnoDB!\n"); "InnoDB: InnoDB! But if you absolutely need to downgrade, see section 4.6 of\n"
"InnoDB: http://www.innodb.com/ibman.php for instructions.\n");
} }
if (srv_force_recovery == 0) { if (srv_force_recovery == 0) {
......
...@@ -33,10 +33,10 @@ INCLUDES= @MT_INCLUDES@ @bdb_includes@ -I$(top_srcdir)/include \ ...@@ -33,10 +33,10 @@ INCLUDES= @MT_INCLUDES@ @bdb_includes@ -I$(top_srcdir)/include \
noinst_LIBRARIES = libmysqld_int.a noinst_LIBRARIES = libmysqld_int.a
pkglib_LIBRARIES = libmysqld.a pkglib_LIBRARIES = libmysqld.a
SUBDIRS = . examples SUBDIRS = . examples
libmysqld_sources= libmysqld.c lib_sql.cc libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc
libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c
noinst_HEADERS = embedded_priv.h noinst_HEADERS = embedded_priv.h emb_qcache.h
sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
ha_innodb.cc ha_berkeley.cc ha_heap.cc ha_isam.cc ha_isammrg.cc \ ha_innodb.cc ha_berkeley.cc ha_heap.cc ha_isam.cc ha_isammrg.cc \
......
This diff is collapsed.
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
class Querycache_stream
{
byte *cur_data;
byte *data_end;
Query_cache_block *block;
uint headers_len;
public:
#ifndef DBUG_OFF
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();
#ifndef DBUG_OFF
stored_size= 0;
#endif
}
void use_next_block()
{
cur_data= ((byte*)block)+headers_len;
data_end= cur_data + (block->used-headers_len);
}
void store_char(char c);
void store_short(ushort s);
void store_int(uint i);
void store_ll(ulonglong ll);
void store_str_only(const char *str, uint str_len);
void store_str(const char *str, uint str_len);
void store_safe_str(const char *str, uint str_len);
char load_char();
ushort load_short();
uint load_int();
ulonglong load_ll();
void load_str_only(char *buffer, uint str_len);
char *load_str(MEM_ROOT *alloc, uint *str_len);
int load_safe_str(MEM_ROOT *alloc, char **str, uint *str_len);
int load_column(MEM_ROOT *alloc, char **column);
};
uint emb_count_querycache_size(THD *thd);
int emb_load_querycache_result(THD *thd, Querycache_stream *src);
void emb_store_querycache_result(Querycache_stream *dst, THD* thd);
...@@ -23,9 +23,10 @@ ...@@ -23,9 +23,10 @@
#include <my_pthread.h> #include <my_pthread.h>
C_MODE_START C_MODE_START
extern void lib_connection_phase(NET *net, int phase); void lib_connection_phase(NET *net, int phase);
extern void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db); void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db);
extern void *create_embedded_thd(int client_flag, char *db); void *create_embedded_thd(int client_flag, char *db);
extern MYSQL_METHODS embedded_methods; int check_embedded_connection(MYSQL *mysql);
void free_old_query(MYSQL *mysql); void free_old_query(MYSQL *mysql);
extern MYSQL_METHODS embedded_methods;
C_MODE_END C_MODE_END
...@@ -478,7 +478,17 @@ void *create_embedded_thd(int client_flag, char *db) ...@@ -478,7 +478,17 @@ void *create_embedded_thd(int client_flag, char *db)
return thd; return thd;
} }
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifdef NO_EMBEDDED_ACCESS_CHECKS
int check_embedded_connection(MYSQL *mysql)
{
THD *thd= (THD*)mysql->thd;
thd->host= (char*)my_localhost;
thd->host_or_ip= thd->host;
thd->user= mysql->user;
return 0;
}
#else
int check_embedded_connection(MYSQL *mysql) int check_embedded_connection(MYSQL *mysql)
{ {
THD *thd= (THD*)mysql->thd; THD *thd= (THD*)mysql->thd;
...@@ -486,9 +496,13 @@ int check_embedded_connection(MYSQL *mysql) ...@@ -486,9 +496,13 @@ int check_embedded_connection(MYSQL *mysql)
char scramble_buff[SCRAMBLE_LENGTH]; char scramble_buff[SCRAMBLE_LENGTH];
int passwd_len; int passwd_len;
thd->host= mysql->options.client_ip ? if (mysql->options.client_ip)
mysql->options.client_ip : (char*)my_localhost; {
thd->ip= thd->host; thd->host= mysql->options.client_ip;
thd->ip= thd->host;
}
else
thd->host= (char*)my_localhost;
thd->host_or_ip= thd->host; thd->host_or_ip= thd->host;
if (acl_check_host(thd->host,thd->ip)) if (acl_check_host(thd->host,thd->ip))
...@@ -565,6 +579,9 @@ bool Protocol::send_fields(List<Item> *list, uint flag) ...@@ -565,6 +579,9 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
client_field->org_name_length= strlen(client_field->org_name); client_field->org_name_length= strlen(client_field->org_name);
client_field->org_table_length= strlen(client_field->org_table); client_field->org_table_length= strlen(client_field->org_table);
client_field->charsetnr= server_field.charsetnr; client_field->charsetnr= server_field.charsetnr;
client_field->catalog= strdup_root(field_alloc, "std");
client_field->catalog_length= 3;
if (INTERNAL_NUM_FIELD(client_field)) if (INTERNAL_NUM_FIELD(client_field))
client_field->flags|= NUM_FLAG; client_field->flags|= NUM_FLAG;
...@@ -575,9 +592,15 @@ bool Protocol::send_fields(List<Item> *list, uint flag) ...@@ -575,9 +592,15 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
String tmp(buff, sizeof(buff), default_charset_info), *res; String tmp(buff, sizeof(buff), default_charset_info), *res;
if (!(res=item->val_str(&tmp))) if (!(res=item->val_str(&tmp)))
{
client_field->def= strdup_root(field_alloc, ""); client_field->def= strdup_root(field_alloc, "");
client_field->def_length= 0;
}
else else
{
client_field->def= strdup_root(field_alloc, tmp.ptr()); client_field->def= strdup_root(field_alloc, tmp.ptr());
client_field->def_length= tmp.length();
}
} }
else else
client_field->def=0; client_field->def=0;
......
...@@ -124,17 +124,14 @@ static inline int mysql_init_charset(MYSQL *mysql) ...@@ -124,17 +124,14 @@ static inline int mysql_init_charset(MYSQL *mysql)
return 0; return 0;
} }
int check_embedded_connection(MYSQL *mysql);
MYSQL * STDCALL MYSQL * STDCALL
mysql_real_connect(MYSQL *mysql,const char *host, const char *user, mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db, const char *passwd, const char *db,
uint port, const char *unix_socket,ulong client_flag) uint port, const char *unix_socket,ulong client_flag)
{ {
char *db_name; char *db_name;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
char name_buff[USERNAME_LENGTH]; char name_buff[USERNAME_LENGTH];
#endif
DBUG_ENTER("mysql_real_connect"); DBUG_ENTER("mysql_real_connect");
DBUG_PRINT("enter",("host: %s db: %s user: %s", DBUG_PRINT("enter",("host: %s db: %s user: %s",
host ? host : "(Null)", host ? host : "(Null)",
...@@ -165,10 +162,10 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, ...@@ -165,10 +162,10 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
if (!db || !db[0]) if (!db || !db[0])
db=mysql->options.db; db=mysql->options.db;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!user || !user[0]) if (!user || !user[0])
user=mysql->options.user; user=mysql->options.user;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!passwd) if (!passwd)
{ {
passwd=mysql->options.password; passwd=mysql->options.password;
...@@ -177,16 +174,18 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, ...@@ -177,16 +174,18 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
passwd=getenv("MYSQL_PWD"); /* get it from environment */ passwd=getenv("MYSQL_PWD"); /* get it from environment */
#endif #endif
} }
mysql->passwd= passwd ? my_strdup(passwd,MYF(0)) : NULL;
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
if (!user || !user[0]) if (!user || !user[0])
{ {
read_user_name(name_buff); read_user_name(name_buff);
if (!name_buff[0]) if (name_buff[0])
user= name_buff; user= name_buff;
} }
if (!user)
user= "";
mysql->user=my_strdup(user,MYF(0)); mysql->user=my_strdup(user,MYF(0));
mysql->passwd= passwd ? my_strdup(passwd,MYF(0)) : NULL;
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
port=0; port=0;
unix_socket=0; unix_socket=0;
...@@ -196,10 +195,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, ...@@ -196,10 +195,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
init_embedded_mysql(mysql, client_flag, db_name); init_embedded_mysql(mysql, client_flag, db_name);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_embedded_connection(mysql)) if (check_embedded_connection(mysql))
goto error; goto error;
#endif
if (mysql_init_charset(mysql)) if (mysql_init_charset(mysql))
goto error; goto error;
......
...@@ -120,3 +120,45 @@ select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i; ...@@ -120,3 +120,45 @@ select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i;
1 3 2 0 1 3 2 0
3 6 3 0 3 6 3 0
drop table t1; drop table t1;
set @a=_latin2'test';
select charset(@a),collation(@a),coercibility(@a);
charset(@a) collation(@a) coercibility(@a)
latin2 latin2_general_ci 3
select @a=_latin2'TEST';
@a=_latin2'TEST'
1
select @a=_latin2'TEST' collate latin2_bin;
@a=_latin2'TEST' collate latin2_bin
0
set @a=_latin2'test' collate latin2_general_ci;
select charset(@a),collation(@a),coercibility(@a);
charset(@a) collation(@a) coercibility(@a)
latin2 latin2_general_ci 0
select @a=_latin2'TEST';
@a=_latin2'TEST'
1
select @a=_latin2'TEST' collate latin2_bin;
ERROR HY000: Illegal mix of collations (latin2_general_ci,EXPLICIT) and (latin2_bin,EXPLICIT) for operation '='
select charset(@a:=_latin2'test');
charset(@a:=_latin2'test')
latin2
select collation(@a:=_latin2'test');
collation(@a:=_latin2'test')
latin2_general_ci
select coercibility(@a:=_latin2'test');
coercibility(@a:=_latin2'test')
3
select collation(@a:=_latin2'test' collate latin2_bin);
collation(@a:=_latin2'test' collate latin2_bin)
latin2_bin
select coercibility(@a:=_latin2'test' collate latin2_bin);
coercibility(@a:=_latin2'test' collate latin2_bin)
0
select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST';
(@a:=_latin2'test' collate latin2_bin) = _latin2'TEST'
0
select charset(@a),collation(@a),coercibility(@a);
charset(@a) collation(@a) coercibility(@a)
latin2 latin2_bin 0
select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST' collate latin2_general_ci;
ERROR HY000: Illegal mix of collations (latin2_bin,EXPLICIT) and (latin2_general_ci,EXPLICIT) for operation '='
...@@ -71,3 +71,31 @@ select @a:=0; select @a, @a:=@a+count(*), count(*), @a from t1 group by i; ...@@ -71,3 +71,31 @@ select @a:=0; select @a, @a:=@a+count(*), count(*), @a from t1 group by i;
select @a:=0; select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i; select @a:=0; select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i;
drop table t1; drop table t1;
#
# Bug #2244: User variables didn't copy collation and derivation
# attributes from values they were initialized to.
#
set @a=_latin2'test';
select charset(@a),collation(@a),coercibility(@a);
select @a=_latin2'TEST';
select @a=_latin2'TEST' collate latin2_bin;
set @a=_latin2'test' collate latin2_general_ci;
select charset(@a),collation(@a),coercibility(@a);
select @a=_latin2'TEST';
--error 1266
select @a=_latin2'TEST' collate latin2_bin;
#
# Check the same invoking Item_set_user_var
#
select charset(@a:=_latin2'test');
select collation(@a:=_latin2'test');
select coercibility(@a:=_latin2'test');
select collation(@a:=_latin2'test' collate latin2_bin);
select coercibility(@a:=_latin2'test' collate latin2_bin);
select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST';
select charset(@a),collation(@a),coercibility(@a);
--error 1266
select (@a:=_latin2'test' collate latin2_bin) = _latin2'TEST' collate latin2_general_ci;
...@@ -2163,6 +2163,7 @@ bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables, ...@@ -2163,6 +2163,7 @@ bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables,
is different from query_id). is different from query_id).
*/ */
entry->update_query_id= thd->query_id; entry->update_query_id= thd->query_id;
entry->collation.set(args[0]->collation);
cached_result_type= args[0]->result_type(); cached_result_type= args[0]->result_type();
return 0; return 0;
} }
...@@ -2174,6 +2175,7 @@ Item_func_set_user_var::fix_length_and_dec() ...@@ -2174,6 +2175,7 @@ Item_func_set_user_var::fix_length_and_dec()
maybe_null=args[0]->maybe_null; maybe_null=args[0]->maybe_null;
max_length=args[0]->max_length; max_length=args[0]->max_length;
decimals=args[0]->decimals; decimals=args[0]->decimals;
collation.set(args[0]->collation);
} }
...@@ -2488,7 +2490,9 @@ void Item_func_get_user_var::fix_length_and_dec() ...@@ -2488,7 +2490,9 @@ void Item_func_get_user_var::fix_length_and_dec()
if (!(var_entry= get_variable(&thd->user_vars, name, 0))) if (!(var_entry= get_variable(&thd->user_vars, name, 0)))
null_value= 1; null_value= 1;
else
collation.set(var_entry->collation);
if (!(opt_bin_log && is_update_query(thd->lex->sql_command))) if (!(opt_bin_log && is_update_query(thd->lex->sql_command)))
return; return;
......
<?xml version='1.0' encoding="utf-8"?> <?xml version='1.0' encoding="utf-8"?>
<charsets max-id="93"> <charsets max-id="94">
<description> <description>
This file lists all of the available character sets. This file lists all of the available character sets.
...@@ -100,6 +100,7 @@ To make maintaining easier please: ...@@ -100,6 +100,7 @@ To make maintaining easier please:
<collation name="latin1_swedish_ci" id="8" order="Finnish, Swedish" flag="primary"/> <collation name="latin1_swedish_ci" id="8" order="Finnish, Swedish" flag="primary"/>
<collation name="latin1_danish_ci" id="15" order="Danish"/> <collation name="latin1_danish_ci" id="15" order="Danish"/>
<collation name="latin1_german2_ci" id="31" order="German Phonebook" flag="compiled"/> <collation name="latin1_german2_ci" id="31" order="German Phonebook" flag="compiled"/>
<collation name="latin1_spanish_ci" id="94" order="Spanish"/>
<collation name="latin1_bin" id="47" order="Binary"> <collation name="latin1_bin" id="47" order="Binary">
<flag>binary</flag> <flag>binary</flag>
<flag>compiled</flag> <flag>compiled</flag>
......
...@@ -209,6 +209,27 @@ ...@@ -209,6 +209,27 @@
</collation> </collation>
<collation name="latin1_spanish_ci">
<map>
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 41 51 53 57 5B 65 67 69 6B 75 77 79 7B 7D 81
8F 91 93 95 98 9A A4 A6 A8 AA AF B3 B4 B5 B6 B7
B8 41 51 53 57 5B 65 67 69 6B 75 77 79 7B 7D 81
8F 91 93 95 98 9A A4 A6 A8 AA AF B9 BA BB BC BF
C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF
D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF
E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF
41 41 41 41 41 41 41 53 5B 5B 5B 5B 6B 6B 6B 6B
57 7F 81 81 81 81 81 BD 81 9A 9A 9A 9A AA B1 97
41 41 41 41 41 41 41 53 5B 5B 5B 5B 6B 6B 6B 6B
57 7F 81 81 81 81 81 BE 81 9A 9A 9A 9A AA B1 AA
</map>
</collation>
</charset> </charset>
</charsets> </charsets>
...@@ -308,6 +308,10 @@ TODO list: ...@@ -308,6 +308,10 @@ TODO list:
#include "../myisammrg/myrg_def.h" #include "../myisammrg/myrg_def.h"
#endif #endif
#ifdef EMBEDDED_LIBRARY
#include "emb_qcache.h"
#endif
#if defined(EXTRA_DEBUG) && !defined(DBUG_OFF) #if defined(EXTRA_DEBUG) && !defined(DBUG_OFF)
#define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \ #define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \
pthread_mutex_lock(M);} pthread_mutex_lock(M);}
...@@ -646,7 +650,7 @@ void query_cache_abort(NET *net) ...@@ -646,7 +650,7 @@ void query_cache_abort(NET *net)
} }
void query_cache_end_of_result(NET *net) void query_cache_end_of_result(THD *thd)
{ {
DBUG_ENTER("query_cache_end_of_result"); DBUG_ENTER("query_cache_end_of_result");
...@@ -655,11 +659,15 @@ void query_cache_end_of_result(NET *net) ...@@ -655,11 +659,15 @@ void query_cache_end_of_result(NET *net)
if (query_cache.query_cache_size == 0) DBUG_VOID_RETURN; if (query_cache.query_cache_size == 0) DBUG_VOID_RETURN;
#endif #endif
if (net->query_cache_query != 0) // Quick check on unlocked structure if (thd->net.query_cache_query != 0) // Quick check on unlocked structure
{ {
#ifdef EMBEDDED_LIBRARY
query_cache_insert(&thd->net, (byte*)thd,
emb_count_querycache_size(thd));
#endif
STRUCT_LOCK(&query_cache.structure_guard_mutex); STRUCT_LOCK(&query_cache.structure_guard_mutex);
Query_cache_block *query_block = ((Query_cache_block*) Query_cache_block *query_block = ((Query_cache_block*)
net->query_cache_query); thd->net.query_cache_query);
if (query_block) if (query_block)
{ {
DUMP(&query_cache); DUMP(&query_cache);
...@@ -691,7 +699,7 @@ void query_cache_end_of_result(NET *net) ...@@ -691,7 +699,7 @@ void query_cache_end_of_result(NET *net)
// Cache was flushed or resized and query was deleted => do nothing // Cache was flushed or resized and query was deleted => do nothing
STRUCT_UNLOCK(&query_cache.structure_guard_mutex); STRUCT_UNLOCK(&query_cache.structure_guard_mutex);
} }
net->query_cache_query=0; thd->net.query_cache_query=0;
DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0);); DBUG_EXECUTE("check_querycache",query_cache.check_integrity(0););
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -1052,23 +1060,29 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length) ...@@ -1052,23 +1060,29 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
/* /*
Send cached result to client Send cached result to client
*/ */
#ifndef EMBEDDED_LIBRARY
do do
{ {
DBUG_PRINT("qcache", ("Results (len %lu, used %lu, headers %lu)", DBUG_PRINT("qcache", ("Results (len %lu, used %lu, headers %lu)",
result_block->length, result_block->used, result_block->length, result_block->used,
result_block->headers_len()+ result_block->headers_len()+
ALIGN_SIZE(sizeof(Query_cache_result)))); ALIGN_SIZE(sizeof(Query_cache_result))));
Query_cache_result *result = result_block->result(); Query_cache_result *result = result_block->result();
#ifndef EMBEDDED_LIBRARY /* TODO query cache in embedded library*/
if (net_real_write(&thd->net, result->data(), if (net_real_write(&thd->net, result->data(),
result_block->used - result_block->used -
result_block->headers_len() - result_block->headers_len() -
ALIGN_SIZE(sizeof(Query_cache_result)))) ALIGN_SIZE(sizeof(Query_cache_result))))
break; // Client aborted break; // Client aborted
#endif
result_block = result_block->next; result_block = result_block->next;
} while (result_block != first_result_block); } while (result_block != first_result_block);
#else
{
Querycache_stream qs(result_block, result_block->headers_len() +
ALIGN_SIZE(sizeof(Query_cache_result)));
emb_load_querycache_result(thd, &qs);
}
#endif /*!EMBEDDED_LIBRARY*/
thd->limit_found_rows = query->found_rows(); thd->limit_found_rows = query->found_rows();
...@@ -1804,18 +1818,23 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block, ...@@ -1804,18 +1818,23 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block,
Query_cache_block *block = *result_block; Query_cache_block *block = *result_block;
uint headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) + uint headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
ALIGN_SIZE(sizeof(Query_cache_result))); ALIGN_SIZE(sizeof(Query_cache_result)));
#ifndef EMBEDDED_LIBRARY
// Now fill list of blocks that created by allocate_data_chain // Now fill list of blocks that created by allocate_data_chain
do do
{ {
block->type = type; block->type = type;
ulong length = block->used - headers_len; ulong length = block->used - headers_len;
DBUG_PRINT("qcache", ("write %lu byte in block 0x%lx",length, DBUG_PRINT("qcache", ("write %lu byte in block 0x%lx",length,
(ulong)block)); (ulong)block));
memcpy((void*)(((byte*) block)+headers_len), (void*) rest, length); memcpy((void*)(((byte*) block)+headers_len), (void*) rest, length);
rest += length; rest += length;
block = block->next; block = block->next;
type = Query_cache_block::RES_CONT; type = Query_cache_block::RES_CONT;
} while (block != *result_block); } while (block != *result_block);
#else
Querycache_stream qs(*result_block, headers_len);
emb_store_querycache_result(&qs, (THD*)data);
#endif /*!EMBEDDED_LIBRARY*/
} }
else else
{ {
......
...@@ -392,7 +392,7 @@ class Query_cache ...@@ -392,7 +392,7 @@ class Query_cache
void destroy(); void destroy();
friend void query_cache_insert(NET *net, const char *packet, ulong length); friend void query_cache_insert(NET *net, const char *packet, ulong length);
friend void query_cache_end_of_result(NET *net); friend void query_cache_end_of_result(THD *thd);
friend void query_cache_abort(NET *net); friend void query_cache_abort(NET *net);
/* /*
...@@ -416,7 +416,7 @@ class Query_cache ...@@ -416,7 +416,7 @@ class Query_cache
extern Query_cache query_cache; extern Query_cache query_cache;
extern TYPELIB query_cache_type_typelib; extern TYPELIB query_cache_type_typelib;
void query_cache_end_of_result(NET *net); void query_cache_end_of_result(THD *thd);
void query_cache_abort(NET *net); void query_cache_abort(NET *net);
#endif #endif
...@@ -323,12 +323,14 @@ THD::~THD() ...@@ -323,12 +323,14 @@ THD::~THD()
#endif #endif
DBUG_PRINT("info", ("freeing host")); DBUG_PRINT("info", ("freeing host"));
#ifndef EMBEDDED_LIBRARY
if (host != my_localhost) // If not pointer to constant if (host != my_localhost) // If not pointer to constant
safeFree(host); safeFree(host);
if (user != delayed_user) if (user != delayed_user)
safeFree(user); safeFree(user);
safeFree(db);
safeFree(ip); safeFree(ip);
#endif
safeFree(db);
free_root(&warn_root,MYF(0)); free_root(&warn_root,MYF(0));
free_root(&transaction.mem_root,MYF(0)); free_root(&transaction.mem_root,MYF(0));
mysys_var=0; // Safety (shouldn't be needed) mysys_var=0; // Safety (shouldn't be needed)
......
...@@ -3877,7 +3877,7 @@ mysql_parse(THD *thd, char *inBuf, uint length) ...@@ -3877,7 +3877,7 @@ mysql_parse(THD *thd, char *inBuf, uint length)
else else
{ {
mysql_execute_command(thd); mysql_execute_command(thd);
query_cache_end_of_result(&thd->net); query_cache_end_of_result(thd);
} }
} }
} }
......
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