mariadb/libmysqld/emb_qcache.cc
Michael Widenius 70823e1d91 MDEV-5120 Test suite test maria-no-logging fails
The reason for the failure was a bug in an include file on debian that causes 'struct stat'
to have different sized depending on the environment.

This patch fixes so that we always include my_global.h or my_config.h before we include any other files.

Other things:
- Removed #include <my_global.h> in some include files; Better to always do this at the top level to have as few
  "always-include-this-file-first' files as possible.
- Removed usage of some include files that where already included by my_global.h or by other files.


client/mysql_plugin.c:
  Use my_global.h first
client/mysqlslap.c:
  Remove duplicated include files
extra/comp_err.c:
  Remove duplicated include files
include/m_string.h:
  Remove duplicated include files
include/maria.h:
  Remove duplicated include files
libmysqld/emb_qcache.cc:
  Use my_global.h first
plugin/semisync/semisync.h:
  Use my_pthread.h first
sql/datadict.cc:
  Use my_global.h first
sql/debug_sync.cc:
  Use my_global.h first
sql/derror.cc:
  Use my_global.h first
sql/des_key_file.cc:
  Use my_global.h first
sql/discover.cc:
  Use my_global.h first
sql/event_data_objects.cc:
  Use my_global.h first
sql/event_db_repository.cc:
  Use my_global.h first
sql/event_parse_data.cc:
  Use my_global.h first
sql/event_queue.cc:
  Use my_global.h first
sql/event_scheduler.cc:
  Use my_global.h first
sql/events.cc:
  Use my_global.h first
sql/field.cc:
  Use my_global.h first
  Remove duplicated include files
sql/field_conv.cc:
  Use my_global.h first
sql/filesort.cc:
  Use my_global.h first
  Remove duplicated include files
sql/gstream.cc:
  Use my_global.h first
sql/ha_ndbcluster.cc:
  Use my_global.h first
sql/ha_ndbcluster_binlog.cc:
  Use my_global.h first
sql/ha_ndbcluster_cond.cc:
  Use my_global.h first
sql/ha_partition.cc:
  Use my_global.h first
sql/handler.cc:
  Use my_global.h first
sql/hash_filo.cc:
  Use my_global.h first
sql/hostname.cc:
  Use my_global.h first
sql/init.cc:
  Use my_global.h first
sql/item.cc:
  Use my_global.h first
sql/item_buff.cc:
  Use my_global.h first
sql/item_cmpfunc.cc:
  Use my_global.h first
sql/item_create.cc:
  Use my_global.h first
sql/item_geofunc.cc:
  Use my_global.h first
sql/item_inetfunc.cc:
  Use my_global.h first
sql/item_row.cc:
  Use my_global.h first
sql/item_strfunc.cc:
  Use my_global.h first
sql/item_subselect.cc:
  Use my_global.h first
sql/item_sum.cc:
  Use my_global.h first
sql/item_timefunc.cc:
  Use my_global.h first
sql/item_xmlfunc.cc:
  Use my_global.h first
sql/key.cc:
  Use my_global.h first
sql/lock.cc:
  Use my_global.h first
sql/log.cc:
  Use my_global.h first
sql/log_event.cc:
  Use my_global.h first
sql/log_event_old.cc:
  Use my_global.h first
sql/mf_iocache.cc:
  Use my_global.h first
sql/mysql_install_db.cc:
  Remove duplicated include files
sql/mysqld.cc:
  Remove duplicated include files
sql/net_serv.cc:
  Remove duplicated include files
sql/opt_range.cc:
  Use my_global.h first
sql/opt_subselect.cc:
  Use my_global.h first
sql/opt_sum.cc:
  Use my_global.h first
sql/parse_file.cc:
  Use my_global.h first
sql/partition_info.cc:
  Use my_global.h first
sql/procedure.cc:
  Use my_global.h first
sql/protocol.cc:
  Use my_global.h first
sql/records.cc:
  Use my_global.h first
sql/records.h:
  Don't include my_global.h
  Better to do this at the upper level
sql/repl_failsafe.cc:
  Use my_global.h first
sql/rpl_filter.cc:
  Use my_global.h first
sql/rpl_gtid.cc:
  Use my_global.h first
sql/rpl_handler.cc:
  Use my_global.h first
sql/rpl_injector.cc:
  Use my_global.h first
sql/rpl_record.cc:
  Use my_global.h first
sql/rpl_record_old.cc:
  Use my_global.h first
sql/rpl_reporting.cc:
  Use my_global.h first
sql/rpl_rli.cc:
  Use my_global.h first
sql/rpl_tblmap.cc:
  Use my_global.h first
