33 #include <drizzled/drizzled.h>
34 #include <drizzled/sql_sort.h>
35 #include <drizzled/filesort.h>
36 #include <drizzled/error.h>
37 #include <drizzled/probes.h>
38 #include <drizzled/session.h>
39 #include <drizzled/table.h>
40 #include <drizzled/table_list.h>
41 #include <drizzled/optimizer/range.h>
42 #include <drizzled/records.h>
43 #include <drizzled/internal/iocache.h>
44 #include <drizzled/internal/my_sys.h>
45 #include <plugin/myisam/myisam.h>
46 #include <drizzled/plugin/transactional_storage_engine.h>
47 #include <drizzled/atomics.h>
48 #include <drizzled/global_buffer.h>
49 #include <drizzled/sort_field.h>
50 #include <drizzled/item/subselect.h>
51 #include <drizzled/statistics_variables.h>
52 #include <drizzled/system_variables.h>
65 qsort_cmp2 key_compare;
66 void *key_compare_arg;
80 uint32_t addon_length;
83 ha_rows max_rows,examined_rows;
88 unsigned char *unique_buff;
120 int write_keys(
unsigned char * *sort_keys,
125 void make_sortkey(
unsigned char *to,
126 unsigned char *ref_pos);
127 void register_used_fields();
128 void save_index(
unsigned char **sort_keys,
143 static uint32_t suffix_length(uint32_t string_length);
145 unsigned char *buff);
147 FileSort::FileSort(
Session &arg) :
189 bool sort_positions, ha_rows &examined_rows)
192 uint32_t memavl= 0, min_sort_memory;
194 size_t allocated_sort_memory= 0;
196 ha_rows records= HA_POS_ERROR;
197 unsigned char **sort_keys= 0;
203 bool multi_byte_charset;
211 table->sort.io_cache= NULL;
213 TableList *tab= table->pos_in_table_list;
216 DRIZZLE_FILESORT_START(table->getShare()->getSchemaName(), table->getShare()->getTableName());
225 outfile= table_sort.io_cache;
226 assert(tempfile.buffer == 0);
227 assert(buffpek_pointers.buffer == 0);
229 param.sort_length=
sortlength(sortorder, s_length, &multi_byte_charset);
232 if (!(table->
cursor->getEngine()->check_flag(HTON_BIT_FAST_KEY_READ)) && !sort_positions)
240 ¶m.addon_length);
243 table_sort.addon_buf= 0;
244 table_sort.addon_length= param.addon_length;
245 table_sort.addon_field= param.addon_field;
247 if (param.addon_field)
249 param.res_length= param.addon_length;
250 table_sort.addon_buf= (
unsigned char *) malloc(param.addon_length);
254 param.res_length= param.ref_length;
259 param.sort_length+= param.ref_length;
261 param.rec_length= param.sort_length+param.addon_length;
262 param.max_rows= max_rows;
264 if (select && select->
quick)
266 getSession().status_var.filesort_range_count++;
270 getSession().status_var.filesort_scan_count++;
272 #ifdef CAN_TRUST_RANGE
275 records= min((ha_rows) (select->
quick->
records*2+EXTRA_RECORDS*2),
276 table->
cursor->stats.records)+EXTRA_RECORDS;
277 selected_records_file=0;
287 if (records == HA_POS_ERROR)
289 selected_records_file= 0;
292 if (multi_byte_charset)
293 param.tmp_buffer= (
char*) malloc(param.sort_length);
295 memavl= getSession().
variables.sortbuff_size;
296 min_sort_memory= max((uint32_t)MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
297 while (memavl >= min_sort_memory)
300 uint32_t keys= memavl/(param.rec_length+
sizeof(
char*));
301 param.keys= (uint32_t) min(records+1, (ha_rows)keys);
303 allocated_sort_memory= param.keys * param.rec_length;
304 if (not global_sort_buffer.add(allocated_sort_memory))
306 my_error(ER_OUT_OF_GLOBAL_SORTMEMORY, MYF(ME_ERROR+ME_WAITTANG));
310 if ((table_sort.sort_keys=
312 param.keys, param.rec_length)))
315 global_sort_buffer.sub(allocated_sort_memory);
317 if ((memavl= memavl/4*3) < min_sort_memory && old_memavl > min_sort_memory)
318 memavl= min_sort_memory;
320 sort_keys= table_sort.sort_keys;
321 if (memavl < min_sort_memory)
323 my_error(ER_OUT_OF_SORTMEMORY,MYF(ME_ERROR+ME_WAITTANG));
327 if (buffpek_pointers.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
333 param.sort_form= table;
334 param.end=(param.local_sortorder=sortorder)+s_length;
335 if ((records=
find_all_keys(¶m,select,sort_keys, &buffpek_pointers,
336 &tempfile, selected_records_file)) == HA_POS_ERROR)
340 maxbuffer= (uint32_t)(buffpek_pointers.tell() /
sizeof(*buffpek_inst));
344 param.save_index(sort_keys,(uint32_t) records, &table_sort);
348 if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
350 free(table_sort.buffpek);
351 table_sort.buffpek = 0;
353 if (!(table_sort.buffpek=
358 buffpek_inst= (
buffpek *) table_sort.buffpek;
359 table_sort.buffpek_len= maxbuffer;
360 buffpek_pointers.close_cached_file();
362 if (not outfile->inited() && outfile->open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX,READ_RECORD_BUFFER, MYF(MY_WME)))
376 param.keys=((param.keys*(param.rec_length+
sizeof(
char*))) / param.rec_length-1);
379 if (
merge_many_buff(¶m,(
unsigned char*) sort_keys,buffpek_inst,&maxbuffer, &tempfile))
384 if (tempfile.flush() || tempfile.
reinit_io_cache(internal::READ_CACHE,0L,0,0))
389 if (merge_index(¶m,(
unsigned char*) sort_keys,buffpek_inst,maxbuffer,&tempfile, outfile))
395 if (records > param.max_rows)
397 records= param.max_rows;
402 if (not subselect || not subselect->is_uncacheable())
405 table_sort.sort_keys= 0;
407 table_sort.buffpek= 0;
408 table_sort.buffpek_len= 0;
411 tempfile.close_cached_file();
412 buffpek_pointers.close_cached_file();
414 if (outfile->inited())
416 if (outfile->flush())
421 internal::my_off_t save_pos= outfile->pos_in_file;
427 outfile->end_of_file=save_pos;
433 my_message(ER_FILSORT_ABORT, ER(ER_FILSORT_ABORT),
434 MYF(ME_ERROR+ME_WAITTANG));
438 getSession().status_var.filesort_rows+= (uint32_t) records;
440 examined_rows= param.examined_rows;
441 global_sort_buffer.sub(allocated_sort_memory);
442 table->sort= table_sort;
443 DRIZZLE_FILESORT_DONE(error, records);
444 return (error ? HA_POS_ERROR : records);
453 old_pos= (
char**) malloc((uint32_t) fields * (length +
sizeof(
char*)));
455 char* char_pos= ((
char*) (pos+fields)) - length;
457 *(pos++) = (char_pos+= length);
467 uint32_t length=
sizeof(
buffpek)*count;
468 unsigned char *tmp= buf;
469 if (count > UINT_MAX/
sizeof(
buffpek))
472 tmp= (
unsigned char *)malloc(length);
475 buffpek_pointers->read(tmp, length))
524 unsigned char **sort_keys,
528 int error,flag,quick_select;
529 uint32_t idx,indexpos,ref_length;
530 unsigned char *ref_pos,*next_pos,ref_buff[MAX_REFLENGTH];
531 internal::my_off_t record;
533 volatile Session::killed_state_t *killed= getSession().getKilledPtr();
535 boost::dynamic_bitset<> *save_read_set= NULL;
536 boost::dynamic_bitset<> *save_write_set= NULL;
539 error=quick_select=0;
540 sort_form=param->sort_form;
542 ref_length=param->ref_length;
544 quick_select=select && select->
quick;
546 flag= ((!indexfile && ! file->isOrdered())
548 if (indexfile || flag)
549 ref_pos= &file->ref[0];
551 if (! indexfile && ! quick_select)
553 next_pos=(
unsigned char*) 0;
554 if (file->startTableScan(1))
555 return(HA_POS_ERROR);
556 file->extra_opt(HA_EXTRA_CACHE, getSession().variables.read_buff_size);
563 return(HA_POS_ERROR);
565 if (read_record_info.init_read_record(&getSession(), select->
quick->head, select, 1, 1))
566 return(HA_POS_ERROR);
570 save_read_set= sort_form->read_set;
571 save_write_set= sort_form->write_set;
573 sort_form->tmp_set.reset();
575 sort_form->read_set= &sort_form->tmp_set;
576 param->register_used_fields();
577 if (select && select->
cond)
578 select->
cond->walk(&Item::register_field_in_read_map, 1,
579 (
unsigned char*) sort_form);
580 sort_form->column_bitmaps_set(sort_form->tmp_set, sort_form->tmp_set);
586 if ((error= read_record_info.read_record(&read_record_info)))
588 error= HA_ERR_END_OF_FILE;
591 file->position(sort_form->getInsertRecord());
597 if (indexfile->read(ref_pos, ref_length))
599 error= errno ? errno : -1;
602 error=file->rnd_pos(sort_form->getInsertRecord(),next_pos);
606 error=file->rnd_next(sort_form->getInsertRecord());
610 internal::my_store_ptr(ref_pos,ref_length,record);
611 record+= sort_form->getShare()->db_record_offset;
614 file->position(sort_form->getInsertRecord());
616 if (error && error != HA_ERR_RECORD_DELETED)
622 if (!indexfile && !quick_select)
624 (void) file->extra(HA_EXTRA_NO_CACHE);
625 file->endTableScan();
627 return(HA_POS_ERROR);
630 param->examined_rows++;
631 if (error == 0 && (!select || select->skip_record() == 0))
633 if (idx == param->keys)
635 if (param->
write_keys(sort_keys, idx, buffpek_pointers, tempfile))
636 return(HA_POS_ERROR);
648 if (getSession().is_error())
657 read_record_info.end_read_record();
661 (void) file->extra(HA_EXTRA_NO_CACHE);
663 file->endTableScan();
666 if (getSession().is_error())
667 return(HA_POS_ERROR);
670 sort_form->column_bitmaps_set(*save_read_set, *save_write_set);
672 if (error != HA_ERR_END_OF_FILE)
674 sort_form->print_error(error,MYF(ME_ERROR | ME_WAITTANG));
675 return(HA_POS_ERROR);
678 if (indexpos && idx && param->
write_keys(sort_keys,idx,buffpek_pointers,tempfile))
680 return(HA_POS_ERROR);
683 return tempfile->inited() ? (ha_rows) (tempfile->tell() / param->rec_length) : idx;
714 internal::my_string_ptr_sort((
unsigned char*) sort_keys, (uint32_t) count, sort_length);
715 if (not tempfile->inited() &&
716 tempfile->open_cached_file(drizzle_tmpdir.c_str(), TEMP_PREFIX, DISK_BUFFER_SIZE, MYF(MY_WME)))
721 if (buffpek_pointers->tell() +
sizeof(buffpek) > UINT_MAX)
726 buffpek.file_pos= tempfile->tell();
727 if ((ha_rows) count > max_rows)
728 count=(uint32_t) max_rows;
730 buffpek.count=(ha_rows) count;
732 for (
unsigned char **ptr= sort_keys + count ; sort_keys != ptr ; sort_keys++)
734 if (tempfile->write(*sort_keys, rec_length))
740 if (buffpek_pointers->write(&buffpek,
sizeof(buffpek)))
753 static inline void store_length(
unsigned char *to, uint32_t length, uint32_t pack_length)
755 switch (pack_length) {
757 *to= (
unsigned char) length;
760 mi_int2store(to, length);
763 mi_int3store(to, length);
766 mi_int4store(to, length);
780 for (sort_field= local_sortorder ;
785 if ((field=sort_field->
field))
787 if (field->maybe_null())
789 if (field->is_null())
792 memset(to, 255, sort_field->
length+1);
794 memset(to, 0, sort_field->
length+1);
795 to+= sort_field->
length+1;
801 field->sort_string(to, sort_field->
length);
812 char fill_char= ((cs->state & MY_CS_BINSORT) ? (
char) 0 :
' ');
814 uint32_t sort_field_length;
820 String *res= item->str_result(&tmp);
824 memset(to-1, 0, sort_field->
length+1);
833 memset(to, 0, sort_field->
length);
837 length= res->length();
839 diff=(int) (sort_field_length - length);
843 length= sort_field_length;
853 char *from=(
char*) res->ptr();
855 if ((
unsigned char*) from == to)
857 set_if_smaller(length,sort_field->
length);
858 memcpy(tmp_buffer,from,length);
861 tmp_length= cs->strnxfrm(to,sort_field->
length, (
unsigned char*) from, length);
862 assert(tmp_length == sort_field->
length);
866 cs->strnxfrm((
unsigned char*)to,length,(
const unsigned char*)res->ptr(),length);
867 cs->cset->fill(cs, (
char *)to+length,diff,fill_char);
873 int64_t value= item->val_int_result();
880 memset(to-1, 0, sort_field->
length+1);
883 memset(to, 0, sort_field->
length);
888 to[7]= (
unsigned char) value;
889 to[6]= (
unsigned char) (value >> 8);
890 to[5]= (
unsigned char) (value >> 16);
891 to[4]= (
unsigned char) (value >> 24);
892 to[3]= (
unsigned char) (value >> 32);
893 to[2]= (
unsigned char) (value >> 40);
894 to[1]= (
unsigned char) (value >> 48);
895 if (item->unsigned_flag)
896 to[0]= (
unsigned char) (value >> 56);
898 to[0]= (
unsigned char) (value >> 56) ^ 128;
903 type::Decimal dec_buf, *dec_val= item->val_decimal_result(&dec_buf);
908 memset(to, 0, sort_field->
length+1);
914 dec_val->val_binary(E_DEC_FATAL_ERROR, to,
915 item->max_length - (item->decimals ? 1:0),
921 double value= item->val_result();
926 memset(to, 0, sort_field->
length+1);
932 change_double_for_sort(value,(
unsigned char*) to);
947 length=sort_field->
length;
950 *to = (
unsigned char) (~ *to);
969 unsigned char *nulls= to;
971 memset(nulls, 0, addonf->offset);
973 for ( ; (field= addonf->field) ; addonf++)
975 if (addonf->null_bit && field->is_null())
977 nulls[addonf->null_offset]|= addonf->null_bit;
979 memset(to, 0, addonf->length);
985 unsigned char *end= field->
pack(to, field->
ptr);
986 uint32_t local_length= (uint32_t) ((to + addonf->length) - end);
987 assert((
int) local_length >= 0);
989 memset(end, 0, local_length);
991 (void) field->
pack(to, field->
ptr);
1000 memcpy(to, ref_pos, (
size_t) ref_length);
1009 void SortParam::register_used_fields()
1012 Table *table= sort_form;
1014 for (sort_field= local_sortorder ;
1019 if ((field= sort_field->
field))
1021 if (field->getTable() == table)
1022 table->setReadSet(field->position());
1026 sort_field->
item->walk(&Item::register_field_in_read_map, 1,
1027 (
unsigned char *) table);
1033 sort_addon_field *addonf= addon_field;
1035 for ( ; (field= addonf->field) ; addonf++)
1036 table->setReadSet(field->position());
1041 table->prepare_for_position();
1046 void SortParam::save_index(
unsigned char **sort_keys, uint32_t count, filesort_info *table_sort)
1048 internal::my_string_ptr_sort((
unsigned char*) sort_keys, (uint32_t) count, sort_length);
1049 uint32_t offset= rec_length - res_length;
1051 if ((ha_rows) count > max_rows)
1052 count=(uint32_t) max_rows;
1054 unsigned char* to= table_sort->record_pointers= (
unsigned char*) malloc(res_length*count);
1056 for (
unsigned char **end_ptr= sort_keys+count ; sort_keys != end_ptr ; sort_keys++)
1058 memcpy(to, *sort_keys+offset, res_length);
1072 if (*maxbuffer < MERGEBUFF2)
1074 if (t_file->flush() ||
1075 t_file2.open_cached_file(drizzle_tmpdir.c_str(),TEMP_PREFIX,DISK_BUFFER_SIZE, MYF(MY_WME)))
1080 from_file= t_file ; to_file= &t_file2;
1081 while (*maxbuffer >= MERGEBUFF2)
1088 lastbuff= buffpek_inst;
1089 for (; i <= *maxbuffer - MERGEBUFF * 3 / 2; i += MERGEBUFF)
1091 if (
merge_buffers(param, from_file, to_file, sort_buffer, lastbuff++, buffpek_inst + i, buffpek_inst + i + MERGEBUFF - 1, 0))
1097 if (
merge_buffers(param, from_file, to_file, sort_buffer, lastbuff++, buffpek_inst + i, buffpek_inst + *maxbuffer, 0)
1098 || to_file->flush())
1101 temp=from_file; from_file=to_file; to_file=temp;
1104 *maxbuffer= (uint32_t) (lastbuff-buffpek_inst)-1;
1108 to_file->close_cached_file();
1109 if (to_file == t_file)
1115 return(*maxbuffer >= MERGEBUFF2);
1131 if ((count= (uint32_t) min((ha_rows) buffpek_inst->max_keys,buffpek_inst->count)))
1133 if (pread(fromfile->file,(
unsigned char*) buffpek_inst->base, (length= rec_length*count),buffpek_inst->file_pos) == 0)
1134 return((uint32_t) -1);
1136 buffpek_inst->key= buffpek_inst->base;
1137 buffpek_inst->file_pos+= length;
1138 buffpek_inst->count-= count;
1139 buffpek_inst->mem_count= count;
1141 return (count*rec_length);
1147 qsort2_cmp key_compare;
1148 void *key_compare_arg;
1152 key_compare(in_key_compare),
1153 key_compare_arg(in_compare_arg)
1158 int val= key_compare(key_compare_arg, &i->key, &j->key);
1189 uint32_t rec_length,res_length,offset;
1192 ha_rows max_rows,org_max_rows;
1193 internal::my_off_t to_start_filepos;
1194 unsigned char *strpos;
1197 void *first_cmp_arg;
1198 volatile Session::killed_state_t *killed= getSession().getKilledPtr();
1199 Session::killed_state_t not_killable;
1201 getSession().status_var.filesort_merge_passes++;
1202 if (param->not_killable)
1204 killed= ¬_killable;
1205 not_killable= Session::NOT_KILLED;
1209 rec_length= param->rec_length;
1210 res_length= param->res_length;
1211 sort_length= param->sort_length;
1212 offset= rec_length-res_length;
1213 maxcount= (uint32_t) (param->keys/((uint32_t) (Tb-Fb) +1));
1214 to_start_filepos= to_file->tell();
1215 strpos= (
unsigned char*) sort_buffer;
1216 org_max_rows=max_rows= param->max_rows;
1219 assert(maxcount!=0);
1221 if (param->unique_buff)
1223 cmp= param->compare;
1224 first_cmp_arg= (
void *) ¶m->cmp_context;
1228 cmp= internal::get_ptr_compare(sort_length);
1229 first_cmp_arg= (
void*) &sort_length;
1233 for (buffpek_inst= Fb ; buffpek_inst <= Tb ; buffpek_inst++)
1235 buffpek_inst->base= strpos;
1236 buffpek_inst->max_keys= maxcount;
1237 strpos+= (uint32_t) (error= (
int)
read_to_buffer(from_file, buffpek_inst,
1242 buffpek_inst->max_keys= buffpek_inst->mem_count;
1243 queue.push(buffpek_inst);
1246 if (param->unique_buff)
1256 buffpek_inst= queue.top();
1257 memcpy(param->unique_buff, buffpek_inst->key, rec_length);
1258 if (to_file->write(buffpek_inst->key, rec_length))
1262 buffpek_inst->key+= rec_length;
1263 buffpek_inst->mem_count--;
1271 queue.push(buffpek_inst);
1278 while (queue.size() > 1)
1286 buffpek_inst= queue.top();
1289 if (!(*cmp)(first_cmp_arg, &(param->unique_buff),
1290 (
unsigned char**) &buffpek_inst->key))
1291 goto skip_duplicate;
1292 memcpy(param->unique_buff, buffpek_inst->key, rec_length);
1296 if (to_file->write(buffpek_inst->key, rec_length))
1303 if (to_file->write(buffpek_inst->key+offset, res_length))
1315 buffpek_inst->key+= rec_length;
1316 if (! --buffpek_inst->mem_count)
1324 else if (error == -1)
1331 queue.push(buffpek_inst);
1334 buffpek_inst= queue.top();
1335 buffpek_inst->base= sort_buffer;
1336 buffpek_inst->max_keys= param->keys;
1344 if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (
unsigned char**) &buffpek_inst->key))
1346 buffpek_inst->key+= rec_length;
1347 --buffpek_inst->mem_count;
1353 if ((ha_rows) buffpek_inst->mem_count > max_rows)
1355 buffpek_inst->mem_count= (uint32_t) max_rows;
1356 buffpek_inst->count= 0;
1358 max_rows-= buffpek_inst->mem_count;
1361 if (to_file->write(buffpek_inst->key, (rec_length*buffpek_inst->mem_count)))
1369 strpos= buffpek_inst->key+offset;
1370 for (end= strpos+buffpek_inst->mem_count*rec_length ;
1372 strpos+= rec_length)
1374 if (to_file->write(strpos, res_length))
1382 while ((error=(
int)
read_to_buffer(from_file,buffpek_inst, rec_length))
1383 != -1 && error != 0);
1386 lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
1387 lastbuff->file_pos= to_start_filepos;
1395 int FileSort::merge_index(
SortParam *param,
unsigned char *sort_buffer,
1396 buffpek *buffpek_inst, uint32_t maxbuffer,
1399 if (
merge_buffers(param,tempfile,outfile,sort_buffer,buffpek_inst,buffpek_inst,
1400 buffpek_inst+maxbuffer,1))
1407 static uint32_t suffix_length(uint32_t string_length)
1409 if (string_length < 256)
1411 if (string_length < 256L*256L)
1413 if (string_length < 256L*256L*256L)
1441 *multi_byte_charset= 0;
1444 for (; s_length-- ; sortorder++)
1448 if (sortorder->
field)
1450 cs= sortorder->
field->sort_charset();
1451 sortorder->
length= sortorder->
field->sort_length();
1452 cs= sortorder->
field->sort_charset();
1453 if (cs->use_strnxfrm())
1456 *multi_byte_charset= 1;
1457 sortorder->
length= cs->coll->strnxfrmlen(cs, sortorder->
length);
1459 if (sortorder->
field->maybe_null())
1470 sortorder->
length=sortorder->
item->max_length;
1471 set_if_smaller(sortorder->
length, getSession().variables.max_sort_length);
1472 cs= sortorder->
item->collation.collation;
1473 if (cs->use_strnxfrm())
1475 sortorder->
length= cs->coll->strnxfrmlen(cs, sortorder->
length);
1477 *multi_byte_charset= 1;
1479 else if (cs == &my_charset_bin)
1489 case DECIMAL_RESULT:
1491 class_decimal_get_binary_size(sortorder->
item->max_length -
1492 (sortorder->
item->decimals ? 1 : 0),
1493 sortorder->
item->decimals);
1496 sortorder->
length=
sizeof(double);
1506 set_if_smaller(sortorder->
length, (
size_t)getSession().variables.max_sort_length);
1507 length+=sortorder->
length;
1547 uint32_t null_fields= 0;
1560 for (pfield= ptabfield; (field= *pfield) ; pfield++)
1562 if (!(field->isReadSet()))
1564 if (field->flags & BLOB_FLAG)
1566 length+= field->max_packed_col_length(field->
pack_length());
1567 if (field->maybe_null())
1573 length+= (null_fields+7)/8;
1575 if (length+sortlength_arg > getSession().
variables.max_length_for_sort_data)
1580 length= (null_fields+7)/8;
1582 for (pfield= ptabfield; (field= *pfield) ; pfield++)
1584 if (!(field->isReadSet()))
1586 addonf->field= field;
1587 addonf->offset= length;
1588 if (field->maybe_null())
1590 addonf->null_offset= null_fields/8;
1591 addonf->null_bit= 1<<(null_fields & 7);
1596 addonf->null_offset= 0;
1597 addonf->null_bit= 0;
1599 addonf->length= field->max_packed_col_length(field->
pack_length());
1600 length+= addonf->length;
1605 return (addonf-fields);
1630 for ( ; (field= addonf->field) ; addonf++)
1632 if (addonf->null_bit && (addonf->null_bit & buff[addonf->null_offset]))
1637 field->set_notnull();
1638 field->
unpack(field->
ptr, buff + addonf->offset);
1647 #define DBL_EXP_DIG (sizeof(double)*8-DBL_MANT_DIG)
1649 void change_double_for_sort(
double nr,
unsigned char *to)
1651 unsigned char *tmp=(
unsigned char*) to;
1654 tmp[0]=(
unsigned char) 128;
1655 memset(tmp+1, 0,
sizeof(nr)-1);
1659 #ifdef WORDS_BIGENDIAN
1660 memcpy(tmp,&nr,
sizeof(nr));
1663 unsigned char *ptr= (
unsigned char*) &nr;
1664 #if defined(__FLOAT_WORD_ORDER) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN)
1665 tmp[0]= ptr[3]; tmp[1]=ptr[2]; tmp[2]= ptr[1]; tmp[3]=ptr[0];
1666 tmp[4]= ptr[7]; tmp[5]=ptr[6]; tmp[6]= ptr[5]; tmp[7]=ptr[4];
1668 tmp[0]= ptr[7]; tmp[1]=ptr[6]; tmp[2]= ptr[5]; tmp[3]=ptr[4];
1669 tmp[4]= ptr[3]; tmp[5]=ptr[2]; tmp[6]= ptr[1]; tmp[7]=ptr[0];
1676 for (i=0 ; i <
sizeof(nr); i++)
1677 tmp[i]=tmp[i] ^ (
unsigned char) 255;
1681 uint16_t exp_part=(((uint16_t) tmp[0] << 8) | (uint16_t) tmp[1] |
1683 exp_part+= (uint16_t) 1 << (16-1-DBL_EXP_DIG);
1684 tmp[0]= (
unsigned char) (exp_part >> 8);
1685 tmp[1]= (
unsigned char) exp_part;