mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
cleanup: simplify multi-update's juggling with positions
introduce Item_temptable_rowid() that is used to store table->file->position() in the temporary table record
This commit is contained in:
@ -5204,3 +5204,23 @@ null:
|
|||||||
my_free(names);
|
my_free(names);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item_temptable_rowid::Item_temptable_rowid(TABLE *table_arg)
|
||||||
|
: Item_str_func(table_arg->in_use), table(table_arg)
|
||||||
|
{
|
||||||
|
max_length= table->file->ref_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Item_temptable_rowid::fix_length_and_dec()
|
||||||
|
{
|
||||||
|
used_tables_cache= table->map;
|
||||||
|
const_item_cache= false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String *Item_temptable_rowid::val_str(String *str)
|
||||||
|
{
|
||||||
|
if (!((null_value= table->null_row)))
|
||||||
|
table->file->position(table->record[0]);
|
||||||
|
str_value.set((char*)(table->file->ref), max_length, &my_charset_bin);
|
||||||
|
return &str_value;
|
||||||
|
}
|
||||||
|
@ -1751,5 +1751,24 @@ public:
|
|||||||
{ return get_item_copy<Item_func_dyncol_list>(thd, this); }
|
{ return get_item_copy<Item_func_dyncol_list>(thd, this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* ITEM_STRFUNC_INCLUDED */
|
/*
|
||||||
|
this is used by JOIN_TAB::keep_current_rowid
|
||||||
|
and stores handler::position().
|
||||||
|
It has nothing to do with _rowid pseudo-column, that the parser supports.
|
||||||
|
*/
|
||||||
|
class Item_temptable_rowid :public Item_str_func
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TABLE *table;
|
||||||
|
Item_temptable_rowid(TABLE *table_arg);
|
||||||
|
const Type_handler *type_handler() const { return &type_handler_string; }
|
||||||
|
Field *create_tmp_field(bool group, TABLE *table)
|
||||||
|
{ return create_table_field_from_handler(table); }
|
||||||
|
String *val_str(String *str);
|
||||||
|
const char *func_name() const { return "<rowid>"; }
|
||||||
|
void fix_length_and_dec();
|
||||||
|
Item *get_copy(THD *thd)
|
||||||
|
{ return get_item_copy<Item_temptable_rowid>(thd, this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* ITEM_STRFUNC_INCLUDED */
|
||||||
|
@ -23400,13 +23400,10 @@ get_sort_by_table(ORDER *a,ORDER *b, List<TABLE_LIST> &tables,
|
|||||||
calc how big buffer we need for comparing group entries.
|
calc how big buffer we need for comparing group entries.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
void calc_group_buffer(TMP_TABLE_PARAM *param, ORDER *group)
|
||||||
calc_group_buffer(JOIN *join,ORDER *group)
|
|
||||||
{
|
{
|
||||||
uint key_length=0, parts=0, null_parts=0;
|
uint key_length=0, parts=0, null_parts=0;
|
||||||
|
|
||||||
if (group)
|
|
||||||
join->group= 1;
|
|
||||||
for (; group ; group=group->next)
|
for (; group ; group=group->next)
|
||||||
{
|
{
|
||||||
Item *group_item= *group->item;
|
Item *group_item= *group->item;
|
||||||
@ -23476,9 +23473,16 @@ calc_group_buffer(JOIN *join,ORDER *group)
|
|||||||
if (group_item->maybe_null)
|
if (group_item->maybe_null)
|
||||||
null_parts++;
|
null_parts++;
|
||||||
}
|
}
|
||||||
join->tmp_table_param.group_length=key_length+null_parts;
|
param->group_length= key_length + null_parts;
|
||||||
join->tmp_table_param.group_parts=parts;
|
param->group_parts= parts;
|
||||||
join->tmp_table_param.group_null_parts=null_parts;
|
param->group_null_parts= null_parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void calc_group_buffer(JOIN *join, ORDER *group)
|
||||||
|
{
|
||||||
|
if (group)
|
||||||
|
join->group= 1;
|
||||||
|
calc_group_buffer(&join->tmp_table_param, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2382,6 +2382,7 @@ int append_possible_keys(MEM_ROOT *alloc, String_list &list, TABLE *table,
|
|||||||
#define RATIO_TO_PACK_ROWS 2
|
#define RATIO_TO_PACK_ROWS 2
|
||||||
#define MIN_STRING_LENGTH_TO_PACK_ROWS 10
|
#define MIN_STRING_LENGTH_TO_PACK_ROWS 10
|
||||||
|
|
||||||
|
void calc_group_buffer(TMP_TABLE_PARAM *param, ORDER *group);
|
||||||
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
TABLE *create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
||||||
ORDER *group, bool distinct, bool save_sum_fields,
|
ORDER *group, bool distinct, bool save_sum_fields,
|
||||||
ulonglong select_options, ha_rows rows_limit,
|
ulonglong select_options, ha_rows rows_limit,
|
||||||
|
@ -2167,22 +2167,12 @@ loop_end:
|
|||||||
tbl->prepare_for_position();
|
tbl->prepare_for_position();
|
||||||
join->map2table[tbl->tablenr]->keep_current_rowid= true;
|
join->map2table[tbl->tablenr]->keep_current_rowid= true;
|
||||||
|
|
||||||
Field_string *field= new Field_string(tbl->file->ref_length, 0,
|
Item_temptable_rowid *item=
|
||||||
&field_name,
|
new (thd->mem_root) Item_temptable_rowid(tbl);
|
||||||
&my_charset_bin);
|
if (!item)
|
||||||
if (!field)
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
field->init(tbl);
|
|
||||||
/*
|
|
||||||
The field will be converted to varstring when creating tmp table if
|
|
||||||
table to be updated was created by mysql 4.1. Deny this.
|
|
||||||
*/
|
|
||||||
field->can_alter_field_type= 0;
|
|
||||||
Item_field *ifield= new (thd->mem_root) Item_field(join->thd, (Field *) field);
|
|
||||||
if (!ifield)
|
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
ifield->maybe_null= 0;
|
item->fix_fields(thd, 0);
|
||||||
if (temp_fields.push_back(ifield, thd->mem_root))
|
if (temp_fields.push_back(item, thd->mem_root))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
} while ((tbl= tbl_it++));
|
} while ((tbl= tbl_it++));
|
||||||
|
|
||||||
@ -2193,10 +2183,10 @@ loop_end:
|
|||||||
group.direction= ORDER::ORDER_ASC;
|
group.direction= ORDER::ORDER_ASC;
|
||||||
group.item= (Item**) temp_fields.head_ref();
|
group.item= (Item**) temp_fields.head_ref();
|
||||||
|
|
||||||
tmp_param->quick_group=1;
|
tmp_param->quick_group= 1;
|
||||||
tmp_param->field_count=temp_fields.elements;
|
tmp_param->field_count= temp_fields.elements;
|
||||||
tmp_param->group_parts=1;
|
tmp_param->func_count= temp_fields.elements - 1;
|
||||||
tmp_param->group_length= table->file->ref_length;
|
calc_group_buffer(tmp_param, &group);
|
||||||
/* small table, ignore SQL_BIG_TABLES */
|
/* small table, ignore SQL_BIG_TABLES */
|
||||||
my_bool save_big_tables= thd->variables.big_tables;
|
my_bool save_big_tables= thd->variables.big_tables;
|
||||||
thd->variables.big_tables= FALSE;
|
thd->variables.big_tables= FALSE;
|
||||||
@ -2384,29 +2374,11 @@ int multi_update::send_data(List<Item> ¬_used_values)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
TABLE *tmp_table= tmp_tables[offset];
|
TABLE *tmp_table= tmp_tables[offset];
|
||||||
/*
|
if (copy_funcs(tmp_table_param[offset].items_to_copy, thd))
|
||||||
For updatable VIEW store rowid of the updated table and
|
DBUG_RETURN(1);
|
||||||
rowids of tables used in the CHECK OPTION condition.
|
|
||||||
*/
|
|
||||||
uint field_num= 0;
|
|
||||||
List_iterator_fast<TABLE> tbl_it(unupdated_check_opt_tables);
|
|
||||||
/* Set first tbl = table and then tbl to tables from tbl_it */
|
|
||||||
TABLE *tbl= table;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
tbl->file->position(tbl->record[0]);
|
|
||||||
memcpy((char*) tmp_table->field[field_num]->ptr,
|
|
||||||
(char*) tbl->file->ref, tbl->file->ref_length);
|
|
||||||
/*
|
|
||||||
For outer joins a rowid field may have no NOT_NULL_FLAG,
|
|
||||||
so we have to reset NULL bit for this field.
|
|
||||||
(set_notnull() resets NULL bit only if available).
|
|
||||||
*/
|
|
||||||
tmp_table->field[field_num]->set_notnull();
|
|
||||||
field_num++;
|
|
||||||
} while ((tbl= tbl_it++));
|
|
||||||
|
|
||||||
/* Store regular updated fields in the row. */
|
/* Store regular updated fields in the row. */
|
||||||
|
DBUG_ASSERT(1 + unupdated_check_opt_tables.elements ==
|
||||||
|
tmp_table_param[offset].func_count);
|
||||||
fill_record(thd, tmp_table,
|
fill_record(thd, tmp_table,
|
||||||
tmp_table->field + 1 + unupdated_check_opt_tables.elements,
|
tmp_table->field + 1 + unupdated_check_opt_tables.elements,
|
||||||
*values_for_table[offset], TRUE, FALSE);
|
*values_for_table[offset], TRUE, FALSE);
|
||||||
|
Reference in New Issue
Block a user