sql/rpl_utility.cc:
  Use my_global.h first
sql/set_var.cc:
  Added comment
sql/slave.cc:
  Use my_global.h first
sql/sp.cc:
  Use my_global.h first
sql/sp_cache.cc:
  Use my_global.h first
sql/sp_head.cc:
  Use my_global.h first
sql/sp_pcontext.cc:
  Use my_global.h first
sql/sp_rcontext.cc:
  Use my_global.h first
sql/spatial.cc:
  Use my_global.h first
sql/sql_acl.cc:
  Use my_global.h first
sql/sql_admin.cc:
  Use my_global.h first
sql/sql_analyse.cc:
  Use my_global.h first
sql/sql_audit.cc:
  Use my_global.h first
sql/sql_base.cc:
  Use my_global.h first
sql/sql_binlog.cc:
  Use my_global.h first
sql/sql_bootstrap.cc:
  Use my_global.h first
  Use my_global.h first
sql/sql_cache.cc:
  Use my_global.h first
sql/sql_class.cc:
  Use my_global.h first
sql/sql_client.cc:
  Use my_global.h first
sql/sql_connect.cc:
  Use my_global.h first
sql/sql_crypt.cc:
  Use my_global.h first
sql/sql_cursor.cc:
  Use my_global.h first
sql/sql_db.cc:
  Use my_global.h first
sql/sql_delete.cc:
  Use my_global.h first
sql/sql_derived.cc:
  Use my_global.h first
sql/sql_do.cc:
  Use my_global.h first
sql/sql_error.cc:
  Use my_global.h first
sql/sql_explain.cc:
  Use my_global.h first
sql/sql_expression_cache.cc:
  Use my_global.h first
sql/sql_handler.cc:
  Use my_global.h first
sql/sql_help.cc:
  Use my_global.h first
sql/sql_insert.cc:
  Use my_global.h first
sql/sql_lex.cc:
  Use my_global.h first
sql/sql_load.cc:
  Use my_global.h first
sql/sql_locale.cc:
  Use my_global.h first
sql/sql_manager.cc:
  Use my_global.h first
sql/sql_parse.cc:
  Use my_global.h first
sql/sql_partition.cc:
  Use my_global.h first
sql/sql_plugin.cc:
  Added comment
sql/sql_prepare.cc:
  Use my_global.h first
sql/sql_priv.h:
  Added error if we use this before including my_global.h
  This check is here becasue so many files includes sql_priv.h first.
sql/sql_profile.cc:
  Use my_global.h first
sql/sql_reload.cc:
  Use my_global.h first
sql/sql_rename.cc:
  Use my_global.h first
sql/sql_repl.cc:
  Use my_global.h first
sql/sql_select.cc:
  Use my_global.h first
sql/sql_servers.cc:
  Use my_global.h first
sql/sql_show.cc:
  Added comment
sql/sql_signal.cc:
  Use my_global.h first
sql/sql_statistics.cc:
  Use my_global.h first
sql/sql_table.cc:
  Use my_global.h first
sql/sql_tablespace.cc:
  Use my_global.h first
sql/sql_test.cc:
  Use my_global.h first
sql/sql_time.cc:
  Use my_global.h first
sql/sql_trigger.cc:
  Use my_global.h first
sql/sql_udf.cc:
  Use my_global.h first
sql/sql_union.cc:
  Use my_global.h first
sql/sql_update.cc:
  Use my_global.h first
sql/sql_view.cc:
  Use my_global.h first
sql/sys_vars.cc:
  Added comment
sql/table.cc:
  Use my_global.h first
sql/thr_malloc.cc:
  Use my_global.h first
sql/transaction.cc:
  Use my_global.h first
sql/uniques.cc:
  Use my_global.h first
sql/unireg.cc:
  Use my_global.h first
sql/unireg.h:
  Removed inclusion of my_global.h
storage/archive/ha_archive.cc:
  Added comment
storage/blackhole/ha_blackhole.cc:
  Use my_global.h first
storage/csv/ha_tina.cc:
  Use my_global.h first
storage/csv/transparent_file.cc:
  Use my_global.h first
storage/federated/ha_federated.cc:
  Use my_global.h first
storage/federatedx/federatedx_io.cc:
  Use my_global.h first
storage/federatedx/federatedx_io_mysql.cc:
  Use my_global.h first
storage/federatedx/federatedx_io_null.cc:
  Use my_global.h first
storage/federatedx/federatedx_txn.cc:
  Use my_global.h first
storage/heap/ha_heap.cc:
  Use my_global.h first
storage/innobase/handler/handler0alter.cc:
  Use my_global.h first
storage/maria/ha_maria.cc:
  Use my_global.h first
