mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Enhancing both multi-table delete and division of LEX
This commit is contained in:
@ -739,7 +739,6 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
|
||||
buffpek=(BUFFPEK*) queue_top(&queue);
|
||||
if (cmp) // Remove duplicates
|
||||
{
|
||||
// Was if (!cmp(&sort_length, param->unique_buff, (uchar**) buffpek->key))
|
||||
if (!cmp(&sort_length, &(param->unique_buff), (uchar**) &buffpek->key))
|
||||
goto skip_duplicate;
|
||||
memcpy(param->unique_buff, (uchar*) buffpek->key,sort_length);
|
||||
|
@ -464,34 +464,6 @@ public:
|
||||
void send_error(uint errcode,const char *err);
|
||||
bool send_eof();
|
||||
};
|
||||
|
||||
class multi_delete : public select_result {
|
||||
TABLE_LIST *delete_tables, *table_being_deleted;
|
||||
IO_CACHE **tempfiles;
|
||||
thr_lock_type lock_option;
|
||||
ulong deleted;
|
||||
byte *dup_checking, wrong_record[MAX_REFLENGTH], *memory_lane;
|
||||
int num_of_tables, error;
|
||||
bool do_delete;
|
||||
THD *thd;
|
||||
public:
|
||||
multi_delete(TABLE_LIST *dt, thr_lock_type o, uint n)
|
||||
: delete_tables (dt), lock_option(o), deleted(0), num_of_tables(n), error(0)
|
||||
{
|
||||
memset(wrong_record,'\xFF',MAX_REFLENGTH);
|
||||
thd = current_thd; do_delete = false;
|
||||
}
|
||||
~multi_delete();
|
||||
int prepare(List<Item> &list);
|
||||
bool send_fields(List<Item> &list,
|
||||
uint flag) { return 0; }
|
||||
bool send_data(List<Item> &items);
|
||||
void send_error(uint errcode,const char *err);
|
||||
int do_deletes (bool from_send_error);
|
||||
bool send_eof();
|
||||
};
|
||||
|
||||
|
||||
class select_insert :public select_result {
|
||||
protected:
|
||||
TABLE *table;
|
||||
@ -619,3 +591,35 @@ public:
|
||||
friend int unique_write_to_file(gptr key, element_count count, Unique *unique);
|
||||
friend int unique_write_to_ptrs(gptr key, element_count count, Unique *unique);
|
||||
};
|
||||
|
||||
class multi_delete : public select_result {
|
||||
TABLE_LIST *delete_tables, *table_being_deleted;
|
||||
#ifdef SINISAS_STRIP
|
||||
IO_CACHE **tempfiles;
|
||||
byte *memory_lane;
|
||||
#else
|
||||
Unique **tempfiles;
|
||||
#endif
|
||||
byte * dup_checking;
|
||||
THD *thd;
|
||||
ha_rows deleted;
|
||||
int num_of_tables, error;
|
||||
thr_lock_type lock_option;
|
||||
bool do_delete;
|
||||
public:
|
||||
multi_delete(TABLE_LIST *dt, thr_lock_type o, uint n)
|
||||
: delete_tables (dt), lock_option(o), deleted(0), num_of_tables(n), error(0)
|
||||
{
|
||||
thd = current_thd; do_delete = false;
|
||||
}
|
||||
~multi_delete();
|
||||
int prepare(List<Item> &list);
|
||||
bool send_fields(List<Item> &list,
|
||||
uint flag) { return 0; }
|
||||
bool send_data(List<Item> &items);
|
||||
void send_error(uint errcode,const char *err);
|
||||
int do_deletes (bool from_send_error);
|
||||
bool send_eof();
|
||||
};
|
||||
|
||||
|
||||
|
@ -150,7 +150,7 @@ int mysql_delete(THD *thd,
|
||||
(OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN)));
|
||||
#ifdef HAVE_INNOBASE_DB
|
||||
/* We need to add code to not generate table based on the table type */
|
||||
if (!innobase_skip)
|
||||
if (!innodb_skip)
|
||||
use_generate_table=0; // Innobase can't use re-generate table
|
||||
#endif
|
||||
if (use_generate_table && ! thd->open_tables)
|
||||
@ -294,15 +294,27 @@ int mysql_delete(THD *thd,
|
||||
|
||||
|
||||
#define MEM_STRIP_BUF_SIZE 2048
|
||||
#ifndef SINISAS_STRIP
|
||||
int refposcmp2(void* arg, const void *a,const void *b)
|
||||
{
|
||||
return memcmp(a,b,(int)arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
multi_delete::prepare(List<Item> &values)
|
||||
{
|
||||
DBUG_ENTER("multi_delete::prepare");
|
||||
uint counter = 0;
|
||||
#ifdef SINISAS_STRIP
|
||||
tempfiles = (IO_CACHE **) sql_calloc(sizeof(IO_CACHE *)*(num_of_tables));
|
||||
memory_lane = (byte *)sql_alloc(MAX_REFLENGTH*MEM_STRIP_BUF_SIZE); uint counter = 0;
|
||||
memory_lane = (byte *)sql_alloc(MAX_REFLENGTH*MEM_STRIP_BUF_SIZE);
|
||||
#else
|
||||
tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables));
|
||||
#endif
|
||||
do_delete = true;
|
||||
dup_checking = (byte *) sql_calloc(MAX_REFLENGTH * (num_of_tables + 1));
|
||||
memset(dup_checking,'\xFF', MAX_REFLENGTH * (num_of_tables + 1)); do_delete = true;
|
||||
memset(dup_checking,'\xFF', MAX_REFLENGTH * (num_of_tables + 1));
|
||||
for (table_being_deleted=delete_tables; table_being_deleted; table_being_deleted=table_being_deleted->next, counter++)
|
||||
{
|
||||
TABLE *table=table_being_deleted->table;
|
||||
@ -314,12 +326,16 @@ multi_delete::prepare(List<Item> &values)
|
||||
(void) table->file->extra(HA_EXTRA_NO_READCHECK);
|
||||
if (counter < num_of_tables)
|
||||
{
|
||||
#ifdef SINISAS_STRIP
|
||||
tempfiles[counter]=(IO_CACHE *)sql_alloc(sizeof(IO_CACHE));
|
||||
if (open_cached_file(tempfiles[counter], mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
|
||||
{
|
||||
my_error(ER_CANT_OPEN_FILE,MYF(0),(tempfiles[counter])->file_name,errno);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
#else
|
||||
tempfiles[counter] = new Unique (refposcmp2,(void *)table->file->ref_length,table->file->ref_length,MEM_STRIP_BUF_SIZE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
thd->proc_info="updating";
|
||||
@ -330,7 +346,11 @@ multi_delete::~multi_delete()
|
||||
{
|
||||
for (uint counter = 0; counter < num_of_tables; counter++)
|
||||
if (tempfiles[counter])
|
||||
end_io_cache(tempfiles[counter]);
|
||||
#ifdef SINISAS_STRIP
|
||||
// end_io_cache(tempfiles[counter]);
|
||||
#else
|
||||
delete tempfiles[counter];
|
||||
#endif
|
||||
// Here it crashes ...
|
||||
}
|
||||
|
||||
@ -342,7 +362,7 @@ bool multi_delete::send_data(List<Item> &values)
|
||||
TABLE *table=table_being_deleted->table;
|
||||
table->file->position(table->record[0]); int rl = table->file->ref_length;
|
||||
byte *dup_check = dup_checking + (secure_counter + 1)*MAX_REFLENGTH;
|
||||
if (!table->null_row && memcmp(dup_check,table->file->ref, rl) && memcmp(table->file->ref,wrong_record,rl))
|
||||
if (!table->null_row && memcmp(dup_check,table->file->ref, rl))
|
||||
{
|
||||
memcpy(dup_check,table->file->ref,rl);
|
||||
if (secure_counter == -1)
|
||||
@ -357,7 +377,11 @@ bool multi_delete::send_data(List<Item> &values)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef SINISAS_STRIP
|
||||
if (my_b_write(tempfiles[secure_counter],table->file->ref,rl))
|
||||
#else
|
||||
if (tempfiles[secure_counter]->unique_add(table->file->ref))
|
||||
#endif
|
||||
{
|
||||
error=-1;
|
||||
return 1;
|
||||
@ -687,11 +711,7 @@ static IO_CACHE *strip_duplicates_from_temp (byte *memory_lane, IO_CACHE *ptr, u
|
||||
return tempptr;
|
||||
}
|
||||
}
|
||||
#else
|
||||
int refposcmp2(void* arg, const void *a,const void *b)
|
||||
{
|
||||
return memcmp(a,b,(int)arg);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static bool some_table_is_not_transaction_safe (TABLE_LIST *tl)
|
||||
@ -708,9 +728,14 @@ static bool some_table_is_not_transaction_safe (TABLE_LIST *tl)
|
||||
|
||||
void multi_delete::send_error(uint errcode,const char *err)
|
||||
{
|
||||
// First send error what ever it is ...
|
||||
::send_error(&thd->net,errcode,err);
|
||||
// If nothing deleted return
|
||||
if (!deleted) return;
|
||||
// Below can happen when thread is killed ...
|
||||
if (!table_being_deleted) table_being_deleted=delete_tables;
|
||||
// If rows from the first table only has been deleted and it is transactional, just do rollback
|
||||
// The same if all tables are transactional, regardless of where we are. In all other cases do attempt deletes ...
|
||||
if ((table_being_deleted->table->file->has_transactions() && table_being_deleted == delete_tables) || !some_table_is_not_transaction_safe(delete_tables))
|
||||
ha_rollback(current_thd);
|
||||
else if (do_delete)
|
||||
@ -732,30 +757,16 @@ int multi_delete::do_deletes (bool from_send_error)
|
||||
for (table_being_deleted=table_being_deleted->next; table_being_deleted ; counter++, table_being_deleted=table_being_deleted->next)
|
||||
{
|
||||
table = table_being_deleted->table; int rl = table->file->ref_length;
|
||||
#ifdef SINISAS_STRIP
|
||||
int num_of_positions = (int)my_b_tell(tempfiles[counter])/rl;
|
||||
if (!num_of_positions) continue;
|
||||
#ifdef SINISAS_STRIP
|
||||
tempfiles[counter] = strip_duplicates_from_temp(memory_lane, tempfiles[counter],rl,&num_of_positions);
|
||||
if (!num_of_positions)
|
||||
{
|
||||
error=1; break;
|
||||
}
|
||||
#else
|
||||
Unique strip_it(refposcmp2,(void *)rl,rl,MEM_STRIP_BUF_SIZE);
|
||||
if (reinit_io_cache(tempfiles[counter],READ_CACHE,0L,0,0))
|
||||
{
|
||||
error=1; break;
|
||||
}
|
||||
for (count = 0; count < num_of_positions; count++)
|
||||
{
|
||||
byte tmp [MAX_REFLENGTH];
|
||||
if (my_b_read(tempfiles[counter], tmp, rl) || strip_it.unique_add(tmp))
|
||||
{
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
strip_it.get(table);
|
||||
tempfiles[counter]->get(table);
|
||||
#endif
|
||||
#if 0
|
||||
if (num_of_positions == table->file->records) // nice little optimization ....
|
||||
@ -773,12 +784,17 @@ int multi_delete::do_deletes (bool from_send_error)
|
||||
else
|
||||
{
|
||||
#endif
|
||||
READ_RECORD info; error=0;
|
||||
#ifdef SINISAS_STRIP
|
||||
SQL_SELECT *select= new SQL_SELECT;
|
||||
READ_RECORD info;
|
||||
select->head=table;
|
||||
select->file=*tempfiles[counter];
|
||||
init_read_record(&info,thd,table,select,0,0); error=0;
|
||||
while (!(error=info.read_record(&info)) && (!thd->killed || from_send_error))
|
||||
init_read_record(&info,thd,table,select,0,0);
|
||||
#else
|
||||
init_read_record(&info,thd,table,NULL,0,0);
|
||||
#endif
|
||||
bool not_trans_safe = some_table_is_not_transaction_safe(delete_tables);
|
||||
while (!(error=info.read_record(&info)) && (!thd->killed || from_send_error || not_trans_safe))
|
||||
{
|
||||
error=table->file->delete_row(table->record[0]);
|
||||
if (error)
|
||||
@ -789,8 +805,11 @@ int multi_delete::do_deletes (bool from_send_error)
|
||||
else
|
||||
deleted++;
|
||||
}
|
||||
end_read_record(&info); delete select;
|
||||
if (error = -1) error = 0; // Monty, that is what read_record returns on end of the file !!
|
||||
end_read_record(&info);
|
||||
#ifdef SINISAS_STRIP
|
||||
delete select;
|
||||
#endif
|
||||
if (error = -1) error = 0;
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
@ -822,11 +841,6 @@ bool multi_delete::send_eof()
|
||||
error=1;
|
||||
VOID(ha_autocommit_or_rollback(thd,error >= 0));
|
||||
}
|
||||
if (thd->lock)
|
||||
{
|
||||
mysql_unlock_tables(thd, thd->lock);
|
||||
thd->lock=0;
|
||||
}
|
||||
::send_ok(&thd->net,deleted);
|
||||
return 0;
|
||||
|
||||
|
200
sql/sql_parse.cc
200
sql/sql_parse.cc
@ -1059,7 +1059,7 @@ mysql_execute_command(void)
|
||||
THD *thd=current_thd;
|
||||
LEX *lex= &thd->lex;
|
||||
TABLE_LIST *tables=(TABLE_LIST*) lex->select->table_list.first;
|
||||
SELECT_LEX *Select = lex->select;
|
||||
SELECT_LEX *select_lex = lex->select;
|
||||
DBUG_ENTER("mysql_execute_command");
|
||||
|
||||
if(table_rules_on && thd->slave_thread && tables && !tables_ok(thd,tables))
|
||||
@ -1071,7 +1071,7 @@ mysql_execute_command(void)
|
||||
case SQLCOM_SELECT:
|
||||
{
|
||||
select_result *result;
|
||||
if (Select->options & SELECT_DESCRIBE)
|
||||
if (select_lex->options & SELECT_DESCRIBE)
|
||||
lex->exchange=0;
|
||||
if (tables)
|
||||
{
|
||||
@ -1089,12 +1089,12 @@ mysql_execute_command(void)
|
||||
break; // Error message is given
|
||||
}
|
||||
|
||||
thd->offset_limit=Select->offset_limit;
|
||||
thd->select_limit=Select->select_limit+Select->offset_limit;
|
||||
if (thd->select_limit < Select->select_limit)
|
||||
thd->offset_limit=select_lex->offset_limit;
|
||||
thd->select_limit=select_lex->select_limit+select_lex->offset_limit;
|
||||
if (thd->select_limit < select_lex->select_limit)
|
||||
thd->select_limit= HA_POS_ERROR; // no limit
|
||||
if (thd->select_limit == HA_POS_ERROR)
|
||||
Select->options&= ~OPTION_FOUND_ROWS;
|
||||
select_lex->options&= ~OPTION_FOUND_ROWS;
|
||||
|
||||
if (lex->exchange)
|
||||
{
|
||||
@ -1119,8 +1119,8 @@ mysql_execute_command(void)
|
||||
{
|
||||
res= -1;
|
||||
#ifdef DELETE_ITEMS
|
||||
delete Select->having;
|
||||
delete Select->where;
|
||||
delete select_lex->having;
|
||||
delete select_lex->where;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@ -1138,22 +1138,22 @@ mysql_execute_command(void)
|
||||
|
||||
if (!(res=open_and_lock_tables(thd,tables)))
|
||||
{
|
||||
res=mysql_select(thd,tables,Select->item_list,
|
||||
Select->where,
|
||||
Select->ftfunc_list,
|
||||
(ORDER*) Select->order_list.first,
|
||||
(ORDER*) Select->group_list.first,
|
||||
Select->having,
|
||||
res=mysql_select(thd,tables,select_lex->item_list,
|
||||
select_lex->where,
|
||||
select_lex->ftfunc_list,
|
||||
(ORDER*) select_lex->order_list.first,
|
||||
(ORDER*) select_lex->group_list.first,
|
||||
select_lex->having,
|
||||
(ORDER*) lex->proc_list.first,
|
||||
Select->options | thd->options,
|
||||
select_lex->options | thd->options,
|
||||
result);
|
||||
if (res)
|
||||
result->abort();
|
||||
}
|
||||
delete result;
|
||||
#ifdef DELETE_ITEMS
|
||||
delete Select->having;
|
||||
delete Select->where;
|
||||
delete select_lex->having;
|
||||
delete select_lex->where;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@ -1272,7 +1272,7 @@ mysql_execute_command(void)
|
||||
res=0;
|
||||
break;
|
||||
}
|
||||
if (Select->item_list.elements) // With select
|
||||
if (select_lex->item_list.elements) // With select
|
||||
{
|
||||
select_result *result;
|
||||
|
||||
@ -1290,9 +1290,9 @@ mysql_execute_command(void)
|
||||
for (table = tables->next ; table ; table=table->next)
|
||||
table->lock_type= lex->lock_option;
|
||||
}
|
||||
thd->offset_limit=Select->offset_limit;
|
||||
thd->select_limit=Select->select_limit+Select->offset_limit;
|
||||
if (thd->select_limit < Select->select_limit)
|
||||
thd->offset_limit=select_lex->offset_limit;
|
||||
thd->select_limit=select_lex->select_limit+select_lex->offset_limit;
|
||||
if (thd->select_limit < select_lex->select_limit)
|
||||
thd->select_limit= HA_POS_ERROR; // No limit
|
||||
|
||||
if (!(res=open_and_lock_tables(thd,tables->next)))
|
||||
@ -1301,16 +1301,16 @@ mysql_execute_command(void)
|
||||
tables->real_name, &lex->create_info,
|
||||
lex->create_list,
|
||||
lex->key_list,
|
||||
Select->item_list,lex->duplicates)))
|
||||
select_lex->item_list,lex->duplicates)))
|
||||
{
|
||||
res=mysql_select(thd,tables->next,Select->item_list,
|
||||
Select->where,
|
||||
Select->ftfunc_list,
|
||||
(ORDER*) Select->order_list.first,
|
||||
(ORDER*) Select->group_list.first,
|
||||
Select->having,
|
||||
res=mysql_select(thd,tables->next,select_lex->item_list,
|
||||
select_lex->where,
|
||||
select_lex->ftfunc_list,
|
||||
(ORDER*) select_lex->order_list.first,
|
||||
(ORDER*) select_lex->group_list.first,
|
||||
select_lex->having,
|
||||
(ORDER*) lex->proc_list.first,
|
||||
Select->options | thd->options,
|
||||
select_lex->options | thd->options,
|
||||
result);
|
||||
if (res)
|
||||
result->abort();
|
||||
@ -1365,10 +1365,10 @@ mysql_execute_command(void)
|
||||
}
|
||||
if (!tables->db)
|
||||
tables->db=thd->db;
|
||||
if (!Select->db)
|
||||
Select->db=tables->db;
|
||||
if (!select_lex->db)
|
||||
select_lex->db=tables->db;
|
||||
if (check_access(thd,ALTER_ACL,tables->db,&tables->grant.privilege) ||
|
||||
check_access(thd,INSERT_ACL | CREATE_ACL,Select->db,&priv) ||
|
||||
check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv) ||
|
||||
check_merge_table_access(thd, tables->db,
|
||||
(TABLE_LIST *)
|
||||
lex->create_info.merge_list.first))
|
||||
@ -1384,7 +1384,7 @@ mysql_execute_command(void)
|
||||
TABLE_LIST tmp_table;
|
||||
bzero((char*) &tmp_table,sizeof(tmp_table));
|
||||
tmp_table.real_name=lex->name;
|
||||
tmp_table.db=Select->db;
|
||||
tmp_table.db=select_lex->db;
|
||||
tmp_table.grant.privilege=priv;
|
||||
if (check_grant(thd,INSERT_ACL | CREATE_ACL,tables))
|
||||
goto error;
|
||||
@ -1394,11 +1394,11 @@ mysql_execute_command(void)
|
||||
if (end_active_trans(thd))
|
||||
res= -1;
|
||||
else
|
||||
res= mysql_alter_table(thd, Select->db, lex->name,
|
||||
res= mysql_alter_table(thd, select_lex->db, lex->name,
|
||||
&lex->create_info,
|
||||
tables, lex->create_list,
|
||||
lex->key_list, lex->drop_list, lex->alter_list,
|
||||
(ORDER *) Select->order_list.first,
|
||||
(ORDER *) select_lex->order_list.first,
|
||||
lex->drop_primary, lex->duplicates,
|
||||
lex->alter_keys_onoff, lex->simple_alter);
|
||||
break;
|
||||
@ -1518,22 +1518,22 @@ mysql_execute_command(void)
|
||||
goto error;
|
||||
if (grant_option && check_grant(thd,UPDATE_ACL,tables))
|
||||
goto error;
|
||||
if (Select->item_list.elements != lex->value_list.elements)
|
||||
if (select_lex->item_list.elements != lex->value_list.elements)
|
||||
{
|
||||
send_error(&thd->net,ER_WRONG_VALUE_COUNT);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
res = mysql_update(thd,tables,
|
||||
Select->item_list,
|
||||
select_lex->item_list,
|
||||
lex->value_list,
|
||||
Select->where,
|
||||
(ORDER *) Select->order_list.first,
|
||||
Select->select_limit,
|
||||
select_lex->where,
|
||||
(ORDER *) select_lex->order_list.first,
|
||||
select_lex->select_limit,
|
||||
lex->duplicates,
|
||||
lex->lock_option);
|
||||
|
||||
#ifdef DELETE_ITEMS
|
||||
delete Select->where;
|
||||
delete select_lex->where;
|
||||
#endif
|
||||
break;
|
||||
case SQLCOM_INSERT:
|
||||
@ -1577,9 +1577,9 @@ mysql_execute_command(void)
|
||||
}
|
||||
|
||||
select_result *result;
|
||||
thd->offset_limit=Select->offset_limit;
|
||||
thd->select_limit=Select->select_limit+Select->offset_limit;
|
||||
if (thd->select_limit < Select->select_limit)
|
||||
thd->offset_limit=select_lex->offset_limit;
|
||||
thd->select_limit=select_lex->select_limit+select_lex->offset_limit;
|
||||
if (thd->select_limit < select_lex->select_limit)
|
||||
thd->select_limit= HA_POS_ERROR; // No limit
|
||||
|
||||
if (check_dup(thd,tables->db,tables->real_name,tables->next))
|
||||
@ -1599,14 +1599,14 @@ mysql_execute_command(void)
|
||||
lex->sql_command == SQLCOM_REPLACE_SELECT ?
|
||||
DUP_REPLACE : DUP_IGNORE)))
|
||||
{
|
||||
res=mysql_select(thd,tables->next,Select->item_list,
|
||||
Select->where,
|
||||
Select->ftfunc_list,
|
||||
(ORDER*) Select->order_list.first,
|
||||
(ORDER*) Select->group_list.first,
|
||||
Select->having,
|
||||
res=mysql_select(thd,tables->next,select_lex->item_list,
|
||||
select_lex->where,
|
||||
select_lex->ftfunc_list,
|
||||
(ORDER*) select_lex->order_list.first,
|
||||
(ORDER*) select_lex->group_list.first,
|
||||
select_lex->having,
|
||||
(ORDER*) lex->proc_list.first,
|
||||
Select->options | thd->options,
|
||||
select_lex->options | thd->options,
|
||||
result);
|
||||
delete result;
|
||||
}
|
||||
@ -1614,14 +1614,14 @@ mysql_execute_command(void)
|
||||
res= -1;
|
||||
}
|
||||
#ifdef DELETE_ITEMS
|
||||
delete Select->having;
|
||||
delete Select->where;
|
||||
delete select_lex->having;
|
||||
delete select_lex->where;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case SQLCOM_TRUNCATE:
|
||||
Select->where=0;
|
||||
Select->select_limit=HA_POS_ERROR;
|
||||
select_lex->where=0;
|
||||
select_lex->select_limit=HA_POS_ERROR;
|
||||
/* Fall through */
|
||||
case SQLCOM_DELETE:
|
||||
{
|
||||
@ -1635,8 +1635,8 @@ mysql_execute_command(void)
|
||||
if (lex->sql_command == SQLCOM_TRUNCATE && end_active_trans(thd))
|
||||
res= -1;
|
||||
else
|
||||
res = mysql_delete(thd,tables, Select->where, (ORDER*)Select->order_list.first,
|
||||
Select->select_limit, lex->lock_option, Select->options);
|
||||
res = mysql_delete(thd,tables, select_lex->where, (ORDER*)select_lex->order_list.first,
|
||||
select_lex->select_limit, lex->lock_option, select_lex->options);
|
||||
break;
|
||||
}
|
||||
case SQLCOM_MULTI_DELETE:
|
||||
@ -1653,9 +1653,7 @@ mysql_execute_command(void)
|
||||
}
|
||||
if (!tables->db)
|
||||
tables->db=thd->db;
|
||||
if (!aux_tables->db)
|
||||
aux_tables->db=thd->db;
|
||||
if ((thd->options & OPTION_SAFE_UPDATES) && !Select->where)
|
||||
if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where)
|
||||
{
|
||||
send_error(&thd->net,ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE);
|
||||
res=1; goto error;
|
||||
@ -1679,51 +1677,27 @@ mysql_execute_command(void)
|
||||
res=-2; goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
auxi->lock_type=walk->lock_type=TL_WRITE;
|
||||
TABLE form; char path[FN_REFLEN];
|
||||
(void)sprintf(path,"%s/%s/%s",mysql_data_home,auxi->db,auxi->name);
|
||||
if (openfrm(path,auxi->name,(uint)HA_TRY_READ_ONLY,COMPUTE_TYPES,0,&form))
|
||||
{
|
||||
res=-1; goto error;
|
||||
auxi->table= (TABLE *) walk;
|
||||
}
|
||||
char *field_name=sql_strdup(form.fieldnames.type_names[0]); VOID(closefrm(&form));
|
||||
if (add_item_to_list(new Item_field(auxi->db,auxi->name,field_name)))
|
||||
{
|
||||
net_printf(&thd->net,ER_WRONG_TABLE_NAME,auxi->name);
|
||||
res=-1; goto error;
|
||||
}
|
||||
}
|
||||
if (!howmuch--)
|
||||
{
|
||||
my_error(ER_NO_TABLES_USED, MYF(0));
|
||||
res=-2; goto error;
|
||||
}
|
||||
tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
|
||||
if (add_item_to_list(new Item_null())) goto error;
|
||||
thd->proc_info="init";
|
||||
if (open_and_lock_tables(thd,tables))
|
||||
{
|
||||
res=-1; goto error;
|
||||
}
|
||||
/* This double loop definitely looks like it could have been merged up. But not !!
|
||||
* Problmes are that we have to first set lock for tables to be deleted to write
|
||||
* and then to get auxi->table from tables, like below .....
|
||||
*/
|
||||
for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next)
|
||||
{
|
||||
for (walk=(TABLE_LIST*) tables ; walk ; walk=walk->next)
|
||||
{
|
||||
if (!strcmp(auxi->real_name,walk->real_name) && !strcmp(walk->db,auxi->db))
|
||||
break;
|
||||
}
|
||||
auxi->table = walk->table;
|
||||
}
|
||||
auxi->table= ((TABLE_LIST*) auxi->table)->table;
|
||||
if ((result=new multi_delete(aux_tables,lex->lock_option,howmuch)))
|
||||
{
|
||||
res=mysql_select(thd,tables,Select->item_list,
|
||||
Select->where,Select->ftfunc_list,
|
||||
res=mysql_select(thd,tables,select_lex->item_list,
|
||||
select_lex->where,select_lex->ftfunc_list,
|
||||
(ORDER *)NULL,(ORDER *)NULL,(Item *)NULL,
|
||||
(ORDER *)NULL,
|
||||
Select->options | thd->options,
|
||||
select_lex->options | thd->options,
|
||||
result);
|
||||
delete result;
|
||||
}
|
||||
@ -1797,7 +1771,7 @@ mysql_execute_command(void)
|
||||
DBUG_VOID_RETURN;
|
||||
#else
|
||||
{
|
||||
char *db=Select->db ? Select->db : thd->db;
|
||||
char *db=select_lex->db ? select_lex->db : thd->db;
|
||||
if (!db)
|
||||
{
|
||||
send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
|
||||
@ -1812,7 +1786,7 @@ mysql_execute_command(void)
|
||||
if (check_access(thd,SELECT_ACL,db,&thd->col_access))
|
||||
goto error; /* purecov: inspected */
|
||||
/* grant is checked in mysqld_show_tables */
|
||||
if (Select->options & SELECT_DESCRIBE)
|
||||
if (select_lex->options & SELECT_DESCRIBE)
|
||||
res= mysqld_extend_show_tables(thd,db,
|
||||
(lex->wild ? lex->wild->ptr() : NullS));
|
||||
else
|
||||
@ -1877,7 +1851,7 @@ mysql_execute_command(void)
|
||||
}
|
||||
#endif
|
||||
case SQLCOM_CHANGE_DB:
|
||||
mysql_change_db(thd,Select->db);
|
||||
mysql_change_db(thd,select_lex->db);
|
||||
break;
|
||||
case SQLCOM_LOAD:
|
||||
{
|
||||
@ -1901,10 +1875,10 @@ mysql_execute_command(void)
|
||||
case SQLCOM_SET_OPTION:
|
||||
{
|
||||
uint org_options=thd->options;
|
||||
thd->options=Select->options;
|
||||
thd->options=select_lex->options;
|
||||
thd->update_lock_default= ((thd->options & OPTION_LOW_PRIORITY_UPDATES) ?
|
||||
TL_WRITE_LOW_PRIORITY : TL_WRITE);
|
||||
thd->default_select_limit=Select->select_limit;
|
||||
thd->default_select_limit=select_lex->select_limit;
|
||||
thd->tx_isolation=lex->tx_isolation;
|
||||
if (thd->gemini_spin_retries != lex->gemini_spin_retries)
|
||||
{
|
||||
@ -1915,7 +1889,7 @@ mysql_execute_command(void)
|
||||
thd->options,(long) thd->default_select_limit));
|
||||
|
||||
/* Check if auto_commit mode changed */
|
||||
if ((org_options ^ Select->options) & OPTION_NOT_AUTO_COMMIT)
|
||||
if ((org_options ^ select_lex->options) & OPTION_NOT_AUTO_COMMIT)
|
||||
{
|
||||
if ((org_options & OPTION_NOT_AUTO_COMMIT))
|
||||
{
|
||||
@ -2025,7 +1999,7 @@ mysql_execute_command(void)
|
||||
if (tables && !tables->db)
|
||||
tables->db=thd->db;
|
||||
if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
|
||||
tables && tables->db ? tables->db : Select->db,
|
||||
tables && tables->db ? tables->db : select_lex->db,
|
||||
tables ? &tables->grant.privilege : 0,
|
||||
tables ? 0 : 1))
|
||||
goto error;
|
||||
@ -2077,7 +2051,7 @@ mysql_execute_command(void)
|
||||
res=1;
|
||||
}
|
||||
else
|
||||
res = mysql_grant(thd, Select->db, lex->users_list, lex->grant,
|
||||
res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
|
||||
lex->sql_command == SQLCOM_REVOKE);
|
||||
if(!res)
|
||||
{
|
||||
@ -2125,8 +2099,8 @@ mysql_execute_command(void)
|
||||
if (check_db_used(thd,tables) || check_table_access(thd,SELECT_ACL, tables))
|
||||
goto error;
|
||||
res = mysql_ha_read(thd, tables, lex->ha_read_mode, lex->backup_dir,
|
||||
lex->insert_list, lex->ha_rkey_mode, Select->where,
|
||||
Select->select_limit, Select->offset_limit);
|
||||
lex->insert_list, lex->ha_rkey_mode, select_lex->where,
|
||||
select_lex->select_limit, select_lex->offset_limit);
|
||||
break;
|
||||
|
||||
case SQLCOM_BEGIN:
|
||||
@ -2403,19 +2377,19 @@ mysql_init_query(THD *thd)
|
||||
void
|
||||
mysql_init_select(LEX *lex)
|
||||
{
|
||||
SELECT_LEX *Select = lex->select;
|
||||
Select->where=Select->having=0;
|
||||
Select->select_limit=current_thd->default_select_limit;
|
||||
Select->offset_limit=0L;
|
||||
Select->options=0; Select->linkage=UNSPECIFIED_TYPE;
|
||||
Select->select_number = 0; lex->exchange = 0;
|
||||
SELECT_LEX *select_lex = lex->select;
|
||||
select_lex->where=select_lex->having=0;
|
||||
select_lex->select_limit=current_thd->default_select_limit;
|
||||
select_lex->offset_limit=0L;
|
||||
select_lex->options=0; select_lex->linkage=UNSPECIFIED_TYPE;
|
||||
select_lex->select_number = 0; lex->exchange = 0;
|
||||
lex->proc_list.first=0;
|
||||
Select->order_list.elements=Select->group_list.elements=0;
|
||||
Select->order_list.first=0;
|
||||
Select->order_list.next= (byte**) &Select->order_list.first;
|
||||
Select->group_list.first=0;
|
||||
Select->group_list.next= (byte**) &Select->group_list.first;
|
||||
Select->next = (SELECT_LEX *)NULL;
|
||||
select_lex->order_list.elements=select_lex->group_list.elements=0;
|
||||
select_lex->order_list.first=0;
|
||||
select_lex->order_list.next= (byte**) &select_lex->order_list.first;
|
||||
select_lex->group_list.first=0;
|
||||
select_lex->group_list.next= (byte**) &select_lex->group_list.first;
|
||||
select_lex->next = (SELECT_LEX *)NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -542,7 +542,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
||||
opt_mi_check_type opt_to mi_check_types normal_join
|
||||
table_to_table_list table_to_table opt_table_list opt_as
|
||||
handler_rkey_function handler_rkey_mode handler_read_or_scan
|
||||
single_multi table_multi_delete table_sin_wild
|
||||
single_multi table_multi_delete table_sini_wild
|
||||
END_OF_INPUT
|
||||
|
||||
%type <NONE>
|
||||
@ -764,12 +764,12 @@ create_table_option:
|
||||
{
|
||||
/* Move the union list to the merge_list */
|
||||
LEX *lex=Lex;
|
||||
TABLE_LIST *table_list= (TABLE_LIST*) Select->table_list.first;
|
||||
lex->create_info.merge_list= Select->table_list;
|
||||
TABLE_LIST *table_list= (TABLE_LIST*) lex->select->table_list.first;
|
||||
lex->create_info.merge_list= lex->select->table_list;
|
||||
lex->create_info.merge_list.elements--;
|
||||
lex->create_info.merge_list.first= (byte*) (table_list->next);
|
||||
Select->table_list.elements=1;
|
||||
Select->table_list.next= (byte**) &(table_list->next);
|
||||
lex->select->table_list.elements=1;
|
||||
lex->select->table_list.next= (byte**) &(table_list->next);
|
||||
table_list->next=0;
|
||||
lex->create_info.used_fields|= HA_CREATE_USED_UNION;
|
||||
}
|
||||
@ -1064,10 +1064,10 @@ alter:
|
||||
lex->col_list.empty();
|
||||
lex->drop_list.empty();
|
||||
lex->alter_list.empty();
|
||||
Select->order_list.elements=0;
|
||||
Select->order_list.first=0;
|
||||
Select->order_list.next= (byte**) &Select->order_list.first;
|
||||
Select->db=lex->name=0;
|
||||
lex->select->order_list.elements=0;
|
||||
lex->select->order_list.first=0;
|
||||
lex->select->order_list.next= (byte**) &lex->select->order_list.first;
|
||||
lex->select->db=lex->name=0;
|
||||
bzero((char*) &lex->create_info,sizeof(lex->create_info));
|
||||
lex->create_info.db_type= DB_TYPE_DEFAULT;
|
||||
lex->alter_keys_onoff=LEAVE_AS_IS;
|
||||
@ -1118,7 +1118,10 @@ alter_list_item:
|
||||
| ALTER opt_column field_ident DROP DEFAULT
|
||||
{ Lex->alter_list.push_back(new Alter_column($3.str,(Item*) 0)); Lex->simple_alter=0; }
|
||||
| RENAME opt_to table_alias table_ident
|
||||
{ Select->db=$4->db.str ; Lex->name= $4->table.str; Lex->simple_alter=0; }
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->select->db=$4->db.str ; lex->name= $4->table.str; lex->simple_alter=0;
|
||||
}
|
||||
| create_table_options { Lex->simple_alter=0; }
|
||||
| order_clause { Lex->simple_alter=0; }
|
||||
|
||||
@ -2197,9 +2200,9 @@ single_multi:
|
||||
| table_multi_delete
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
Lex->sql_command = SQLCOM_MULTI_DELETE;
|
||||
lex->sql_command = SQLCOM_MULTI_DELETE;
|
||||
mysql_init_select(lex);
|
||||
Select->select_limit=HA_POS_ERROR;
|
||||
lex->select->select_limit=HA_POS_ERROR;
|
||||
lex->auxilliary_table_list.elements=0;
|
||||
lex->auxilliary_table_list.first=0;
|
||||
lex->auxilliary_table_list.next= (byte**) &(lex->auxilliary_table_list.first);
|
||||
@ -2213,13 +2216,17 @@ single_multi:
|
||||
} join_table_list where_clause
|
||||
|
||||
table_multi_delete:
|
||||
table_sin_wild {}
|
||||
| table_multi_delete ',' table_sin_wild {}
|
||||
table_sini_wild {}
|
||||
| table_multi_delete ',' table_sini_wild {}
|
||||
|
||||
table_sin_wild:
|
||||
table_sini_wild:
|
||||
ident '.' '*' { if (!add_table_to_list(new Table_ident($1),NULL,1,TL_WRITE)) YYABORT; }
|
||||
| ident '.' ident '.' '*'
|
||||
{ if (!add_table_to_list(new Table_ident($1,$3,0),NULL,1,TL_WRITE)) YYABORT;}
|
||||
| ident { if (!add_table_to_list(new Table_ident($1),NULL,1,TL_WRITE)) YYABORT; }
|
||||
| ident '.' ident
|
||||
{ if (!add_table_to_list(new Table_ident($1,$3,0),NULL,1,TL_WRITE)) YYABORT;}
|
||||
|
||||
|
||||
opt_delete_options:
|
||||
/* empty */ {}
|
||||
|
@ -39,12 +39,12 @@ Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
|
||||
uint size, ulong max_in_memory_size_arg)
|
||||
:max_in_memory_size(max_in_memory_size_arg),elements(0)
|
||||
{
|
||||
my_b_clear(&file);
|
||||
init_tree(&tree, max_in_memory_size / 16, size, comp_func, 0, 0);
|
||||
tree.cmp_arg=comp_func_fixed_arg;
|
||||
/* If the following fail's the next add will also fail */
|
||||
init_dynamic_array(&file_ptrs, sizeof(BUFFPEK), 16, 16);
|
||||
max_elements= max_in_memory_size / ALIGN_SIZE(sizeof(TREE_ELEMENT)+size);
|
||||
open_cached_file(&file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME));
|
||||
}
|
||||
|
||||
|
||||
@ -74,8 +74,6 @@ bool Unique::flush()
|
||||
|
||||
int unique_write_to_file(gptr key, element_count count, Unique *unique)
|
||||
{
|
||||
if (!my_b_inited(&unique->file) && open_cached_file(&unique->file, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
|
||||
return 1;
|
||||
return my_b_write(&unique->file, key, unique->tree.size_of_element) ? 1 : 0;
|
||||
}
|
||||
|
||||
@ -114,7 +112,7 @@ bool Unique::get(TABLE *table)
|
||||
|
||||
IO_CACHE *outfile=table->io_cache, tempfile;
|
||||
BUFFPEK *file_ptr= (BUFFPEK*) file_ptrs.buffer;
|
||||
uint maxbuffer= file_ptrs.elements - 1; // I added -1 .....
|
||||
uint maxbuffer= file_ptrs.elements - 1;
|
||||
uchar *sort_buffer;
|
||||
my_off_t save_pos;
|
||||
bool error=1;
|
||||
@ -122,16 +120,15 @@ bool Unique::get(TABLE *table)
|
||||
my_b_clear(&tempfile);
|
||||
|
||||
/* Open cached file if it isn't open */
|
||||
if (!outfile) outfile= (IO_CACHE *) sql_calloc(sizeof(IO_CACHE));
|
||||
if (! my_b_inited(outfile) &&
|
||||
outfile=table->io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),MYF(MY_ZEROFILL));
|
||||
|
||||
if (!outfile || ! my_b_inited(outfile) &&
|
||||
open_cached_file(outfile,mysql_tmpdir,TEMP_PREFIX,READ_RECORD_BUFFER,
|
||||
MYF(MY_WME)))
|
||||
return 1;
|
||||
reinit_io_cache(outfile,WRITE_CACHE,0L,0,0);
|
||||
|
||||
// sort_param.keys=elements;
|
||||
sort_param.max_rows= elements;
|
||||
sort_param.examined_rows=0;
|
||||
sort_param.sort_form=table;
|
||||
sort_param.sort_length=sort_param.ref_length=tree.size_of_element;
|
||||
sort_param.keys= max_in_memory_size / sort_param.sort_length;
|
||||
|
Reference in New Issue
Block a user