1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Merge with 4.0.13

This commit is contained in:
monty@narttu.mysql.fi
2003-05-19 16:35:49 +03:00
317 changed files with 6662 additions and 3466 deletions

View File

@ -62,33 +62,46 @@ int mysql_update(THD *thd,
int error=0;
uint used_index, want_privilege;
ulong query_id=thd->query_id, timestamp_query_id;
ha_rows updated, found;
key_map old_used_keys;
TABLE *table;
SQL_SELECT *select;
READ_RECORD info;
TABLE_LIST *update_table_list= (TABLE_LIST*)
thd->lex.select_lex.table_list.first;
TABLE_LIST *update_table_list= ((TABLE_LIST*)
thd->lex.select_lex.table_list.first);
TABLE_LIST tables;
List<Item> all_fields;
DBUG_ENTER("mysql_update");
LINT_INIT(used_index);
LINT_INIT(timestamp_query_id);
if ((open_and_lock_tables(thd, table_list)))
DBUG_RETURN(-1);
thd->proc_info="init";
fix_tables_pointers(thd->lex.all_selects_list);
table= table_list->table;
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
thd->proc_info="init";
/* Calculate "table->used_keys" based on the WHERE */
table->used_keys=table->keys_in_use;
table->quick_keys=0;
want_privilege=table->grant.want_privilege;
table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege);
if (setup_tables(update_table_list) ||
setup_conds(thd,update_table_list,&conds)
|| setup_ftfuncs(&thd->lex.select_lex))
bzero((char*) &tables,sizeof(tables)); // For ORDER BY
tables.table= table;
if (setup_tables(update_table_list) ||
setup_conds(thd,update_table_list,&conds) ||
setup_ref_array(thd, &thd->lex.select_lex.ref_pointer_array,
order_num) ||
setup_order(thd, thd->lex.select_lex.ref_pointer_array,
&tables, fields, all_fields, order) ||
setup_ftfuncs(&thd->lex.select_lex))
DBUG_RETURN(-1); /* purecov: inspected */
/* Check that we are not using table that we are updating in a sub select */
if (find_real_table_in_list(table_list->next,
table_list->db, table_list->real_name))
{
@ -96,8 +109,7 @@ int mysql_update(THD *thd,
DBUG_RETURN(-1);
}
old_used_keys=table->used_keys; // Keys used in WHERE
old_used_keys= table->used_keys; // Keys used in WHERE
/*
Change the query_id for the timestamp column so that we can
check if this is modified directly
@ -151,10 +163,9 @@ int mysql_update(THD *thd,
thd->lex.select_lex.options|=QUERY_NO_INDEX_USED;
if (safe_update && !using_limit)
{
delete select;
free_underlaid_joins(thd, &thd->lex.select_lex);
send_error(thd,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
DBUG_RETURN(1);
my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
goto err;
}
}
init_ftfuncs(thd, &thd->lex.select_lex, 1);
@ -175,14 +186,6 @@ int mysql_update(THD *thd,
matching rows before updating the table!
*/
table->file->extra(HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE);
IO_CACHE tempfile;
if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX,
DISK_BUFFER_SIZE, MYF(MY_WME)))
{
delete select; /* purecov: inspected */
free_underlaid_joins(thd, &thd->lex.select_lex);
DBUG_RETURN(-1);
}
if (old_used_keys & ((key_map) 1 << used_index))
{
table->key_read=1;
@ -191,94 +194,102 @@ int mysql_update(THD *thd,
if (order)
{
/*
Doing an ORDER BY; Let filesort find and sort the rows we are going
to update
*/
uint length;
SORT_FIELD *sortorder;
TABLE_LIST tables;
List<Item> fields;
List<Item> all_fields;
ha_rows examined_rows;
bzero((char*) &tables,sizeof(tables));
tables.table = table;
table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
MYF(MY_FAE | MY_ZEROFILL));
if (setup_ref_array(thd, &thd->lex.select_lex.ref_pointer_array,
order_num)||
setup_order(thd, thd->lex.select_lex.ref_pointer_array,
&tables, fields, all_fields, order) ||
!(sortorder=make_unireg_sortorder(order, &length)) ||
MYF(MY_FAE | MY_ZEROFILL));
if (!(sortorder=make_unireg_sortorder(order, &length)) ||
(table->sort.found_records = filesort(thd, table, sortorder, length,
(SQL_SELECT *) 0,
HA_POS_ERROR, &examined_rows))
select, 0L, limit,
&examined_rows))
== HA_POS_ERROR)
{
delete select;
free_underlaid_joins(thd, &thd->lex.select_lex);
DBUG_RETURN(-1);
free_io_cache(table);
goto err;
}
/*
Filesort has already found and selected the rows we want to update,
so we don't need the where clause
*/
delete select;
select= 0;
}
init_read_record(&info,thd,table,select,0,1);
thd->proc_info="Searching rows for update";
while (!(error=info.read_record(&info)) && !thd->killed)
else
{
if (!(select && select->skipp_record()))
/*
We are doing a search on a key that is updated. In this case
we go trough the matching rows, save a pointer to them and
update these in a separate loop based on the pointer.
*/
IO_CACHE tempfile;
if (open_cached_file(&tempfile, mysql_tmpdir,TEMP_PREFIX,
DISK_BUFFER_SIZE, MYF(MY_WME)))
goto err;
init_read_record(&info,thd,table,select,0,1);
thd->proc_info="Searching rows for update";
uint tmp_limit= limit;
while (!(error=info.read_record(&info)) && !thd->killed)
{
table->file->position(table->record[0]);
if (my_b_write(&tempfile,table->file->ref,
table->file->ref_length))
if (!(select && select->skipp_record()))
{
error=1; /* purecov: inspected */
break; /* purecov: inspected */
table->file->position(table->record[0]);
if (my_b_write(&tempfile,table->file->ref,
table->file->ref_length))
{
error=1; /* purecov: inspected */
break; /* purecov: inspected */
}
if (!--limit && using_limit)
{
error= -1;
break;
}
}
}
limit= tmp_limit;
end_read_record(&info);
/* Change select to use tempfile */
if (select)
{
delete select->quick;
if (select->free_cond)
delete select->cond;
select->quick=0;
select->cond=0;
}
else
{
if (!(test_flags & 512)) /* For debugging */
{
DBUG_DUMP("record",(char*) table->record[0],table->reclength);
}
select= new SQL_SELECT;
select->head=table;
}
if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
error=1; /* purecov: inspected */
select->file=tempfile; // Read row ptrs from this file
if (error >= 0)
goto err;
}
end_read_record(&info);
if (table->key_read)
{
table->key_read=0;
table->file->extra(HA_EXTRA_NO_KEYREAD);
}
/* Change select to use tempfile */
if (select)
{
delete select->quick;
if (select->free_cond)
delete select->cond;
select->quick=0;
select->cond=0;
}
else
{
select= new SQL_SELECT;
select->head=table;
}
if (reinit_io_cache(&tempfile,READ_CACHE,0L,0,0))
error=1; /* purecov: inspected */
select->file=tempfile; // Read row ptrs from this file
if (error >= 0)
{
delete select;
free_underlaid_joins(thd, &thd->lex.select_lex);
DBUG_RETURN(-1);
}
}
if (handle_duplicates == DUP_IGNORE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
init_read_record(&info,thd,table,select,0,1);
ha_rows updated=0L,found=0L;
updated= found= 0;
thd->count_cuted_fields=1; /* calc cuted fields */
thd->cuted_fields=0L;
thd->proc_info="Updating";
@ -289,7 +300,7 @@ int mysql_update(THD *thd,
if (!(select && select->skipp_record()))
{
store_record(table,record[1]);
if (fill_record(fields,values) || thd->net.report_error)
if (fill_record(fields,values, 0) || thd->net.report_error)
break; /* purecov: inspected */
found++;
if (compare_record(table, query_id))
@ -298,11 +309,6 @@ int mysql_update(THD *thd,
(byte*) table->record[0])))
{
updated++;
if (!--limit && using_limit)
{
error= -1;
break;
}
}
else if (handle_duplicates != DUP_IGNORE ||
error != HA_ERR_FOUND_DUPP_KEY)
@ -312,11 +318,17 @@ int mysql_update(THD *thd,
break;
}
}
if (!--limit && using_limit)
{
error= -1; // Simulate end of file
break;
}
}
else
table->file->unlock_row();
}
end_read_record(&info);
free_io_cache(table); // If ORDER BY
thd->proc_info="end";
VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY));
transactional_table= table->file->has_transactions();
@ -370,8 +382,17 @@ int mysql_update(THD *thd,
}
thd->count_cuted_fields=0; /* calc cuted fields */
free_io_cache(table);
DBUG_RETURN(0);
err:
delete select;
free_underlaid_joins(thd, &thd->lex.select_lex);
if (table->key_read)
{
table->key_read=0;
table->file->extra(HA_EXTRA_NO_KEYREAD);
}
DBUG_RETURN(-1);
}
@ -508,6 +529,8 @@ int multi_update::prepare(List<Item> &not_used_values, SELECT_LEX_UNIT *unit)
table->pos_in_table_list= tl;
}
}
table_count= update.elements;
update_tables= (TABLE_LIST*) update.first;
@ -732,7 +755,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
{
table->status|= STATUS_UPDATED;
store_record(table,record[1]);
if (fill_record(*fields_for_table[offset], *values_for_table[offset]))
if (fill_record(*fields_for_table[offset], *values_for_table[offset]), 0)
DBUG_RETURN(1);
found++;
if (compare_record(table, thd->query_id))
@ -760,7 +783,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
{
int error;
TABLE *tmp_table= tmp_tables[offset];
fill_record(tmp_table->field+1, *values_for_table[offset]);
fill_record(tmp_table->field+1, *values_for_table[offset], 1);
found++;
/* Store pointer to row */
memcpy((char*) tmp_table->field[0]->ptr,