mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 05:22:25 +01:00
Merge bk-internal.mysql.com:/home/bk/mysql-4.1
into mysql.com:/home/my/mysql-4.1
This commit is contained in:
commit
f784f54c9c
22 changed files with 756 additions and 58 deletions
|
@ -227,11 +227,12 @@ typedef struct {
|
|||
} COMMANDS;
|
||||
|
||||
static COMMANDS commands[] = {
|
||||
{ "help", 'h', com_help, 1, "Display this help." },
|
||||
{ "?", '?', com_help, 1, "Synonym for `help'." },
|
||||
{ "clear", 'c', com_clear, 0, "Clear command."},
|
||||
{ "connect",'r', com_connect,1,
|
||||
"Reconnect to the server. Optional arguments are db and host." },
|
||||
{ "delimiter", 'd', com_delimiter, 1,
|
||||
"Set query delimiter. " },
|
||||
#ifdef USE_POPEN
|
||||
{ "edit", 'e', com_edit, 0, "Edit command with $EDITOR."},
|
||||
#endif
|
||||
|
@ -239,6 +240,7 @@ static COMMANDS commands[] = {
|
|||
"Send command to mysql server, display result vertically."},
|
||||
{ "exit", 'q', com_quit, 0, "Exit mysql. Same as quit."},
|
||||
{ "go", 'g', com_go, 0, "Send command to mysql server." },
|
||||
{ "help", 'h', com_help, 1, "Display this help." },
|
||||
#ifdef USE_POPEN
|
||||
{ "nopager",'n', com_nopager,0, "Disable pager, print to stdout." },
|
||||
#endif
|
||||
|
@ -261,8 +263,6 @@ static COMMANDS commands[] = {
|
|||
"Set outfile [to_outfile]. Append everything into given outfile." },
|
||||
{ "use", 'u', com_use, 1,
|
||||
"Use another database. Takes database name as argument." },
|
||||
{ "delimiter", 'd', com_delimiter, 1,
|
||||
"Set query delimiter. " },
|
||||
/* Get bash-like expansion for some commands */
|
||||
{ "create table", 0, 0, 0, ""},
|
||||
{ "create database", 0, 0, 0, ""},
|
||||
|
@ -1577,8 +1577,8 @@ static int
|
|||
com_help(String *buffer __attribute__((unused)),
|
||||
char *line __attribute__((unused)))
|
||||
{
|
||||
reg1 int i;
|
||||
char * help_arg= strchr(line,' ');
|
||||
reg1 int i, j;
|
||||
char * help_arg= strchr(line,' '), buff[32], *end;
|
||||
|
||||
if (help_arg)
|
||||
return com_server_help(buffer,line,help_arg+1);
|
||||
|
@ -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);
|
||||
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)
|
||||
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);
|
||||
}
|
||||
if (connected && mysql_get_server_version(&mysql) >= 40100)
|
||||
|
@ -2433,8 +2436,9 @@ com_delimiter(String *buffer __attribute__((unused)), char *line)
|
|||
static int
|
||||
com_use(String *buffer __attribute__((unused)), char *line)
|
||||
{
|
||||
char *tmp;
|
||||
char buff[256];
|
||||
char *tmp, buff[FN_REFLEN + 1];
|
||||
MYSQL_RES *res;
|
||||
MYSQL_ROW row;
|
||||
|
||||
bzero(buff, sizeof(buff));
|
||||
strmov(buff, 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);
|
||||
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 (one_database)
|
||||
|
|
|
@ -32,6 +32,4 @@
|
|||
#undef MYSQL_SERVER_SUFFIX
|
||||
#define MYSQL_SERVER_SUFFIX "-embedded"
|
||||
|
||||
#undef HAVE_QUERY_CACHE /* Cache dosn't work yet */
|
||||
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
|
|
@ -15,6 +15,8 @@ Created 9/20/1997 Heikki Tuuri
|
|||
#include "hash0hash.h"
|
||||
#include "log0log.h"
|
||||
|
||||
extern ibool recv_replay_file_ops;
|
||||
|
||||
/***********************************************************************
|
||||
Reads the checkpoint info needed in hot backup. */
|
||||
|
||||
|
|
|
@ -34,6 +34,11 @@ Created 9/20/1997 Heikki Tuuri
|
|||
#include "dict0boot.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;
|
||||
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))
|
||||
|
@ -1974,19 +1979,22 @@ loop:
|
|||
|| type == MLOG_FILE_RENAME
|
||||
|| type == MLOG_FILE_DELETE)) {
|
||||
#ifdef UNIV_HOTBACKUP
|
||||
if (recv_replay_file_ops) {
|
||||
|
||||
/* In ibbackup --apply-log, replay an .ibd file
|
||||
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,
|
||||
type, TRUE, space)) {
|
||||
if (NULL == fil_op_log_parse_or_replay(body,
|
||||
end_ptr, type, TRUE, space)) {
|
||||
fprintf(stderr,
|
||||
"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));
|
||||
|
||||
ut_a(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* In normal mysqld crash recovery we do not try to
|
||||
replay file operations */
|
||||
|
|
|
@ -1447,7 +1447,7 @@ row_create_table_for_mysql(
|
|||
fprintf(stderr,
|
||||
" InnoDB: Error: table %s already exists in InnoDB internal\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: See the Restrictions section of the InnoDB manual.\n",
|
||||
table->name);
|
||||
|
|
|
@ -534,6 +534,8 @@ row_purge_parse_undo_rec(
|
|||
|
||||
node->table = NULL;
|
||||
|
||||
row_mysql_unfreeze_data_dictionary(trx);
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
|
|
|
@ -1603,6 +1603,19 @@ NetWare. */
|
|||
fflush(stderr);
|
||||
|
||||
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,
|
||||
"InnoDB: You are upgrading to an InnoDB version which allows multiple\n"
|
||||
"InnoDB: tablespaces. Wait that purge and insert buffer merge run to\n"
|
||||
|
@ -1625,8 +1638,9 @@ NetWare. */
|
|||
|
||||
fprintf(stderr,
|
||||
"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: InnoDB!\n");
|
||||
"InnoDB: format. You should NOT DOWNGRADE again to an earlier version of\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) {
|
||||
|
|
|
@ -33,10 +33,10 @@ INCLUDES= @MT_INCLUDES@ @bdb_includes@ -I$(top_srcdir)/include \
|
|||
noinst_LIBRARIES = libmysqld_int.a
|
||||
pkglib_LIBRARIES = libmysqld.a
|
||||
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
|
||||
|
||||
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 \
|
||||
ha_innodb.cc ha_berkeley.cc ha_heap.cc ha_isam.cc ha_isammrg.cc \
|
||||
|
|
446
libmysqld/emb_qcache.cc
Normal file
446
libmysqld/emb_qcache.cc
Normal file
|
@ -0,0 +1,446 @@
|
|||
/* Copyright (C) 2000-2003 MySQL 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 */
|
||||
|
||||
#include "mysql_priv.h"
|
||||
#ifdef HAVE_QUERY_CACHE
|
||||
#include <mysql.h>
|
||||
#include "emb_qcache.h"
|
||||
|
||||
void Querycache_stream::store_char(char c)
|
||||
{
|
||||
if (data_end == cur_data)
|
||||
use_next_block();
|
||||
*(cur_data++)= c;
|
||||
#ifndef DBUG_OFF
|
||||
stored_size++;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Querycache_stream::store_short(ushort s)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
stored_size+= 2;
|
||||
#endif
|
||||
if (data_end - cur_data > 1)
|
||||
{
|
||||
int2store(cur_data, s);
|
||||
cur_data+= 2;
|
||||
return;
|
||||
}
|
||||
if (data_end == cur_data)
|
||||
{
|
||||
use_next_block();
|
||||
int2store(cur_data, s);
|
||||
cur_data+= 2;
|
||||
return;
|
||||
}
|
||||
*cur_data= ((byte *)(&s))[0];
|
||||
use_next_block();
|
||||
*(cur_data++)= ((byte *)(&s))[1];
|
||||
}
|
||||
|
||||
void Querycache_stream::store_int(uint i)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
stored_size+= 4;
|
||||
#endif
|
||||
size_t rest_len= data_end - cur_data;
|
||||
if (rest_len > 3)
|
||||
{
|
||||
int4store(cur_data, i);
|
||||
cur_data+= 4;
|
||||
return;
|
||||
}
|
||||
if (!rest_len)
|
||||
{
|
||||
use_next_block();
|
||||
int4store(cur_data, i);
|
||||
cur_data+= 4;
|
||||
return;
|
||||
}
|
||||
memcpy(cur_data, &i, rest_len);
|
||||
use_next_block();
|
||||
memcpy(cur_data, ((byte*)&i)+rest_len, 4-rest_len);
|
||||
cur_data+= 4-rest_len;
|
||||
}
|
||||
|
||||
void Querycache_stream::store_ll(ulonglong ll)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
stored_size+= 8;
|
||||
#endif
|
||||
size_t rest_len= data_end - cur_data;
|
||||
if (rest_len > 7)
|
||||
{
|
||||
int8store(cur_data, ll);
|
||||
cur_data+= 8;
|
||||
return;
|
||||
}
|
||||
if (!rest_len)
|
||||
{
|
||||
use_next_block();
|
||||
int8store(cur_data, ll);
|
||||
cur_data+= 8;
|
||||
return;
|
||||
}
|
||||
memcpy(cur_data, &ll, rest_len);
|
||||
use_next_block();
|
||||
memcpy(cur_data, ((byte*)&ll)+rest_len, 8-rest_len);
|
||||
cur_data+= 8-rest_len;
|
||||
}
|
||||
|
||||
void Querycache_stream::store_str_only(const char *str, uint str_len)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
stored_size+= str_len;
|
||||
#endif
|
||||
do
|
||||
{
|
||||
size_t rest_len= data_end - cur_data;
|
||||
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();
|
||||
str_len-= rest_len;
|
||||
str+= rest_len;
|
||||
} while(str_len);
|
||||
}
|
||||
|
||||
void Querycache_stream::store_str(const char *str, uint str_len)
|
||||
{
|
||||
store_int(str_len);
|
||||
store_str_only(str, str_len);
|
||||
}
|
||||
|
||||
void Querycache_stream::store_safe_str(const char *str, uint str_len)
|
||||
{
|
||||
if (str)
|
||||
{
|
||||
store_int(str_len+1);
|
||||
store_str_only(str, str_len);
|
||||
}
|
||||
else
|
||||
store_int(0);
|
||||
}
|
||||
|
||||
char Querycache_stream::load_char()
|
||||
{
|
||||
if (cur_data == data_end)
|
||||
use_next_block();
|
||||
return *(cur_data++);
|
||||
}
|
||||
|
||||
ushort Querycache_stream::load_short()
|
||||
{
|
||||
ushort result;
|
||||
if (data_end-cur_data > 1)
|
||||
{
|
||||
result= uint2korr(cur_data);
|
||||
cur_data+= 2;
|
||||
return result;
|
||||
}
|
||||
if (data_end == cur_data)
|
||||
{
|
||||
use_next_block();
|
||||
result= uint2korr(cur_data);
|
||||
cur_data+= 2;
|
||||
return result;
|
||||
}
|
||||
((byte*)&result)[0]= *cur_data;
|
||||
use_next_block();
|
||||
((byte*)&result)[1]= *(cur_data++);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint Querycache_stream::load_int()
|
||||
{
|
||||
int result;
|
||||
size_t rest_len= data_end - cur_data;
|
||||
if (rest_len > 3)
|
||||
{
|
||||
result= uint4korr(cur_data);
|
||||
cur_data+= 4;
|
||||
return result;
|
||||
}
|
||||
if (!rest_len)
|
||||
{
|
||||
use_next_block();
|
||||
result= uint4korr(cur_data);
|
||||
cur_data+= 4;
|
||||
return result;
|
||||
}
|
||||
memcpy(&result, cur_data, rest_len);
|
||||
use_next_block();
|
||||
memcpy(((byte*)&result)+rest_len, cur_data, 4-rest_len);
|
||||
cur_data+= 4-rest_len;
|
||||
return result;
|
||||
}
|
||||
|
||||
ulonglong Querycache_stream::load_ll()
|
||||
{
|
||||
ulonglong result;
|
||||
size_t rest_len= data_end - cur_data;
|
||||
if (rest_len > 7)
|
||||
{
|
||||
result= uint8korr(cur_data);
|
||||
cur_data+= 8;
|
||||
return result;
|
||||
}
|
||||
if (!rest_len)
|
||||
{
|
||||
use_next_block();
|
||||
result= uint8korr(cur_data);
|
||||
cur_data+= 8;
|
||||
return result;
|
||||
}
|
||||
memcpy(&result, cur_data, rest_len);
|
||||
use_next_block();
|
||||
memcpy(((byte*)&result)+rest_len, cur_data, 8-rest_len);
|
||||
cur_data+= 8-rest_len;
|
||||
return result;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
memcpy(buffer, cur_data, str_len);
|
||||
cur_data+= str_len;
|
||||
buffer+= str_len;
|
||||
break;
|
||||
}
|
||||
memcpy(buffer, cur_data, rest_len);
|
||||
use_next_block();
|
||||
str_len-= rest_len;
|
||||
buffer+= rest_len;
|
||||
} while(str_len);
|
||||
*buffer= 0;
|
||||
}
|
||||
|
||||
char *Querycache_stream::load_str(MEM_ROOT *alloc, uint *str_len)
|
||||
{
|
||||
char *result;
|
||||
*str_len= load_int();
|
||||
if (!(result= alloc_root(alloc, *str_len + 1)))
|
||||
return 0;
|
||||
load_str_only(result, *str_len);
|
||||
return result;
|
||||
}
|
||||
|
||||
int Querycache_stream::load_safe_str(MEM_ROOT *alloc, char **str, uint *str_len)
|
||||
{
|
||||
if (!(*str_len= load_int()))
|
||||
{
|
||||
*str= NULL;
|
||||
return 0;
|
||||
}
|
||||
(*str_len)--;
|
||||
if (!(*str= alloc_root(alloc, *str_len + 1)))
|
||||
return 1;
|
||||
load_str_only(*str, *str_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Querycache_stream::load_column(MEM_ROOT *alloc, char** column)
|
||||
{
|
||||
int len;
|
||||
if (!(len = load_int()))
|
||||
{
|
||||
*column= NULL;
|
||||
return 0;
|
||||
}
|
||||
len--;
|
||||
if (!(*column= (char *)alloc_root(alloc, len + 4 + 1)))
|
||||
return 1;
|
||||
int4store(*column, len);
|
||||
(*column)+= 4;
|
||||
load_str_only(*column, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint emb_count_querycache_size(THD *thd)
|
||||
{
|
||||
uint result;
|
||||
MYSQL *mysql= thd->mysql;
|
||||
MYSQL_FIELD *field= mysql->fields;
|
||||
MYSQL_FIELD *field_end= field + mysql->field_count;
|
||||
MYSQL_ROWS *cur_row=NULL;
|
||||
my_ulonglong n_rows=0;
|
||||
|
||||
if (!field)
|
||||
return 0;
|
||||
if (thd->data)
|
||||
{
|
||||
*thd->data->prev_ptr= NULL; // this marks the last record
|
||||
cur_row= thd->data->data;
|
||||
n_rows= thd->data->rows;
|
||||
}
|
||||
result= 4+8 + (42 + 4*n_rows)*mysql->field_count;
|
||||
|
||||
for(; field < field_end; field++)
|
||||
{
|
||||
result+= field->name_length + field->table_length +
|
||||
field->org_name_length + field->org_table_length + field->db_length +
|
||||
field->catalog_length;
|
||||
if (field->def)
|
||||
result+= field->def_length;
|
||||
}
|
||||
|
||||
for (; cur_row; cur_row=cur_row->next)
|
||||
{
|
||||
MYSQL_ROW col= cur_row->data;
|
||||
MYSQL_ROW col_end= col + mysql->field_count;
|
||||
for (; col < col_end; col++)
|
||||
if (*col)
|
||||
result+= *(uint *)((*col) - sizeof(uint));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void emb_store_querycache_result(Querycache_stream *dst, THD *thd)
|
||||
{
|
||||
MYSQL *mysql= thd->mysql;
|
||||
MYSQL_FIELD *field= mysql->fields;
|
||||
MYSQL_FIELD *field_end= field + mysql->field_count;
|
||||
MYSQL_ROWS *cur_row= NULL;
|
||||
my_ulonglong n_rows= 0;
|
||||
|
||||
if (!field)
|
||||
return;
|
||||
|
||||
if (thd->data)
|
||||
{
|
||||
*thd->data->prev_ptr= NULL; // this marks the last record
|
||||
cur_row= thd->data->data;
|
||||
n_rows= thd->data->rows;
|
||||
}
|
||||
|
||||
dst->store_int((uint)mysql->field_count);
|
||||
dst->store_ll((uint)n_rows);
|
||||
|
||||
for(; field < field_end; field++)
|
||||
{
|
||||
dst->store_int((uint)field->length);
|
||||
dst->store_int((uint)field->max_length);
|
||||
dst->store_char((char)field->type);
|
||||
dst->store_short((ushort)field->flags);
|
||||
dst->store_short((ushort)field->charsetnr);
|
||||
dst->store_char((char)field->decimals);
|
||||
dst->store_str(field->name, field->name_length);
|
||||
dst->store_str(field->table, field->table_length);
|
||||
dst->store_str(field->org_name, field->org_name_length);
|
||||
dst->store_str(field->org_table, field->org_table_length);
|
||||
dst->store_str(field->db, field->db_length);
|
||||
dst->store_str(field->catalog, field->catalog_length);
|
||||
|
||||
dst->store_safe_str(field->def, field->def_length);
|
||||
}
|
||||
|
||||
for (; cur_row; cur_row=cur_row->next)
|
||||
{
|
||||
MYSQL_ROW col= cur_row->data;
|
||||
MYSQL_ROW col_end= col + mysql->field_count;
|
||||
for (; col < col_end; col++)
|
||||
{
|
||||
uint len= *col ? *(uint *)((*col) - sizeof(uint)) : 0;
|
||||
dst->store_safe_str(*col, len);
|
||||
}
|
||||
}
|
||||
DBUG_ASSERT(emb_count_querycache_size(thd) == dst->stored_size);
|
||||
}
|
||||
|
||||
int emb_load_querycache_result(THD *thd, Querycache_stream *src)
|
||||
{
|
||||
MYSQL *mysql= thd->mysql;
|
||||
MYSQL_DATA *data;
|
||||
MYSQL_FIELD *field;
|
||||
MYSQL_FIELD *field_end;
|
||||
MEM_ROOT *f_alloc= &mysql->field_alloc;
|
||||
MYSQL_ROWS *row, *end_row;
|
||||
MYSQL_ROWS **prev_row;
|
||||
ulonglong rows;
|
||||
MYSQL_ROW columns;
|
||||
|
||||
mysql->field_count= src->load_int();
|
||||
rows= src->load_ll();
|
||||
|
||||
if (!(field= (MYSQL_FIELD *)
|
||||
alloc_root(&mysql->field_alloc,mysql->field_count*sizeof(MYSQL_FIELD))))
|
||||
goto err;
|
||||
mysql->fields= field;
|
||||
for(field_end= field+mysql->field_count; field < field_end; field++)
|
||||
{
|
||||
field->length= src->load_int();
|
||||
field->max_length= (unsigned int)src->load_int();
|
||||
field->type= (enum enum_field_types)src->load_char();
|
||||
field->flags= (unsigned int)src->load_short();
|
||||
field->charsetnr= (unsigned int)src->load_short();
|
||||
field->decimals= (unsigned int)src->load_char();
|
||||
|
||||
if (!(field->name= src->load_str(f_alloc, &field->name_length)) ||
|
||||
!(field->table= src->load_str(f_alloc,&field->table_length)) ||
|
||||
!(field->org_name= src->load_str(f_alloc, &field->org_name_length)) ||
|
||||
!(field->org_table= src->load_str(f_alloc, &field->org_table_length))||
|
||||
!(field->db= src->load_str(f_alloc, &field->db_length)) ||
|
||||
!(field->catalog= src->load_str(f_alloc, &field->catalog_length)) ||
|
||||
src->load_safe_str(f_alloc, &field->def, &field->def_length))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!rows)
|
||||
return 0;
|
||||
if (!(data= (MYSQL_DATA*)my_malloc(sizeof(MYSQL_DATA),
|
||||
MYF(MY_WME | MY_ZEROFILL))))
|
||||
goto err;
|
||||
thd->data= data;
|
||||
init_alloc_root(&data->alloc, 8192,0);
|
||||
row= (MYSQL_ROWS *)alloc_root(&data->alloc, rows * sizeof(MYSQL_ROWS) +
|
||||
rows * (mysql->field_count+1)*sizeof(char*));
|
||||
end_row= row + rows;
|
||||
columns= (MYSQL_ROW)end_row;
|
||||
|
||||
data->rows= rows;
|
||||
data->fields= mysql->field_count;
|
||||
data->data= row;
|
||||
|
||||
for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++)
|
||||
{
|
||||
*prev_row= row;
|
||||
row->data= columns;
|
||||
MYSQL_ROW col_end= columns + mysql->field_count;
|
||||
uint len;
|
||||
for (; columns < col_end; columns++)
|
||||
src->load_column(&data->alloc, columns);
|
||||
|
||||
*(columns++)= NULL;
|
||||
}
|
||||
*prev_row= NULL;
|
||||
data->prev_ptr= prev_row;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /*HAVE_QUERY_CACHE*/
|
||||
|
61
libmysqld/emb_qcache.h
Normal file
61
libmysqld/emb_qcache.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* 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 @@
|
|||
#include <my_pthread.h>
|
||||
|
||||
C_MODE_START
|
||||
extern void lib_connection_phase(NET *net, int phase);
|
||||
extern void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db);
|
||||
extern void *create_embedded_thd(int client_flag, char *db);
|
||||
extern MYSQL_METHODS embedded_methods;
|
||||
void lib_connection_phase(NET *net, int phase);
|
||||
void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db);
|
||||
void *create_embedded_thd(int client_flag, char *db);
|
||||
int check_embedded_connection(MYSQL *mysql);
|
||||
void free_old_query(MYSQL *mysql);
|
||||
extern MYSQL_METHODS embedded_methods;
|
||||
C_MODE_END
|
||||
|
|
|
@ -478,7 +478,17 @@ void *create_embedded_thd(int client_flag, char *db)
|
|||
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)
|
||||
{
|
||||
THD *thd= (THD*)mysql->thd;
|
||||
|
@ -486,9 +496,13 @@ int check_embedded_connection(MYSQL *mysql)
|
|||
char scramble_buff[SCRAMBLE_LENGTH];
|
||||
int passwd_len;
|
||||
|
||||
thd->host= mysql->options.client_ip ?
|
||||
mysql->options.client_ip : (char*)my_localhost;
|
||||
if (mysql->options.client_ip)
|
||||
{
|
||||
thd->host= mysql->options.client_ip;
|
||||
thd->ip= thd->host;
|
||||
}
|
||||
else
|
||||
thd->host= (char*)my_localhost;
|
||||
thd->host_or_ip= thd->host;
|
||||
|
||||
if (acl_check_host(thd->host,thd->ip))
|
||||
|
@ -566,6 +580,9 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
|
|||
client_field->org_table_length= strlen(client_field->org_table);
|
||||
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))
|
||||
client_field->flags|= NUM_FLAG;
|
||||
|
||||
|
@ -575,9 +592,15 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
|
|||
String tmp(buff, sizeof(buff), default_charset_info), *res;
|
||||
|
||||
if (!(res=item->val_str(&tmp)))
|
||||
{
|
||||
client_field->def= strdup_root(field_alloc, "");
|
||||
client_field->def_length= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
client_field->def= strdup_root(field_alloc, tmp.ptr());
|
||||
client_field->def_length= tmp.length();
|
||||
}
|
||||
}
|
||||
else
|
||||
client_field->def=0;
|
||||
|
|
|
@ -124,17 +124,14 @@ static inline int mysql_init_charset(MYSQL *mysql)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int check_embedded_connection(MYSQL *mysql);
|
||||
|
||||
MYSQL * STDCALL
|
||||
mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
||||
const char *passwd, const char *db,
|
||||
uint port, const char *unix_socket,ulong client_flag)
|
||||
{
|
||||
char *db_name;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
char name_buff[USERNAME_LENGTH];
|
||||
#endif
|
||||
|
||||
DBUG_ENTER("mysql_real_connect");
|
||||
DBUG_PRINT("enter",("host: %s db: %s user: %s",
|
||||
host ? host : "(Null)",
|
||||
|
@ -165,10 +162,10 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
|||
if (!db || !db[0])
|
||||
db=mysql->options.db;
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (!user || !user[0])
|
||||
user=mysql->options.user;
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (!passwd)
|
||||
{
|
||||
passwd=mysql->options.password;
|
||||
|
@ -177,16 +174,18 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
|||
passwd=getenv("MYSQL_PWD"); /* get it from environment */
|
||||
#endif
|
||||
}
|
||||
mysql->passwd= passwd ? my_strdup(passwd,MYF(0)) : NULL;
|
||||
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
|
||||
if (!user || !user[0])
|
||||
{
|
||||
read_user_name(name_buff);
|
||||
if (!name_buff[0])
|
||||
if (name_buff[0])
|
||||
user= name_buff;
|
||||
}
|
||||
|
||||
if (!user)
|
||||
user= "";
|
||||
mysql->user=my_strdup(user,MYF(0));
|
||||
mysql->passwd= passwd ? my_strdup(passwd,MYF(0)) : NULL;
|
||||
#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
|
||||
|
||||
port=0;
|
||||
unix_socket=0;
|
||||
|
@ -196,10 +195,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
|||
|
||||
init_embedded_mysql(mysql, client_flag, db_name);
|
||||
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
if (check_embedded_connection(mysql))
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
if (mysql_init_charset(mysql))
|
||||
goto error;
|
||||
|
|
|
@ -120,3 +120,45 @@ select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i;
|
|||
1 3 2 0
|
||||
3 6 3 0
|
||||
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;
|
|||
select @a:=0; select @a+0, @a:=@a+0+count(*), count(*), @a+0 from t1 group by i;
|
||||
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,
|
|||
is different from query_id).
|
||||
*/
|
||||
entry->update_query_id= thd->query_id;
|
||||
entry->collation.set(args[0]->collation);
|
||||
cached_result_type= args[0]->result_type();
|
||||
return 0;
|
||||
}
|
||||
|
@ -2174,6 +2175,7 @@ Item_func_set_user_var::fix_length_and_dec()
|
|||
maybe_null=args[0]->maybe_null;
|
||||
max_length=args[0]->max_length;
|
||||
decimals=args[0]->decimals;
|
||||
collation.set(args[0]->collation);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2488,6 +2490,8 @@ void Item_func_get_user_var::fix_length_and_dec()
|
|||
|
||||
if (!(var_entry= get_variable(&thd->user_vars, name, 0)))
|
||||
null_value= 1;
|
||||
else
|
||||
collation.set(var_entry->collation);
|
||||
|
||||
if (!(opt_bin_log && is_update_query(thd->lex->sql_command)))
|
||||
return;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version='1.0' encoding="utf-8"?>
|
||||
|
||||
<charsets max-id="93">
|
||||
<charsets max-id="94">
|
||||
|
||||
<description>
|
||||
This file lists all of the available character sets.
|
||||
|
@ -100,6 +100,7 @@ To make maintaining easier please:
|
|||
<collation name="latin1_swedish_ci" id="8" order="Finnish, Swedish" flag="primary"/>
|
||||
<collation name="latin1_danish_ci" id="15" order="Danish"/>
|
||||
<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">
|
||||
<flag>binary</flag>
|
||||
<flag>compiled</flag>
|
||||
|
|
|
@ -209,6 +209,27 @@
|
|||
</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>
|
||||
|
||||
</charsets>
|
||||
|
|
|
@ -308,6 +308,10 @@ TODO list:
|
|||
#include "../myisammrg/myrg_def.h"
|
||||
#endif
|
||||
|
||||
#ifdef EMBEDDED_LIBRARY
|
||||
#include "emb_qcache.h"
|
||||
#endif
|
||||
|
||||
#if defined(EXTRA_DEBUG) && !defined(DBUG_OFF)
|
||||
#define MUTEX_LOCK(M) { DBUG_PRINT("lock", ("mutex lock 0x%lx", (ulong)(M))); \
|
||||
pthread_mutex_lock(M);}
|
||||
|
@ -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");
|
||||
|
||||
|
@ -655,11 +659,15 @@ void query_cache_end_of_result(NET *net)
|
|||
if (query_cache.query_cache_size == 0) DBUG_VOID_RETURN;
|
||||
#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);
|
||||
Query_cache_block *query_block = ((Query_cache_block*)
|
||||
net->query_cache_query);
|
||||
thd->net.query_cache_query);
|
||||
if (query_block)
|
||||
{
|
||||
DUMP(&query_cache);
|
||||
|
@ -691,7 +699,7 @@ void query_cache_end_of_result(NET *net)
|
|||
// Cache was flushed or resized and query was deleted => do nothing
|
||||
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_VOID_RETURN;
|
||||
|
@ -1052,6 +1060,7 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
|
|||
/*
|
||||
Send cached result to client
|
||||
*/
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
do
|
||||
{
|
||||
DBUG_PRINT("qcache", ("Results (len %lu, used %lu, headers %lu)",
|
||||
|
@ -1060,15 +1069,20 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
|
|||
ALIGN_SIZE(sizeof(Query_cache_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(),
|
||||
result_block->used -
|
||||
result_block->headers_len() -
|
||||
ALIGN_SIZE(sizeof(Query_cache_result))))
|
||||
break; // Client aborted
|
||||
#endif
|
||||
result_block = result_block->next;
|
||||
} 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();
|
||||
|
||||
|
@ -1804,6 +1818,7 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block,
|
|||
Query_cache_block *block = *result_block;
|
||||
uint headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
|
||||
ALIGN_SIZE(sizeof(Query_cache_result)));
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
// Now fill list of blocks that created by allocate_data_chain
|
||||
do
|
||||
{
|
||||
|
@ -1816,6 +1831,10 @@ my_bool Query_cache::write_result_data(Query_cache_block **result_block,
|
|||
block = block->next;
|
||||
type = Query_cache_block::RES_CONT;
|
||||
} while (block != *result_block);
|
||||
#else
|
||||
Querycache_stream qs(*result_block, headers_len);
|
||||
emb_store_querycache_result(&qs, (THD*)data);
|
||||
#endif /*!EMBEDDED_LIBRARY*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -392,7 +392,7 @@ protected:
|
|||
void destroy();
|
||||
|
||||
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);
|
||||
|
||||
/*
|
||||
|
@ -416,7 +416,7 @@ protected:
|
|||
|
||||
extern Query_cache query_cache;
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -323,12 +323,14 @@ THD::~THD()
|
|||
#endif
|
||||
|
||||
DBUG_PRINT("info", ("freeing host"));
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
if (host != my_localhost) // If not pointer to constant
|
||||
safeFree(host);
|
||||
if (user != delayed_user)
|
||||
safeFree(user);
|
||||
safeFree(db);
|
||||
safeFree(ip);
|
||||
#endif
|
||||
safeFree(db);
|
||||
free_root(&warn_root,MYF(0));
|
||||
free_root(&transaction.mem_root,MYF(0));
|
||||
mysys_var=0; // Safety (shouldn't be needed)
|
||||
|
|
|
@ -3877,7 +3877,7 @@ mysql_parse(THD *thd, char *inBuf, uint length)
|
|||
else
|
||||
{
|
||||
mysql_execute_command(thd);
|
||||
query_cache_end_of_result(&thd->net);
|
||||
query_cache_end_of_result(thd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue