1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00
BitKeeper/etc/logging_ok:
  auto-union
BUILD/autorun.sh:
  Auto merged
BitKeeper/etc/config:
  Auto merged
Makefile.am:
  Auto merged
include/my_bitmap.h:
  Auto merged
libmysqld/Makefile.am:
  Auto merged
mysql-test/mysql-test-run.pl:
  Auto merged
mysql-test/mysql-test-run.sh:
  Auto merged
mysql-test/r/grant.result:
  Auto merged
mysql-test/r/ps_6bdb.result:
  Auto merged
mysql-test/r/ps_7ndb.result:
  Auto merged
mysys/Makefile.am:
  Auto merged
mysys/default.c:
  Auto merged
scripts/mysql_create_system_tables.sh:
  Auto merged
scripts/mysql_fix_privilege_tables.sql:
  Auto merged
sql/Makefile.am:
  Auto merged
sql/field.cc:
  Auto merged
sql/field.h:
  Auto merged
sql/ha_ndbcluster.h:
  Auto merged
sql/handler.cc:
  Auto merged
sql/handler.h:
  Auto merged
sql/item.cc:
  Auto merged
sql/log_event.cc:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/opt_range.cc:
  Auto merged
sql/sql_acl.cc:
  Auto merged
sql/sql_acl.h:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_cache.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_delete.cc:
  Auto merged
sql/sql_lex.cc:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_table.cc:
  Auto merged
sql/sql_udf.cc:
  Auto merged
sql/sql_yacc.yy:
  Auto merged
storage/heap/Makefile.am:
  Auto merged
storage/heap/hp_hash.c:
  Auto merged
storage/innobase/btr/btr0btr.c:
  Auto merged
storage/innobase/btr/btr0cur.c:
  Auto merged
storage/innobase/configure.in:
  Auto merged
storage/innobase/fil/fil0fil.c:
  Auto merged
storage/innobase/ibuf/ibuf0ibuf.c:
  Auto merged
storage/innobase/include/os0file.h:
  Auto merged
storage/innobase/include/page0cur.h:
  Auto merged
storage/innobase/include/row0mysql.h:
  Auto merged
storage/innobase/include/srv0srv.h:
  Auto merged
storage/innobase/include/trx0trx.h:
  Auto merged
storage/innobase/include/trx0trx.ic:
  Auto merged
storage/innobase/lock/lock0lock.c:
  Auto merged
storage/innobase/log/log0recv.c:
  Auto merged
storage/innobase/os/os0file.c:
  Auto merged
storage/innobase/page/page0cur.c:
  Auto merged
storage/innobase/page/page0page.c:
  Auto merged
storage/innobase/rem/rem0rec.c:
  Auto merged
storage/innobase/row/row0mysql.c:
  Auto merged
storage/innobase/row/row0sel.c:
  Auto merged
storage/innobase/row/row0upd.c:
  Auto merged
storage/innobase/srv/srv0srv.c:
  Auto merged
storage/innobase/trx/trx0trx.c:
  Auto merged
storage/innobase/trx/trx0undo.c:
  Auto merged
storage/myisam/Makefile.am:
  Auto merged
storage/myisam/mi_create.c:
  Auto merged
storage/myisam/mi_open.c:
  Auto merged
storage/myisam/mi_packrec.c:
  Auto merged
storage/myisam/mi_unique.c:
  Auto merged
storage/myisam/myisampack.c:
  Auto merged
storage/myisammrg/Makefile.am:
  Auto merged
storage/ndb/include/mgmcommon/ConfigRetriever.hpp:
  Auto merged
storage/ndb/include/transporter/TransporterDefinitions.hpp:
  Auto merged
storage/ndb/src/common/mgmcommon/ConfigRetriever.cpp:
  Auto merged
storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp:
  Auto merged
storage/ndb/src/mgmsrv/main.cpp:
  Auto merged
storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp:
  Auto merged
storage/ndb/test/ndbapi/create_tab.cpp:
  Auto merged
storage/ndb/test/ndbapi/testBlobs.cpp:
  Auto merged
strings/ctype-big5.c:
  Auto merged
strings/ctype-ucs2.c:
  Auto merged
support-files/mysql.spec.sh:
  Auto merged
configure.in:
  merge
mysql-test/t/disabled.def:
  merge
mysys/my_bitmap.c:
  SCCS merged
sql/ha_federated.cc:
  merge
sql/ha_innodb.cc:
  merge
sql/ha_ndbcluster.cc:
  merge
sql/mysqld.cc:
  e
  merge
sql/sql_insert.cc:
  merge
sql/sql_lex.h:
  merge
sql/sql_load.cc:
  merge
sql/sql_select.cc:
  merge
  e
  C
sql/sql_update.cc:
  merge
sql/table.cc:
  merge
This commit is contained in:
unknown
2005-07-12 20:01:22 +02:00
317 changed files with 12088 additions and 4363 deletions

View File

@ -28,8 +28,6 @@
#include <hash.h>
#include <ft_global.h>
typedef uint32 cache_rec_length_type;
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
"MAYBE_REF","ALL","range","index","fulltext",
"ref_or_null","unique_subquery","index_subquery",
@ -87,10 +85,9 @@ static void update_depend_map(JOIN *join, ORDER *order);
static ORDER *remove_const(JOIN *join,ORDER *first_order,COND *cond,
bool change_list, bool *simple_order);
static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables,
List<Item> &fields, bool send_row,
uint select_options, const char *info,
Item *having, Procedure *proc,
SELECT_LEX_UNIT *unit);
List<Item> &fields, bool send_row,
uint select_options, const char *info,
Item *having);
static COND *build_equal_items(THD *thd, COND *cond,
COND_EQUAL *inherited,
List<TABLE_LIST> *join_list,
@ -183,10 +180,10 @@ static void reset_cache_read(JOIN_CACHE *cache);
static void reset_cache_write(JOIN_CACHE *cache);
static void read_cached_record(JOIN_TAB *tab);
static bool cmp_buffer_with_ref(JOIN_TAB *tab);
static bool setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
List<Item> &all_fields,ORDER *new_order);
static ORDER *create_distinct_group(THD *thd, ORDER *order,
List<Item> &fields,
static bool setup_new_fields(THD *thd, List<Item> &fields,
List<Item> &all_fields, ORDER *new_order);
static ORDER *create_distinct_group(THD *thd, Item **ref_pointer_array,
ORDER *order, List<Item> &fields,
bool *all_order_by_fields_used);
static bool test_if_subpart(ORDER *a,ORDER *b);
static TABLE *get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables);
@ -284,6 +281,7 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array,
save_allow_sum_func= thd->allow_sum_func;
thd->allow_sum_func= 0;
res= setup_conds(thd, tables, leaves, conds);
thd->allow_sum_func= save_allow_sum_func;
res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields,
order);
@ -340,11 +338,12 @@ JOIN::prepare(Item ***rref_pointer_array,
/* Check that all tables, fields, conds and order are ok */
if ((!(select_options & OPTION_SETUP_TABLES_DONE) &&
setup_tables(thd, tables_list, &conds, &select_lex->leaf_tables,
setup_tables(thd, &select_lex->context,
tables_list, &conds, &select_lex->leaf_tables,
FALSE)) ||
setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
select_lex->setup_ref_array(thd, og_num) ||
setup_fields(thd, (*rref_pointer_array), tables_list, fields_list, 1,
setup_fields(thd, (*rref_pointer_array), fields_list, 1,
&all_fields, 1) ||
setup_without_group(thd, (*rref_pointer_array), tables_list,
select_lex->leaf_tables, fields_list,
@ -360,7 +359,7 @@ JOIN::prepare(Item ***rref_pointer_array,
thd->allow_sum_func=1;
select_lex->having_fix_field= 1;
bool having_fix_rc= (!having->fixed &&
(having->fix_fields(thd, tables_list, &having) ||
(having->fix_fields(thd, &having) ||
having->check_cols(1)));
select_lex->having_fix_field= 0;
if (having_fix_rc || thd->net.report_error)
@ -433,7 +432,7 @@ JOIN::prepare(Item ***rref_pointer_array,
goto err; /* purecov: inspected */
if (procedure)
{
if (setup_new_fields(thd, tables_list, fields_list, all_fields,
if (setup_new_fields(thd, fields_list, all_fields,
procedure->param_fields))
goto err; /* purecov: inspected */
if (procedure->group)
@ -567,7 +566,7 @@ JOIN::optimize()
Item_cond_and can't be fixed after creation, so we do not check
conds->fixed
*/
conds->fix_fields(thd, tables_list, &conds);
conds->fix_fields(thd, &conds);
conds->change_ref_to_fields(thd, tables_list);
conds->top_level_item();
having= 0;
@ -780,7 +779,8 @@ JOIN::optimize()
bool all_order_fields_used;
if (order)
skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1);
if ((group_list=create_distinct_group(thd, order, fields_list,
if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array,
order, fields_list,
&all_order_fields_used)))
{
bool skip_group= (skip_sort_order &&
@ -1114,7 +1114,6 @@ int
JOIN::reinit()
{
DBUG_ENTER("JOIN::reinit");
first_record= 0;
if (exec_tmp_table1)
@ -1223,8 +1222,7 @@ JOIN::exec()
send_row_on_empty_set(),
select_options,
zero_result_cause,
having, procedure,
unit);
having);
DBUG_VOID_RETURN;
}
@ -1433,7 +1431,7 @@ JOIN::exec()
DBUG_VOID_RETURN;
}
end_read_record(&curr_join->join_tab->read_record);
curr_join->const_tables= curr_join->tables; // Mark free for join_free()
curr_join->const_tables= curr_join->tables; // Mark free for cleanup()
curr_join->join_tab[0].table= 0; // Table is freed
// No sum funcs anymore
@ -1663,9 +1661,9 @@ JOIN::exec()
*/
int
JOIN::cleanup()
JOIN::destroy()
{
DBUG_ENTER("JOIN::cleanup");
DBUG_ENTER("JOIN::destroy");
select_lex->join= 0;
if (tmp_join)
@ -1680,12 +1678,11 @@ JOIN::cleanup()
}
tmp_join->tmp_join= 0;
tmp_table_param.copy_field=0;
DBUG_RETURN(tmp_join->cleanup());
DBUG_RETURN(tmp_join->destroy());
}
cond_equal= 0;
lock=0; // It's faster to unlock later
join_free(1);
cleanup(1);
if (exec_tmp_table1)
free_tmp_table(thd, exec_tmp_table1);
if (exec_tmp_table2)
@ -1693,12 +1690,6 @@ JOIN::cleanup()
delete select;
delete_dynamic(&keyuse);
delete procedure;
for (SELECT_LEX_UNIT *lex_unit= select_lex->first_inner_unit();
lex_unit != 0;
lex_unit= lex_unit->next_unit())
{
error|= lex_unit->cleanup();
}
DBUG_RETURN(error);
}
@ -1742,6 +1733,7 @@ Cursor::init_from_thd(THD *thd)
lock= thd->lock;
query_id= thd->query_id;
free_list= thd->free_list;
change_list= thd->change_list;
reset_thd(thd);
/*
XXX: thd->locked_tables is not changed.
@ -1758,6 +1750,7 @@ Cursor::reset_thd(THD *thd)
thd->open_tables= 0;
thd->lock= 0;
thd->free_list= 0;
thd->change_list.empty();
}
@ -1831,6 +1824,7 @@ Cursor::fetch(ulong num_rows)
thd->open_tables= open_tables;
thd->lock= lock;
thd->query_id= query_id;
thd->change_list= change_list;
/* save references to memory, allocated during fetch */
thd->set_n_backup_item_arena(this, &backup_arena);
@ -1847,10 +1841,8 @@ Cursor::fetch(ulong num_rows)
#ifdef USING_TRANSACTIONS
ha_release_temporary_latches(thd);
#endif
/* Grab free_list here to correctly free it in close */
thd->restore_backup_item_arena(this, &backup_arena);
DBUG_ASSERT(thd->free_list == 0);
reset_thd(thd);
if (error == NESTED_LOOP_CURSOR_LIMIT)
{
@ -1858,10 +1850,12 @@ Cursor::fetch(ulong num_rows)
thd->server_status|= SERVER_STATUS_CURSOR_EXISTS;
::send_eof(thd);
thd->server_status&= ~SERVER_STATUS_CURSOR_EXISTS;
change_list= thd->change_list;
reset_thd(thd);
}
else
{
close();
close(TRUE);
if (error == NESTED_LOOP_OK)
{
thd->server_status|= SERVER_STATUS_LAST_ROW_SENT;
@ -1876,22 +1870,23 @@ Cursor::fetch(ulong num_rows)
void
Cursor::close()
Cursor::close(bool is_active)
{
THD *thd= join->thd;
DBUG_ENTER("Cursor::close");
join->join_free(0);
/*
In case of UNIONs JOIN is freed inside of unit->cleanup(),
otherwise in select_lex->cleanup().
*/
if (unit)
{
/* In case of UNIONs JOIN is freed inside unit->cleanup() */
unit->cleanup();
}
(void) unit->cleanup();
else
(void) join->select_lex->cleanup();
if (is_active)
close_thread_tables(thd);
else
{
join->cleanup();
delete join;
}
{
/* XXX: Another hack: closing tables used in the cursor */
DBUG_ASSERT(lock || open_tables || derived_tables);
@ -1910,13 +1905,8 @@ Cursor::close()
}
join= 0;
unit= 0;
free_items(free_list);
free_list= 0;
/*
Must be last, as some memory might be allocated for free purposes,
like in free_tmp_table() (TODO: fix this issue)
*/
free_root(mem_root, MYF(0));
free_items();
change_list.empty();
DBUG_VOID_RETURN;
}
@ -1924,7 +1914,7 @@ Cursor::close()
Cursor::~Cursor()
{
if (is_open())
close();
close(FALSE);
}
/*********************************************************************/
@ -1986,6 +1976,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
bool free_join= 1;
DBUG_ENTER("mysql_select");
select_lex->context.resolve_in_select_list= TRUE;
JOIN *join;
if (select_lex->join != 0)
{
@ -2068,8 +2059,7 @@ err:
if (free_join)
{
thd->proc_info="end";
err= join->cleanup();
delete join;
err= select_lex->cleanup();
DBUG_RETURN(err || thd->net.report_error);
}
DBUG_RETURN(join->error);
@ -5902,29 +5892,68 @@ void JOIN_TAB::cleanup()
}
void JOIN::join_free(bool full)
{
SELECT_LEX_UNIT *unit;
SELECT_LEX *sl;
DBUG_ENTER("JOIN::join_free");
/*
Optimization: if not EXPLAIN and we are done with the JOIN,
free all tables.
*/
full= full || (!select_lex->uncacheable && !thd->lex->describe);
cleanup(full);
for (unit= select_lex->first_inner_unit(); unit; unit= unit->next_unit())
for (sl= unit->first_select_in_union(); sl; sl= sl->next_select())
{
JOIN *join= sl->join;
if (join)
join->join_free(full);
}
/*
We are not using tables anymore
Unlock all tables. We may be in an INSERT .... SELECT statement.
*/
if (full && lock && thd->lock && !(select_options & SELECT_NO_UNLOCK) &&
!select_lex->subquery_in_having &&
(select_lex == (thd->lex->unit.fake_select_lex ?
thd->lex->unit.fake_select_lex : &thd->lex->select_lex)))
{
/*
TODO: unlock tables even if the join isn't top level select in the
tree.
*/
mysql_unlock_read_tables(thd, lock); // Don't free join->lock
lock= 0;
}
DBUG_VOID_RETURN;
}
/*
Free resources of given join
SYNOPSIS
JOIN::join_free()
JOIN::cleanup()
fill - true if we should free all resources, call with full==1 should be
last, before it this function can be called with full==0
NOTE: with subquery this function definitely will be called several times,
but even for simple query it can be called several times.
*/
void
JOIN::join_free(bool full)
{
JOIN_TAB *tab,*end;
DBUG_ENTER("JOIN::join_free");
full= full || (!select_lex->uncacheable &&
!thd->lex->subqueries &&
!thd->lex->describe); // do not cleanup too early on EXPLAIN
void JOIN::cleanup(bool full)
{
DBUG_ENTER("JOIN::cleanup");
if (table)
{
JOIN_TAB *tab,*end;
/*
Only a sorted table may be cached. This sorted table is always the
first non const table in join->table
@ -5935,16 +5964,6 @@ JOIN::join_free(bool full)
filesort_free_buffers(table[const_tables]);
}
for (SELECT_LEX_UNIT *unit= select_lex->first_inner_unit(); unit;
unit= unit->next_unit())
{
JOIN *join;
for (SELECT_LEX *sl= unit->first_select_in_union(); sl;
sl= sl->next_select())
if ((join= sl->join))
join->join_free(full);
}
if (full)
{
for (tab= join_tab, end= tab+tables; tab != end; tab++)
@ -5961,25 +5980,14 @@ JOIN::join_free(bool full)
}
}
}
/*
We are not using tables anymore
Unlock all tables. We may be in an INSERT .... SELECT statement.
*/
if (full && lock && thd->lock && !(select_options & SELECT_NO_UNLOCK) &&
!select_lex->subquery_in_having)
{
// TODO: unlock tables even if the join isn't top level select in the tree
if (select_lex == (thd->lex->unit.fake_select_lex ?
thd->lex->unit.fake_select_lex : &thd->lex->select_lex))
{
mysql_unlock_read_tables(thd, lock); // Don't free join->lock
lock=0;
}
}
if (full)
{
if (tmp_join)
tmp_table_param.copy_field= 0;
group_fields.delete_elements();
/*
We can't call delete_elements() on copy_funcs as this will cause
@ -6214,8 +6222,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
static int
return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
List<Item> &fields, bool send_row, uint select_options,
const char *info, Item *having, Procedure *procedure,
SELECT_LEX_UNIT *unit)
const char *info, Item *having)
{
DBUG_ENTER("return_zero_rows");
@ -7438,7 +7445,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
conds->top_level_item();
/* conds is always a new item as both cond and on_expr existed */
DBUG_ASSERT(!conds->fixed);
conds->fix_fields(join->thd, 0, &conds);
conds->fix_fields(join->thd, &conds);
}
else
conds= table->on_expr;
@ -7659,7 +7666,7 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
cond->fixed, also it do not need tables so we use 0 as second
argument.
*/
cond->fix_fields(thd, 0, &cond);
cond->fix_fields(thd, &cond);
}
thd->insert_id(0); // Clear for next request
}
@ -7678,7 +7685,7 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
cond->fixed, also it do not need tables so we use 0 as second
argument.
*/
cond->fix_fields(thd, 0, &cond);
cond->fix_fields(thd, &cond);
}
}
}
@ -7950,7 +7957,9 @@ Field *create_tmp_field_for_schema(THD *thd, Item *item, TABLE *table)
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
Item ***copy_func, Field **from_field,
bool group, bool modify_item, uint convert_blob_length)
bool group, bool modify_item,
bool table_cant_handle_bit_fields,
uint convert_blob_length)
{
switch (type) {
case Item::SUM_FUNC_ITEM:
@ -7965,15 +7974,20 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
case Item::DEFAULT_VALUE_ITEM:
{
Item_field *field= (Item_field*) item;
if (table_cant_handle_bit_fields && field->field->type() == FIELD_TYPE_BIT)
return create_tmp_field_from_item(thd, item, table, copy_func,
modify_item, convert_blob_length);
return create_tmp_field_from_field(thd, (*from_field= field->field),
item->name, table,
modify_item ? (Item_field*) item : NULL,
convert_blob_length);
}
case Item::REF_ITEM:
if ( item->real_item()->type() == Item::FIELD_ITEM)
{
Item *tmp_item;
if ((tmp_item= item->real_item())->type() == Item::FIELD_ITEM)
{
Item_field *field= (Item_field*) *((Item_ref*)item)->ref;
Item_field *field= (Item_field*) tmp_item;
Field *new_field= create_tmp_field_from_field(thd,
(*from_field= field->field),
item->name, table,
@ -7983,6 +7997,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
item->set_result_field(new_field);
return new_field;
}
}
case Item::FUNC_ITEM:
case Item::COND_ITEM:
case Item::FIELD_AVG_ITEM:
@ -8186,6 +8201,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
Field *new_field=
create_tmp_field(thd, table, arg, arg->type(), &copy_func,
tmp_from_field, group != 0,not_all_columns,
group || distinct,
param->convert_blob_length);
if (!new_field)
goto err; // Should be OOM
@ -8196,6 +8212,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
*blob_field++= (uint) (reg_field - table->field);
blob_count++;
}
new_field->field_index= (uint) (reg_field - table->field);
*(reg_field++)= new_field;
if (new_field->real_type() == MYSQL_TYPE_STRING ||
new_field->real_type() == MYSQL_TYPE_VARCHAR)
@ -8234,7 +8251,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
create_tmp_field_for_schema(thd, item, table) :
create_tmp_field(thd, table, item, type, &copy_func,
tmp_from_field, group != 0,
not_all_columns || group !=0,
not_all_columns || group != 0, 0,
param->convert_blob_length);
if (!new_field)
@ -8263,6 +8280,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
}
new_field->query_id= thd->query_id;
new_field->fieldnr= ++fieldnr;
new_field->field_index= (uint) (reg_field - table->field);
*(reg_field++) =new_field;
}
if (!--hidden_field_count)
@ -8377,6 +8395,13 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
}
else
field->move_field((char*) pos,(uchar*) 0,0);
if (field->type() == FIELD_TYPE_BIT)
{
/* We have to reserve place for extra bits among null bits */
((Field_bit*) field)->set_bit_ptr(null_flags + null_count / 8,
null_count & 7);
null_count+= (field->field_length & 7);
}
field->reset();
if (from_field[i])
{ /* Not a table Item */
@ -11168,8 +11193,7 @@ static bool fix_having(JOIN *join, Item **having)
else // This should never happen
if (!(table->select->cond= new Item_cond_and(table->select->cond,
sort_table_cond)) ||
table->select->cond->fix_fields(join->thd, join->tables_list,
&table->select->cond))
table->select->cond->fix_fields(join->thd, &table->select->cond))
return 1;
table->select_cond=table->select->cond;
table->select_cond->top_level_item();
@ -11619,7 +11643,7 @@ used_blob_length(CACHE_FIELD **ptr)
static bool
store_record_in_cache(JOIN_CACHE *cache)
{
cache_rec_length_type length;
uint length;
uchar *pos;
CACHE_FIELD *copy,*end_field;
bool last_record;
@ -11664,9 +11688,9 @@ store_record_in_cache(JOIN_CACHE *cache)
end > str && end[-1] == ' ' ;
end--) ;
length=(uint) (end-str);
memcpy(pos+sizeof(length), str, length);
memcpy_fixed(pos, &length, sizeof(length));
pos+= length+sizeof(length);
memcpy(pos+2, str, length);
int2store(pos, length);
pos+= length+2;
}
else
{
@ -11700,7 +11724,7 @@ static void
read_cached_record(JOIN_TAB *tab)
{
uchar *pos;
cache_rec_length_type length;
uint length;
bool last_record;
CACHE_FIELD *copy,*end_field;
@ -11729,10 +11753,10 @@ read_cached_record(JOIN_TAB *tab)
{
if (copy->strip)
{
memcpy_fixed(&length, pos, sizeof(length));
memcpy(copy->str, pos+sizeof(length), length);
length= uint2korr(pos);
memcpy(copy->str, pos+2, length);
memset(copy->str+length, ' ', copy->length-length);
pos+= sizeof(length)+length;
pos+= 2 + length;
}
else
{
@ -11769,10 +11793,10 @@ cp_buffer_from_ref(THD *thd, TABLE_REF *ref)
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
for (store_key **copy=ref->key_copy ; *copy ; copy++)
{
if ((*copy)->copy())
if ((*copy)->copy() & 1)
{
thd->count_cuted_fields= save_count_cuted_fields;
return 1; // Something went wrong
return 1; // Something went wrong
}
}
thd->count_cuted_fields= save_count_cuted_fields;
@ -11789,14 +11813,13 @@ cp_buffer_from_ref(THD *thd, TABLE_REF *ref)
SYNOPSIS
find_order_in_list()
thd [in] Pointer to current thread structure
ref_pointer_array [in/out] All select, group and order by fields
tables [in] List of tables to search in (usually FROM clause)
order [in] Column reference to be resolved
fields [in] List of fields to search in (usually SELECT list)
all_fields [in/out] All select, group and order by fields
is_group_field [in] True if order is a GROUP field, false if
ORDER by field
thd Pointer to current thread structure
ref_pointer_array All select, group and order by fields
tables List of tables to search in (usually FROM clause)
order Column reference to be resolved
fields List of fields to search in (usually SELECT list)
all_fields All select, group and order by fields
is_group_field True if order is a GROUP field, false if ORDER by field
DESCRIPTION
Given a column reference (represented by 'order') from a GROUP BY or ORDER
@ -11813,6 +11836,8 @@ cp_buffer_from_ref(THD *thd, TABLE_REF *ref)
RETURN
FALSE if OK
TRUE if error occurred
ref_pointer_array and all_fields are updated
*/
static bool
@ -11858,26 +11883,25 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
original field name, we should additionaly check if we have conflict
for this name (in case if we would perform lookup in all tables).
*/
if (unaliased && !order_item->fixed && order_item->fix_fields(thd, tables,
order->item))
if (unaliased && !order_item->fixed &&
order_item->fix_fields(thd, order->item))
return TRUE;
/* Lookup the current GROUP field in the FROM clause. */
order_item_type= order_item->type();
from_field= (Field*) not_found_field;
if (is_group_field &&
order_item_type == Item::FIELD_ITEM ||
order_item_type == Item::REF_ITEM)
{
from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
&view_ref, IGNORE_ERRORS, TRUE);
if(!from_field)
from_field= (Field*) not_found_field;
&view_ref, IGNORE_ERRORS, TRUE,
FALSE);
if (!from_field)
from_field= (Field*) not_found_field;
}
else
from_field= (Field*) not_found_field;
if (from_field == not_found_field ||
from_field &&
(from_field != view_ref_found ?
/* it is field of base table => check that fields are same */
((*select_item)->type() == Item::FIELD_ITEM &&
@ -11890,43 +11914,46 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
view_ref->type() == Item::REF_ITEM &&
((Item_ref *) (*select_item))->ref ==
((Item_ref *) view_ref)->ref)))
/*
If there is no such field in the FROM clause, or it is the same field as
the one found in the SELECT clause, then use the Item created for the
SELECT field. As a result if there was a derived field that 'shadowed'
a table field with the same name, the table field will be chosen over
the derived field.
*/
{
/*
If there is no such field in the FROM clause, or it is the same field
as the one found in the SELECT clause, then use the Item created for
the SELECT field. As a result if there was a derived field that
'shadowed' a table field with the same name, the table field will be
chosen over the derived field.
*/
order->item= ref_pointer_array + counter;
order->in_field_list=1;
return FALSE;
}
else
{
/*
There is a field with the same name in the FROM clause. This is the field
that will be chosen. In this case we issue a warning so the user knows
that the field from the FROM clause overshadows the column reference from
the SELECT list.
There is a field with the same name in the FROM clause. This
is the field that will be chosen. In this case we issue a
warning so the user knows that the field from the FROM clause
overshadows the column reference from the SELECT list.
*/
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
ER(ER_NON_UNIQ_ERROR), from_field->field_name,
current_thd->where);
}
}
order->in_field_list=0;
/*
The call to order_item->fix_fields() means that here we resolve 'order_item'
to a column from a table in the list 'tables', or to a column in some outer
query. Exactly because of the second case we come to this point even if
(select_item == not_found_item), inspite of that fix_fields() calls
find_item_in_list() one more time.
The call to order_item->fix_fields() means that here we resolve
'order_item' to a column from a table in the list 'tables', or to
a column in some outer query. Exactly because of the second case
we come to this point even if (select_item == not_found_item),
inspite of that fix_fields() calls find_item_in_list() one more
time.
We check order_item->fixed because Item_func_group_concat can put
arguments for which fix_fields already was called.
*/
if (!order_item->fixed &&
(order_item->fix_fields(thd, tables, order->item) ||
(order_item->fix_fields(thd, order->item) ||
(order_item= *order->item)->check_cols(1) ||
thd->is_fatal_error))
return TRUE; /* Wrong field. */
@ -12038,7 +12065,7 @@ setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
*/
static bool
setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
setup_new_fields(THD *thd, List<Item> &fields,
List<Item> &all_fields, ORDER *new_field)
{
Item **item;
@ -12055,7 +12082,7 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
else
{
thd->where="procedure list";
if ((*new_field->item)->fix_fields(thd, tables, new_field->item))
if ((*new_field->item)->fix_fields(thd, new_field->item))
DBUG_RETURN(1); /* purecov: inspected */
all_fields.push_front(*new_field->item);
new_field->item=all_fields.head_ref();
@ -12071,12 +12098,14 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
*/
static ORDER *
create_distinct_group(THD *thd, ORDER *order_list, List<Item> &fields,
create_distinct_group(THD *thd, Item **ref_pointer_array,
ORDER *order_list, List<Item> &fields,
bool *all_order_by_fields_used)
{
List_iterator<Item> li(fields);
Item *item;
ORDER *order,*group,**prev;
uint index= 0;
*all_order_by_fields_used= 1;
while ((item=li++))
@ -12108,11 +12137,17 @@ create_distinct_group(THD *thd, ORDER *order_list, List<Item> &fields,
ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER));
if (!ord)
return 0;
ord->item=li.ref();
/*
We have here only field_list (not all_field_list), so we can use
simple indexing of ref_pointer_array (order in the array and in the
list are same)
*/
ord->item= ref_pointer_array + index;
ord->asc=1;
*prev=ord;
prev= &ord->next;
}
index++;
}
*prev=0;
return group;
@ -12135,7 +12170,7 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
param->quick_group=1;
while ((field=li++))
{
Item::Type type=field->type();
Item::Type type=field->real_item()->type();
if (type == Item::FIELD_ITEM)
param->field_count++;
else if (type == Item::SUM_FUNC_ITEM)
@ -12149,7 +12184,7 @@ count_field_types(TMP_TABLE_PARAM *param, List<Item> &fields,
for (uint i=0 ; i < sum_item->arg_count ; i++)
{
if (sum_item->args[0]->type() == Item::FIELD_ITEM)
if (sum_item->args[0]->real_item()->type() == Item::FIELD_ITEM)
param->field_count++;
else
param->func_count++;
@ -12396,9 +12431,10 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
param->copy_funcs.empty();
for (i= 0; (pos= li++); i++)
{
if (pos->type() == Item::FIELD_ITEM)
if (pos->real_item()->type() == Item::FIELD_ITEM)
{
Item_field *item;
pos= pos->real_item();
if (!(item= new Item_field(thd, ((Item_field*) pos))))
goto err;
pos= item;
@ -12853,7 +12889,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
DBUG_RETURN(TRUE);
if (!cond->fixed)
cond->fix_fields(thd,(TABLE_LIST *) 0, (Item**)&cond);
cond->fix_fields(thd, (Item**)&cond);
if (join_tab->select)
{
error=(int) cond->add(join_tab->select->cond);
@ -12895,8 +12931,8 @@ void free_underlaid_joins(THD *thd, SELECT_LEX *select)
thd reference to the context
expr expression to make replacement
group_list list of references to group by items
changed out: returns 1 if item contains a replaced field item
changed out: returns 1 if item contains a replaced field item
DESCRIPTION
The function replaces occurrences of group by fields in expr
by ref objects for these fields unless they are under aggregate
@ -12925,6 +12961,7 @@ static bool change_group_ref(THD *thd, Item_func *expr, ORDER *group_list,
{
if (expr->arg_count)
{
Name_resolution_context *context= &thd->lex->current_select->context;
Item **arg,**arg_end;
for (arg= expr->arguments(),
arg_end= expr->arguments()+expr->arg_count;
@ -12938,8 +12975,9 @@ static bool change_group_ref(THD *thd, Item_func *expr, ORDER *group_list,
{
if (item->eq(*group_tmp->item,0))
{
Item *new_item;
if(!(new_item= new Item_ref(group_tmp->item, 0, item->name)))
Item *new_item;
if(!(new_item= new Item_ref(context, group_tmp->item, 0,
item->name)))
return 1; // fatal_error is set
thd->change_item_tree(arg, new_item);
*changed= TRUE;