storage/maria/unittest/ma_maria_log_cleanup.c:
  Remove duplicated include files
storage/maria/unittest/test_file.c:
  Added comment
storage/myisam/ha_myisam.cc:
  Move sql_plugin.h first as this includes my_global.h
storage/myisammrg/ha_myisammrg.cc:
  Use my_global.h first
storage/oqgraph/oqgraph_thunk.cc:
  Use my_config.h and my_global.h first
  One could not include my_global.h before oqgraph_thunk.h (don't know why)
storage/spider/ha_spider.cc:
  Use my_global.h first
storage/spider/hs_client/config.cpp:
  Use my_global.h first
storage/spider/hs_client/escape.cpp:
  Use my_global.h first
storage/spider/hs_client/fatal.cpp:
  Use my_global.h first
storage/spider/hs_client/hstcpcli.cpp:
  Use my_global.h first
storage/spider/hs_client/socket.cpp:
  Use my_global.h first
storage/spider/hs_client/string_util.cpp:
  Use my_global.h first
storage/spider/spd_conn.cc:
  Use my_global.h first
storage/spider/spd_copy_tables.cc:
  Use my_global.h first
storage/spider/spd_db_conn.cc:
  Use my_global.h first
storage/spider/spd_db_handlersocket.cc:
  Use my_global.h first
storage/spider/spd_db_mysql.cc:
  Use my_global.h first
storage/spider/spd_db_oracle.cc:
  Use my_global.h first
storage/spider/spd_direct_sql.cc:
  Use my_global.h first
storage/spider/spd_i_s.cc:
  Use my_global.h first
storage/spider/spd_malloc.cc:
  Use my_global.h first
storage/spider/spd_param.cc:
  Use my_global.h first
storage/spider/spd_ping_table.cc:
  Use my_global.h first
storage/spider/spd_sys_table.cc:
  Use my_global.h first
storage/spider/spd_table.cc:
  Use my_global.h first
storage/spider/spd_trx.cc:
  Use my_global.h first
storage/xtradb/handler/handler0alter.cc:
  Use my_global.h first
storage/xtradb/handler/i_s.cc:
  Use my_global.h first
2014-09-30 20:31:14 +03:00

500 lines
12 KiB
C++

/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
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; version 2 of the License.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "my_global.h" // HAVE_*
#include "sql_priv.h"
#ifdef HAVE_QUERY_CACHE
#include <mysql.h>
#include "emb_qcache.h"
#include "embedded_priv.h"
#include "sql_class.h" // THD
void Querycache_stream::store_uchar(uchar c)
{
if (data_end == cur_data)
use_next_block(TRUE);
*(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(TRUE);
int2store(cur_data, s);
cur_data+= 2;
return;
}
*cur_data= ((uchar *)(&s))[0];
use_next_block(TRUE);
*(cur_data++)= ((uchar *)(&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(TRUE);
int4store(cur_data, i);
cur_data+= 4;
return;
}
char buf[4];
int4store(buf, i);
memcpy(cur_data, buf, rest_len);
use_next_block(TRUE);
memcpy(cur_data, buf+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(TRUE);
int8store(cur_data, ll);
cur_data+= 8;
return;
}
memcpy(cur_data, &ll, rest_len);
use_next_block(TRUE);
memcpy(cur_data, ((uchar*)&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(TRUE);
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);
}
uchar Querycache_stream::load_uchar()
{
if (cur_data == data_end)
use_next_block(FALSE);
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(FALSE);
result= uint2korr(cur_data);
cur_data+= 2;
return result;
}
((uchar*)&result)[0]= *cur_data;
use_next_block(FALSE);
((uchar*)&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(FALSE);
result= uint4korr(cur_data);
cur_data+= 4;
return result;
}
char buf[4];
memcpy(buf, cur_data, rest_len);
use_next_block(FALSE);
memcpy(buf+rest_len, cur_data, 4-rest_len);
cur_data+= 4-rest_len;
result= uint4korr(buf);
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(FALSE);
result= uint8korr(cur_data);
cur_data+= 8;
return result;
}
memcpy(&result, cur_data, rest_len);
use_next_block(FALSE);
memcpy(((uchar*)&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(FALSE);
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= (char*) 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= (char*) 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 + sizeof(uint) + 1)))
return 1;
*((uint*)*column)= len;
(*column)+= sizeof(uint);
load_str_only(*column, len);
return 1;
}
uint emb_count_querycache_size(THD *thd)
{
uint result= 0;
MYSQL_FIELD *field;
MYSQL_FIELD *field_end;
MYSQL_ROWS *cur_row;
my_ulonglong n_rows;
MYSQL_DATA *data= thd->first_data;
while (data->embedded_info->next)
data= data->embedded_info->next;
field= data->embedded_info->fields_list;
field_end= field + data->fields;
if (!field)
return result;
*data->embedded_info->prev_ptr= NULL; // this marks the last record
cur_row= data->data;
n_rows= data->rows;
/* n_fields + n_rows + field_info * n_fields */
result+= (uint) (4+8 + 42*data->fields);
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;
}
if (thd->protocol == &thd->protocol_binary ||
thd->get_command() == COM_STMT_EXECUTE)
{
result+= (uint) (4*n_rows);
for (; cur_row; cur_row=cur_row->next)
result+= cur_row->length;
}
else
{
result+= (uint) (4*n_rows*data->fields);
for (; cur_row; cur_row=cur_row->next)
{
MYSQL_ROW col= cur_row->data;
MYSQL_ROW col_end= col + data->fields;
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_FIELD *field;
MYSQL_FIELD *field_end;
MYSQL_ROWS *cur_row;
my_ulonglong n_rows;
MYSQL_DATA *data= thd->first_data;
DBUG_ENTER("emb_store_querycache_result");
while (data->embedded_info->next)
data= data->embedded_info->next;
field= data->embedded_info->fields_list;
field_end= field + data->fields;
if (!field)
DBUG_VOID_RETURN;
*data->embedded_info->prev_ptr= NULL; // this marks the last record
cur_row= data->data;
n_rows= data->rows;
dst->store_int((uint)data->fields);
dst->store_ll((ulonglong)n_rows);
for(; field < field_end; field++)
{
dst->store_int((uint)field->length);
dst->store_int((uint)field->max_length);
dst->store_uchar((uchar)field->type);
dst->store_short((ushort)field->flags);
dst->store_short((ushort)field->charsetnr);
dst->store_uchar((uchar)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);
}
if (thd->protocol == &thd->protocol_binary ||
thd->get_command() == COM_STMT_EXECUTE)
{
for (; cur_row; cur_row=cur_row->next)
dst->store_str((char *) cur_row->data, cur_row->length);
}
else
{
for (; cur_row; cur_row=cur_row->next)
{
MYSQL_ROW col= cur_row->data;
MYSQL_ROW col_end= col + data->fields;
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);
DBUG_VOID_RETURN;
}
int emb_load_querycache_result(THD *thd, Querycache_stream *src)
{
MYSQL_DATA *data= thd->alloc_new_dataset();
MYSQL_FIELD *field;
MYSQL_FIELD *field_end;
MEM_ROOT *f_alloc;
MYSQL_ROWS *row, *end_row;
MYSQL_ROWS **prev_row;
ulonglong rows;
MYSQL_ROW columns;
DBUG_ENTER("emb_load_querycache_result");
if (!data)
goto err;
init_alloc_root(&data->alloc, 8192,0,MYF(0));
f_alloc= &data->alloc;
data->fields= src->load_int();
rows= src->load_ll();
if (!(field= (MYSQL_FIELD *)
alloc_root(f_alloc,data->fields*sizeof(MYSQL_FIELD))))
goto err;
data->embedded_info->fields_list= field;
for(field_end= field+data->fields; 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_uchar();
field->flags= (unsigned int)src->load_short();
field->charsetnr= (unsigned int)src->load_short();
field->decimals= src->load_uchar();
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;
}
data->rows= rows;
if (!rows)
goto return_ok;
if (thd->protocol == &thd->protocol_binary ||
thd->get_command() == COM_STMT_EXECUTE)
{
uint length;
row= (MYSQL_ROWS *)alloc_root(&data->alloc,
(size_t) (rows * sizeof(MYSQL_ROWS)));
end_row= row + rows;
data->data= row;
for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++)
{
*prev_row= row;
row->data= (MYSQL_ROW) src->load_str(&data->alloc, &length);
row->length= length;
}
}
else
{
row= (MYSQL_ROWS *)alloc_root(&data->alloc,
(uint) (rows * sizeof(MYSQL_ROWS) +
rows*(data->fields+1)*sizeof(char*)));
end_row= row + rows;
columns= (MYSQL_ROW)end_row;
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 + data->fields;
for (; columns < col_end; columns++)
src->load_column(&data->alloc, columns);
*(columns++)= NULL;
}
}
*prev_row= NULL;
data->embedded_info->prev_ptr= prev_row;
return_ok:
net_send_eof(thd, thd->server_status,
thd->get_stmt_da()->current_statement_warn_count());
DBUG_RETURN(0);
err:
DBUG_RETURN(1);
}
#endif /*HAVE_QUERY_CACHE*/