Further work on UNION's
sql/sql_delete.cc: Removed some unnecessary stuff
This commit is contained in:
parent
51e3fb9e45
commit
3a7d827d09
@ -295,12 +295,10 @@ int mysql_delete(THD *thd,
|
|||||||
|
|
||||||
#define MEM_STRIP_BUF_SIZE sortbuff_size
|
#define MEM_STRIP_BUF_SIZE sortbuff_size
|
||||||
|
|
||||||
#ifndef SINISAS_STRIP
|
|
||||||
int refposcmp2(void* arg, const void *a,const void *b)
|
int refposcmp2(void* arg, const void *a,const void *b)
|
||||||
{
|
{
|
||||||
return memcmp(a,b,(int) arg);
|
return memcmp(a,b,(int) arg);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt,
|
multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt,
|
||||||
thr_lock_type lock_option_arg,
|
thr_lock_type lock_option_arg,
|
||||||
@ -310,12 +308,7 @@ multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt,
|
|||||||
do_delete(false)
|
do_delete(false)
|
||||||
{
|
{
|
||||||
uint counter=0;
|
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);
|
|
||||||
#else
|
|
||||||
tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables-1));
|
tempfiles = (Unique **) sql_calloc(sizeof(Unique *) * (num_of_tables-1));
|
||||||
#endif
|
|
||||||
|
|
||||||
(void) dt->table->file->extra(HA_EXTRA_NO_READCHECK);
|
(void) dt->table->file->extra(HA_EXTRA_NO_READCHECK);
|
||||||
/* Don't use key read with MULTI-TABLE-DELETE */
|
/* Don't use key read with MULTI-TABLE-DELETE */
|
||||||
@ -326,21 +319,10 @@ multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt,
|
|||||||
TABLE *table=dt->table;
|
TABLE *table=dt->table;
|
||||||
(void) dt->table->file->extra(HA_EXTRA_NO_READCHECK);
|
(void) dt->table->file->extra(HA_EXTRA_NO_READCHECK);
|
||||||
(void) dt->table->file->extra(HA_EXTRA_NO_KEYREAD);
|
(void) dt->table->file->extra(HA_EXTRA_NO_KEYREAD);
|
||||||
#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);
|
|
||||||
thd->fatal_error=1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
tempfiles[counter] = new Unique (refposcmp2,
|
tempfiles[counter] = new Unique (refposcmp2,
|
||||||
(void *) table->file->ref_length,
|
(void *) table->file->ref_length,
|
||||||
table->file->ref_length,
|
table->file->ref_length,
|
||||||
MEM_STRIP_BUF_SIZE);
|
MEM_STRIP_BUF_SIZE);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,13 +385,7 @@ multi_delete::~multi_delete()
|
|||||||
for (uint counter = 0; counter < num_of_tables-1; counter++)
|
for (uint counter = 0; counter < num_of_tables-1; counter++)
|
||||||
{
|
{
|
||||||
if (tempfiles[counter])
|
if (tempfiles[counter])
|
||||||
{
|
|
||||||
#ifdef SINISAS_STRIP
|
|
||||||
end_io_cache(tempfiles[counter]);
|
|
||||||
#else
|
|
||||||
delete tempfiles[counter];
|
delete tempfiles[counter];
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,11 +419,7 @@ bool multi_delete::send_data(List<Item> &values)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef SINISAS_STRIP
|
|
||||||
error=my_b_write(tempfiles[secure_counter],table->file->ref,rl);
|
|
||||||
#else
|
|
||||||
error=tempfiles[secure_counter]->unique_add(table->file->ref);
|
error=tempfiles[secure_counter]->unique_add(table->file->ref);
|
||||||
#endif
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
error=-1;
|
error=-1;
|
||||||
@ -459,330 +431,6 @@ bool multi_delete::send_data(List<Item> &values)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef SINISAS_STRIP
|
|
||||||
static inline int COMP (byte *ml,uint len,unsigned int left, unsigned int right)
|
|
||||||
{
|
|
||||||
return memcmp(ml + left*len,ml + right*len,len);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define EX(ML,LEN,LLLEFT,RRRIGHT) \
|
|
||||||
ptr1 = ML + LLLEFT*LEN;\
|
|
||||||
ptr2 = ML + RRRIGHT*LEN;\
|
|
||||||
memcpy(tmp,ptr1,LEN);\
|
|
||||||
memcpy(ptr1,ptr2,LEN);\
|
|
||||||
memcpy(ptr2,tmp,LEN);\
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void qsort_mem_pieces(byte *ml, uint length, unsigned short pivotP, unsigned int nElem)
|
|
||||||
{
|
|
||||||
unsigned int leftP, rightP, pivotEnd, pivotTemp, leftTemp;
|
|
||||||
unsigned int lNum; byte tmp [MAX_REFLENGTH], *ptr1, *ptr2;
|
|
||||||
int retval;
|
|
||||||
tailRecursion:
|
|
||||||
if (nElem <= 1) return;
|
|
||||||
if (nElem == 2)
|
|
||||||
{
|
|
||||||
if (COMP(ml,length,pivotP, rightP = pivotP + 1) > 0)
|
|
||||||
{
|
|
||||||
EX(ml,length,pivotP, rightP);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
rightP = (nElem - 1) + pivotP;
|
|
||||||
leftP = (nElem >> 1) + pivotP;
|
|
||||||
|
|
||||||
/* sort the pivot, left, and right elements for "median of 3" */
|
|
||||||
|
|
||||||
if (COMP (ml,length,leftP, rightP) > 0)
|
|
||||||
{
|
|
||||||
EX (ml,length,leftP, rightP);
|
|
||||||
}
|
|
||||||
if (COMP (ml,length,leftP, pivotP) > 0)
|
|
||||||
{
|
|
||||||
EX (ml,length,leftP, pivotP);
|
|
||||||
}
|
|
||||||
else if (COMP (ml,length, pivotP, rightP) > 0)
|
|
||||||
{
|
|
||||||
EX (ml,length,pivotP, rightP);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nElem == 3) {
|
|
||||||
EX (ml,length,pivotP, leftP);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now for the classic Hoare algorithm */
|
|
||||||
|
|
||||||
leftP = pivotEnd = pivotP + 1;
|
|
||||||
|
|
||||||
do {
|
|
||||||
while ((retval = COMP (ml,length, leftP, pivotP)) <= 0)
|
|
||||||
{
|
|
||||||
if (retval == 0) {
|
|
||||||
EX(ml,length,leftP, pivotEnd);
|
|
||||||
pivotEnd++;
|
|
||||||
}
|
|
||||||
if (leftP < rightP)
|
|
||||||
leftP++;
|
|
||||||
else
|
|
||||||
goto qBreak;
|
|
||||||
}
|
|
||||||
while (leftP < rightP) {
|
|
||||||
if ((retval = COMP(ml,length,pivotP, rightP)) < 0)
|
|
||||||
rightP--;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EX (ml,length,leftP, rightP);
|
|
||||||
if (retval != 0) {
|
|
||||||
leftP++;
|
|
||||||
rightP--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (leftP < rightP);
|
|
||||||
|
|
||||||
qBreak:
|
|
||||||
|
|
||||||
if (COMP(ml,length,leftP, pivotP) <= 0)
|
|
||||||
leftP++;
|
|
||||||
|
|
||||||
leftTemp = leftP - 1; pivotTemp = pivotP;
|
|
||||||
|
|
||||||
while ((pivotTemp < pivotEnd) && (leftTemp >= pivotEnd))
|
|
||||||
{
|
|
||||||
EX(ml,length,pivotTemp, leftTemp);
|
|
||||||
pivotTemp++; leftTemp--;
|
|
||||||
}
|
|
||||||
|
|
||||||
lNum = leftP - pivotEnd; nElem = (nElem + pivotP) - leftP;
|
|
||||||
|
|
||||||
/* Sort smaller partition first to reduce stack usage */
|
|
||||||
if (nElem < lNum)
|
|
||||||
{
|
|
||||||
qsort_mem_pieces(ml,length,leftP, nElem); nElem = lNum;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qsort_mem_pieces(ml,length,pivotP, lNum);
|
|
||||||
pivotP = leftP;
|
|
||||||
}
|
|
||||||
goto tailRecursion;
|
|
||||||
}
|
|
||||||
|
|
||||||
static byte * btree_search(byte *lane, byte *key,register int last, uint length)
|
|
||||||
{
|
|
||||||
register int first = 0;
|
|
||||||
if (last == first)
|
|
||||||
{
|
|
||||||
if (!memcmp(lane,key,length)) return lane;
|
|
||||||
return (byte *)0;
|
|
||||||
}
|
|
||||||
Recursion_is_too_slow:
|
|
||||||
if (last - first < 3)
|
|
||||||
{
|
|
||||||
if (!memcmp(lane + first*length,key,length)) return lane + first * length;
|
|
||||||
if (last == first + 1) return (byte *)0;
|
|
||||||
if (!memcmp(lane + last*length,key,length)) return lane + last * length;
|
|
||||||
return (byte *)0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int half = first + (last - first)/2;
|
|
||||||
int result = memcmp(lane + half*length,key,length);
|
|
||||||
if (!result) return lane + half*length;
|
|
||||||
if (result < 0)
|
|
||||||
{
|
|
||||||
first = half + 1; goto Recursion_is_too_slow;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
last = half + 1; goto Recursion_is_too_slow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct written_block {
|
|
||||||
byte first[MAX_REFLENGTH], last[MAX_REFLENGTH];
|
|
||||||
my_off_t offset;
|
|
||||||
uint how_many;
|
|
||||||
};
|
|
||||||
|
|
||||||
static IO_CACHE *strip_duplicates_from_temp (byte *memory_lane, IO_CACHE *ptr, uint ref_length, int *written)
|
|
||||||
{
|
|
||||||
byte *mem_ptr; my_off_t off = 0;
|
|
||||||
int read_error, write_error, how_many_to_read, total_to_read = *written, pieces_in_memory = 0, mem_count,written_rows;
|
|
||||||
int offset = written_rows=*written=0;
|
|
||||||
int mem_pool_size = MEM_STRIP_BUF_SIZE * MAX_REFLENGTH / ref_length;
|
|
||||||
byte dup_record[MAX_REFLENGTH]; memset(dup_record,'\xFF',MAX_REFLENGTH);
|
|
||||||
if (reinit_io_cache(ptr,READ_CACHE,0L,0,0))
|
|
||||||
return ptr;
|
|
||||||
IO_CACHE *tempptr = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), MYF(MY_FAE | MY_ZEROFILL));
|
|
||||||
if (open_cached_file(tempptr, mysql_tmpdir,TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
|
|
||||||
{
|
|
||||||
my_free((gptr) tempptr, MYF (0));
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
DYNAMIC_ARRAY written_blocks;
|
|
||||||
VOID(init_dynamic_array(&written_blocks,sizeof(struct written_block),20,50));
|
|
||||||
for (;pieces_in_memory < total_to_read;)
|
|
||||||
{
|
|
||||||
how_many_to_read = total_to_read - pieces_in_memory; read_error=write_error=0;
|
|
||||||
if (how_many_to_read > mem_pool_size)
|
|
||||||
how_many_to_read = mem_pool_size;
|
|
||||||
if (my_b_read(ptr, memory_lane, (uint) how_many_to_read * ref_length))
|
|
||||||
{
|
|
||||||
read_error = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pieces_in_memory += how_many_to_read;
|
|
||||||
qsort_mem_pieces(memory_lane,0, how_many_to_read, ref_length);
|
|
||||||
byte *checking = dup_record, *cursor=NULL, *mem_end = memory_lane + how_many_to_read * ref_length;
|
|
||||||
int opt_unique_pieces, unique_pieces_in_memory=0; write_error=0;
|
|
||||||
for (mem_ptr=memory_lane; mem_ptr < mem_end ; mem_ptr += ref_length)
|
|
||||||
{
|
|
||||||
if (memcmp(mem_ptr,checking, ref_length))
|
|
||||||
{
|
|
||||||
if (cursor)
|
|
||||||
{
|
|
||||||
memmove(cursor,mem_ptr,mem_end - mem_ptr);
|
|
||||||
mem_end -= mem_ptr - cursor;
|
|
||||||
mem_ptr = cursor; cursor = NULL;
|
|
||||||
}
|
|
||||||
unique_pieces_in_memory++;
|
|
||||||
checking = mem_ptr;
|
|
||||||
}
|
|
||||||
else if (!cursor) cursor = mem_ptr;
|
|
||||||
}
|
|
||||||
opt_unique_pieces=unique_pieces_in_memory;
|
|
||||||
if (written_rows)
|
|
||||||
{
|
|
||||||
if (reinit_io_cache(tempptr,READ_CACHE,0L,0,0)) {write_error = -1; break;}
|
|
||||||
for (uint i=0 ; i < written_blocks.elements ; i++)
|
|
||||||
{
|
|
||||||
struct written_block *wbp=dynamic_element(&written_blocks,i,struct written_block*);
|
|
||||||
if ((memcmp(memory_lane,wbp->last,ref_length) == 1) || (memcmp(memory_lane + (unique_pieces_in_memory - 1) * ref_length, wbp->first, ref_length) == -1))
|
|
||||||
continue;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (wbp->how_many < 3)
|
|
||||||
{
|
|
||||||
if ((mem_ptr=btree_search(memory_lane,wbp->first,unique_pieces_in_memory-1, ref_length)))
|
|
||||||
{
|
|
||||||
if (!--opt_unique_pieces) goto skip_writting; // nice little optimization
|
|
||||||
memcpy(mem_ptr,dup_record,ref_length);
|
|
||||||
}
|
|
||||||
if (wbp->how_many == 2 && (mem_ptr=btree_search(memory_lane,wbp->last,unique_pieces_in_memory-1, ref_length)))
|
|
||||||
{
|
|
||||||
if (!--opt_unique_pieces) goto skip_writting; // nice little optimization
|
|
||||||
memcpy(mem_ptr,dup_record,ref_length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
byte block[MAX_REFLENGTH * MEM_STRIP_BUF_SIZE]; // 16 K maximum and only temporary !!
|
|
||||||
if (my_b_read(tempptr, block, (uint) wbp->how_many * ref_length))
|
|
||||||
{
|
|
||||||
read_error = 1; goto skip_writting;
|
|
||||||
}
|
|
||||||
if (unique_pieces_in_memory < 3)
|
|
||||||
{
|
|
||||||
if ((mem_ptr=btree_search(block,memory_lane,wbp->how_many - 1, ref_length)))
|
|
||||||
{
|
|
||||||
if (!--opt_unique_pieces) goto skip_writting; // nice little optimization
|
|
||||||
memcpy(memory_lane,dup_record,ref_length);
|
|
||||||
}
|
|
||||||
if (unique_pieces_in_memory == 2 && (mem_ptr=btree_search(block,memory_lane + ref_length,wbp->how_many - 1, ref_length)))
|
|
||||||
{
|
|
||||||
if (!--opt_unique_pieces) goto skip_writting; // nice little optimization
|
|
||||||
memcpy(mem_ptr,dup_record,ref_length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
byte *cursor; bool do_check_past;
|
|
||||||
if (unique_pieces_in_memory < wbp->how_many)
|
|
||||||
{
|
|
||||||
do_check_past = (memcmp(memory_lane + (unique_pieces_in_memory - 1)*ref_length,wbp->last,ref_length) == 1);
|
|
||||||
for (cursor=memory_lane; cursor < memory_lane + unique_pieces_in_memory*ref_length; cursor += ref_length)
|
|
||||||
{
|
|
||||||
if ((mem_ptr=btree_search(block,cursor,wbp->how_many - 1, ref_length)))
|
|
||||||
{
|
|
||||||
if (!--opt_unique_pieces) goto skip_writting; // nice little optimization
|
|
||||||
memcpy(cursor,dup_record,ref_length);
|
|
||||||
}
|
|
||||||
else if (do_check_past && (memcmp(cursor,wbp->last,ref_length) == 1)) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
do_check_past = (memcmp(memory_lane + (unique_pieces_in_memory - 1)*ref_length,wbp->last,ref_length) == -1);
|
|
||||||
for (cursor=block; cursor < block + wbp->how_many*ref_length;cursor += ref_length)
|
|
||||||
{
|
|
||||||
if ((mem_ptr=btree_search(memory_lane,cursor,unique_pieces_in_memory-1, ref_length)))
|
|
||||||
{
|
|
||||||
if (!--opt_unique_pieces) goto skip_writting; // nice little optimization
|
|
||||||
memcpy(mem_ptr,dup_record,ref_length);
|
|
||||||
}
|
|
||||||
else if (do_check_past && (memcmp(cursor,memory_lane + (unique_pieces_in_memory - 1)*ref_length,ref_length) == 1)) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reinit_io_cache(tempptr, WRITE_CACHE,off,0,0);
|
|
||||||
struct written_block wb; wb.offset = off; wb.how_many=opt_unique_pieces; byte *last;
|
|
||||||
if (opt_unique_pieces < unique_pieces_in_memory)
|
|
||||||
{
|
|
||||||
for (mem_count=0, mem_ptr=memory_lane; mem_count<unique_pieces_in_memory;mem_count++, mem_ptr += ref_length)
|
|
||||||
{
|
|
||||||
if (memcmp(mem_ptr,dup_record,ref_length))
|
|
||||||
{
|
|
||||||
if (my_b_write(tempptr,mem_ptr,ref_length))
|
|
||||||
{
|
|
||||||
if (write_error == 9 || write_error == -1) write_error = 0;
|
|
||||||
if (write_error) break;
|
|
||||||
}
|
|
||||||
if (!mem_count) memcpy(wb.first,mem_ptr,ref_length);
|
|
||||||
last = mem_ptr;
|
|
||||||
written_rows++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
memcpy(wb.last,last,ref_length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(wb.first,memory_lane,ref_length); memcpy(wb.last,memory_lane + (unique_pieces_in_memory -1)*ref_length,ref_length);
|
|
||||||
if (my_b_write(tempptr, memory_lane,unique_pieces_in_memory * ref_length))
|
|
||||||
{
|
|
||||||
write_error = 1; break;
|
|
||||||
}
|
|
||||||
written_rows += unique_pieces_in_memory;
|
|
||||||
}
|
|
||||||
off = my_b_tell(tempptr);
|
|
||||||
VOID(push_dynamic(&written_blocks,(gptr) &wb));
|
|
||||||
skip_writting:
|
|
||||||
if (write_error || read_error) break;
|
|
||||||
}
|
|
||||||
delete_dynamic(&written_blocks);
|
|
||||||
if (read_error || write_error)
|
|
||||||
{
|
|
||||||
close_cached_file(tempptr); end_io_cache(tempptr);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
close_cached_file(ptr); *written=written_rows; end_io_cache(ptr);
|
|
||||||
reinit_io_cache(tempptr,READ_CACHE,0L,0,0);
|
|
||||||
return tempptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SINISAS_STRIP */
|
|
||||||
|
|
||||||
/* Return true if some table is not transaction safe */
|
/* Return true if some table is not transaction safe */
|
||||||
|
|
||||||
@ -845,21 +493,11 @@ int multi_delete::do_deletes (bool from_send_error)
|
|||||||
{
|
{
|
||||||
TABLE *table = table_being_deleted->table;
|
TABLE *table = table_being_deleted->table;
|
||||||
int rl = table->file->ref_length;
|
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;
|
|
||||||
tempfiles[counter] = strip_duplicates_from_temp(memory_lane, tempfiles[counter],rl,&num_of_positions);
|
|
||||||
if (!num_of_positions)
|
|
||||||
{
|
|
||||||
error=1; break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (tempfiles[counter]->get(table))
|
if (tempfiles[counter]->get(table))
|
||||||
{
|
{
|
||||||
error=1;
|
error=1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if USE_REGENERATE_TABLE
|
#if USE_REGENERATE_TABLE
|
||||||
// nice little optimization ....
|
// nice little optimization ....
|
||||||
@ -883,14 +521,7 @@ int multi_delete::do_deletes (bool from_send_error)
|
|||||||
|
|
||||||
READ_RECORD info;
|
READ_RECORD info;
|
||||||
error=0;
|
error=0;
|
||||||
#ifdef SINISAS_STRIP
|
|
||||||
SQL_SELECT *select= new SQL_SELECT;
|
|
||||||
select->head=table;
|
|
||||||
select->file=*tempfiles[counter];
|
|
||||||
init_read_record(&info,thd,table,select,0,0);
|
|
||||||
#else
|
|
||||||
init_read_record(&info,thd,table,NULL,0,0);
|
init_read_record(&info,thd,table,NULL,0,0);
|
||||||
#endif
|
|
||||||
bool not_trans_safe = some_table_is_not_transaction_safe(delete_tables);
|
bool not_trans_safe = some_table_is_not_transaction_safe(delete_tables);
|
||||||
while (!(error=info.read_record(&info)) &&
|
while (!(error=info.read_record(&info)) &&
|
||||||
(!thd->killed || from_send_error || not_trans_safe))
|
(!thd->killed || from_send_error || not_trans_safe))
|
||||||
@ -905,9 +536,6 @@ int multi_delete::do_deletes (bool from_send_error)
|
|||||||
deleted++;
|
deleted++;
|
||||||
}
|
}
|
||||||
end_read_record(&info);
|
end_read_record(&info);
|
||||||
#ifdef SINISAS_STRIP
|
|
||||||
delete select;
|
|
||||||
#endif
|
|
||||||
if (error == -1)
|
if (error == -1)
|
||||||
error = 0;
|
error = 0;
|
||||||
}
|
}
|
||||||
|
@ -1754,10 +1754,8 @@ mysql_execute_command(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!(res=open_and_lock_tables(thd,(TABLE_LIST *)total->first)))
|
if (!(res=open_and_lock_tables(thd,(TABLE_LIST *)total->first)))
|
||||||
{
|
|
||||||
res=mysql_union(thd,lex, select_lex->select_number+1);
|
res=mysql_union(thd,lex, select_lex->select_number+1);
|
||||||
if (res==-1) res=0;
|
close_thread_tables(thd);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLCOM_DROP_TABLE:
|
case SQLCOM_DROP_TABLE:
|
||||||
|
@ -1,3 +1,25 @@
|
|||||||
|
/* Copyright (C) 2000 MySQL AB
|
||||||
|
|
||||||
|
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; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
|
|
||||||
|
/* UNION of select's */
|
||||||
|
|
||||||
|
/* UNION's were introduced by Monty and Sinisa <sinisa@mysql.com> */
|
||||||
|
|
||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
|
|
||||||
|
|
||||||
@ -6,8 +28,8 @@
|
|||||||
|
|
||||||
int mysql_union(THD *thd,LEX *lex,uint no_of_selects)
|
int mysql_union(THD *thd,LEX *lex,uint no_of_selects)
|
||||||
{
|
{
|
||||||
SELECT_LEX *sl, *for_order=&lex->select_lex; uint no=0; int res;
|
SELECT_LEX *sl, *for_order=&lex->select_lex; uint no=0; int res=0;
|
||||||
List<Item> fields; TABLE *table;
|
List<Item> fields; TABLE *table=(TABLE *)NULL; TABLE_LIST *resulting=(TABLE_LIST *)NULL;
|
||||||
for (;for_order->next;for_order=for_order->next);
|
for (;for_order->next;for_order=for_order->next);
|
||||||
ORDER *some_order = (ORDER *)for_order->order_list.first;
|
ORDER *some_order = (ORDER *)for_order->order_list.first;
|
||||||
for (sl=&lex->select_lex;sl;sl=sl->next, no++)
|
for (sl=&lex->select_lex;sl;sl=sl->next, no++)
|
||||||
@ -38,16 +60,19 @@ int mysql_union(THD *thd,LEX *lex,uint no_of_selects)
|
|||||||
delete result;
|
delete result;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
table=result->table;
|
table=result->table;
|
||||||
List_iterator<Item> it(*(result->fields));
|
List_iterator<Item> it(*(result->fields));
|
||||||
Item *item;
|
Item *item;
|
||||||
while ((item= it++))
|
while ((item= it++))
|
||||||
fields.push_back(item);
|
fields.push_back(item);
|
||||||
}
|
|
||||||
delete result;
|
delete result;
|
||||||
if (reopen_table(table)) return 1;
|
if (!reopen_table(table)) return 1;
|
||||||
|
if (!(resulting = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
|
||||||
|
return 1;
|
||||||
|
resulting->db=tables->db ? tables->db : thd->db;
|
||||||
|
resulting->real_name=table->real_name;
|
||||||
|
resulting->name=table->table_name;
|
||||||
|
resulting->table=table;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
@ -73,29 +98,41 @@ int mysql_union(THD *thd,LEX *lex,uint no_of_selects)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (1) // Meaning if not SELECT ... INTO .... which will be done later
|
select_result *result;
|
||||||
|
List<Item> item_list;
|
||||||
|
List<Item_func_match> ftfunc_list;
|
||||||
|
ftfunc_list.empty();
|
||||||
|
if (item_list.push_back(new Item_field(NULL,NULL,"*")))
|
||||||
|
return -1;
|
||||||
|
if (lex->exchange)
|
||||||
{
|
{
|
||||||
READ_RECORD info;
|
if (lex->exchange->dumpfile)
|
||||||
int error=0;
|
|
||||||
if (send_fields(thd,fields,1)) return 1;
|
|
||||||
SQL_SELECT *select= new SQL_SELECT;
|
|
||||||
select->head=table;
|
|
||||||
select->file=*(table->io_cache);
|
|
||||||
init_read_record(&info,thd,table,select,1,1);
|
|
||||||
while (!(error=info.read_record(&info)) && !thd->killed)
|
|
||||||
{
|
{
|
||||||
|
if (!(result=new select_dump(lex->exchange)))
|
||||||
if (error)
|
return -1;
|
||||||
{
|
|
||||||
table->file->print_error(error,MYF(0));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end_read_record(&info);
|
|
||||||
delete select;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!(result=new select_export(lex->exchange)))
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
}
|
||||||
|
else if (!(result=new select_send()))
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res=mysql_select(thd,resulting,item_list,
|
||||||
|
NULL,
|
||||||
|
ftfunc_list,
|
||||||
|
(ORDER*) NULL,
|
||||||
|
(ORDER*) NULL,
|
||||||
|
NULL,
|
||||||
|
(ORDER*) NULL,
|
||||||
|
thd->options,
|
||||||
|
result);
|
||||||
|
if (res)
|
||||||
|
result->abort();
|
||||||
|
}
|
||||||
|
delete result;
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user