diff --git a/heap/heapdef.h b/heap/heapdef.h index aeb345522f5..c81624059d5 100644 --- a/heap/heapdef.h +++ b/heap/heapdef.h @@ -79,13 +79,14 @@ extern int hp_rec_key_cmp(HP_KEYDEF *keydef,const byte *rec1, extern int hp_key_cmp(HP_KEYDEF *keydef,const byte *rec, const byte *key); extern void hp_make_key(HP_KEYDEF *keydef,byte *key,const byte *rec); -extern void hp_rb_make_key(HP_KEYDEF *keydef, byte *key, +extern uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec, byte *recpos); +extern uint hp_rb_key_length(HP_KEYDEF *keydef, const byte *key); +extern uint hp_rb_null_key_length(HP_KEYDEF *keydef, const byte *key); extern my_bool hp_if_null_in_key(HP_KEYDEF *keyinfo, const byte *record); extern int hp_close(register HP_INFO *info); extern void hp_clear(HP_SHARE *info); -extern uint hp_rb_pack_key(HP_INFO *info, uint inx, uchar *key, - const uchar *old, uint k_length); +extern uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old); #ifdef THREAD extern pthread_mutex_t THR_LOCK_heap; #else diff --git a/heap/hp_delete.c b/heap/hp_delete.c index 82513044058..4ba2f2c5310 100644 --- a/heap/hp_delete.c +++ b/heap/hp_delete.c @@ -65,12 +65,11 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, heap_rb_param custom_arg; if (flag) - info->last_pos = NULL; /* For heap_rnext/heap_rprev */ + info->last_pos= NULL; /* For heap_rnext/heap_rprev */ - hp_rb_make_key(keyinfo, info->recbuf, record, recpos); - custom_arg.keyseg = keyinfo->seg; - custom_arg.key_length = keyinfo->length; - custom_arg.search_flag = SEARCH_SAME; + custom_arg.keyseg= keyinfo->seg; + custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos); + custom_arg.search_flag= SEARCH_SAME; return tree_delete(&keyinfo->rb_tree, info->recbuf, &custom_arg); } diff --git a/heap/hp_hash.c b/heap/hp_hash.c index 70823c2c2c7..424322fd5e7 100644 --- a/heap/hp_hash.c +++ b/heap/hp_hash.c @@ -26,16 +26,17 @@ ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, const byte *start_key, enum ha_rkey_function end_search_flag) { ha_rows start_pos, end_pos; - TREE *rb_tree = &info->s->keydef[inx].rb_tree; + HP_KEYDEF *keyinfo= info->s->keydef + inx; + TREE *rb_tree = &keyinfo->rb_tree; heap_rb_param custom_arg; info->lastinx = inx; - custom_arg.keyseg = info->s->keydef[inx].seg; + custom_arg.keyseg = keyinfo->seg; custom_arg.search_flag = SEARCH_FIND | SEARCH_SAME; custom_arg.key_length = start_key_len; if (start_key) { - hp_rb_pack_key(info, inx, info->recbuf, start_key, start_key_len); + hp_rb_pack_key(keyinfo, info->recbuf, start_key); start_pos= tree_record_pos(rb_tree, info->recbuf, start_search_flag, &custom_arg); } @@ -47,7 +48,7 @@ ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, const byte *start_key, custom_arg.key_length = end_key_len; if (end_key) { - hp_rb_pack_key(info, inx, info->recbuf, end_key, end_key_len); + hp_rb_pack_key(keyinfo, info->recbuf, end_key); end_pos= tree_record_pos(rb_tree, info->recbuf, end_search_flag, &custom_arg); } @@ -391,14 +392,13 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2) if (rec1[seg->null_pos] & seg->null_bit) continue; } - switch (seg->type) { - case HA_KEYTYPE_END: - return 0; - case HA_KEYTYPE_TEXT: + if (seg->type == HA_KEYTYPE_TEXT) + { if (my_sortcmp(seg->charset,rec1+seg->start,rec2+seg->start,seg->length)) return 1; - break; - default: + } + else + { if (bcmp(rec1+seg->start,rec2+seg->start,seg->length)) return 1; } @@ -454,29 +454,30 @@ void hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec) } } -void hp_rb_make_key(HP_KEYDEF *keydef, byte *key, +uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec, byte *recpos) { + byte *start_key= key; HA_KEYSEG *seg, *endseg; - /* -1 means that HA_KEYTYPE_END segment will not copy */ - for (seg= keydef->seg, endseg= seg + keydef->keysegs - 1; seg < endseg; - seg++) + for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++) { if (seg->null_bit) - *key++= 1 - test(rec[seg->null_pos] & seg->null_bit); + { + if (!(*key++= 1 - test(rec[seg->null_pos] & seg->null_bit))) + continue; + } memcpy(key, rec + seg->start, (size_t) seg->length); key+= seg->length; } memcpy(key, &recpos, sizeof(byte*)); + return key - start_key; } -uint hp_rb_pack_key(HP_INFO *info, uint inx, uchar *key, const uchar *old, - uint k_length) +uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old) { HA_KEYSEG *seg, *endseg; uchar *start_key= key; - HP_KEYDEF *keydef= info->s->keydef + inx; for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; old+= seg->length, seg++) @@ -491,6 +492,26 @@ uint hp_rb_pack_key(HP_INFO *info, uint inx, uchar *key, const uchar *old, } return key - start_key; } + +uint hp_rb_key_length(HP_KEYDEF *keydef, + const byte *key __attribute__((unused))) +{ + return keydef->length; +} + +uint hp_rb_null_key_length(HP_KEYDEF *keydef, const byte *key) +{ + const byte *start_key= key; + HA_KEYSEG *seg, *endseg; + + for (seg= keydef->seg, endseg= seg + keydef->keysegs; seg < endseg; seg++) + { + if (seg->null_bit && !*key++) + continue; + key+= seg->length; + } + return key - start_key; +} /* Test if any of the key parts are NULL. diff --git a/heap/hp_open.c b/heap/hp_open.c index 49f9a2cfc33..3aa35e2cf88 100644 --- a/heap/hp_open.c +++ b/heap/hp_open.c @@ -26,8 +26,8 @@ static int keys_compare(heap_rb_param *param, uchar *key1, uchar *key2) { uint not_used; - return hp_rb_key_cmp(param->keyseg, key1, key2, param->key_length, - param->search_flag, ¬_used); + return ha_key_cmp(param->keyseg, key1, key2, param->key_length, + param->search_flag, ¬_used); } static void init_block(HP_BLOCK *block,uint reclength,ulong min_records, @@ -48,29 +48,39 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef, pthread_mutex_lock(&THR_LOCK_heap); if (!(share = hp_find_named_heap(name))) { + HP_KEYDEF *keyinfo; DBUG_PRINT("info",("Initializing new table")); - for (i=key_segs=max_length=0 ; i < keys ; i++) + for (i=key_segs=max_length=0, keyinfo= keydef; i < keys; i++, keyinfo++) { - key_segs+= keydef[i].keysegs; - bzero((char*) &keydef[i].block,sizeof(keydef[i].block)); - bzero((char*) &keydef[i].rb_tree ,sizeof(keydef[i].rb_tree)); - for (j=length=0 ; j < keydef[i].keysegs; j++) + bzero((char*) &keyinfo->block,sizeof(keyinfo->block)); + bzero((char*) &keyinfo->rb_tree ,sizeof(keyinfo->rb_tree)); + for (j=length=0 ; j < keyinfo->keysegs; j++) { - length+=keydef[i].seg[j].length; - if (keydef[i].seg[j].null_bit && - !(keydef[i].flag & HA_NULL_ARE_EQUAL)) - keydef[i].flag |= HA_NULL_PART_KEY; - if (keydef[i].algorithm == HA_KEY_ALG_BTREE && - keydef[i].seg[j].null_bit) - keydef[i].rb_tree.size_of_element++; + length+=keyinfo->seg[j].length; + if (keyinfo->seg[j].null_bit) + { + if (!(keyinfo->flag & HA_NULL_ARE_EQUAL)) + keyinfo->flag |= HA_NULL_PART_KEY; + if (keyinfo->algorithm == HA_KEY_ALG_BTREE) + keyinfo->rb_tree.size_of_element++; + } + } + keyinfo->length= length; + length+= keyinfo->rb_tree.size_of_element + + ((keyinfo->algorithm == HA_KEY_ALG_BTREE) ? sizeof(byte*) : 0); + if (length > max_length) + max_length= length; + key_segs+= keyinfo->keysegs; + if (keyinfo->algorithm == HA_KEY_ALG_BTREE) + { + key_segs++; /* additional HA_KEYTYPE_END segment */ + if (keyinfo->flag & HA_NULL_PART_KEY) + keyinfo->get_key_length = hp_rb_null_key_length; + else + keyinfo->get_key_length = hp_rb_key_length; } - keydef[i].length= length; - keydef[i].ref_offs= length + keydef[i].rb_tree.size_of_element - - sizeof(byte*); - if (length + keydef[i].rb_tree.size_of_element > max_length) - max_length= length + keydef[i].rb_tree.size_of_element; } - if (!(share = (HP_SHARE*) my_malloc((uint) sizeof(HP_SHARE)+ + if (!(share= (HP_SHARE*) my_malloc((uint) sizeof(HP_SHARE)+ keys*sizeof(HP_KEYDEF)+ key_segs*sizeof(HA_KEYSEG), MYF(MY_ZEROFILL)))) @@ -78,44 +88,45 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef, pthread_mutex_unlock(&THR_LOCK_heap); DBUG_RETURN(0); } - share->keydef=(HP_KEYDEF*) (share+1); - keyseg=(HA_KEYSEG*) (share->keydef+keys); - init_block(&share->block,reclength+1,min_records,max_records); + share->keydef= (HP_KEYDEF*) (share + 1); + keyseg= (HA_KEYSEG*) (share->keydef + keys); + init_block(&share->block, reclength + 1, min_records, max_records); /* Fix keys */ - memcpy(share->keydef,keydef,(size_t) (sizeof(keydef[0])*keys)); - for (i=0 ; i < keys ; i++) + memcpy(share->keydef, keydef, (size_t) (sizeof(keydef[0]) * keys)); + for (i= 0, keyinfo= share->keydef; i < keys; i++, keyinfo++) { - HP_KEYDEF *keyinfo = share->keydef + i; - keyinfo->seg = keyseg; - memcpy(keyseg, keydef[i].seg, - (size_t) (sizeof(keyseg[0]) * keydef[i].keysegs)); - keyseg += keydef[i].keysegs; + uint nsegs= keydef[i].keysegs; + if (keydef[i].algorithm == HA_KEY_ALG_BTREE) { - init_tree(&keyinfo->rb_tree, 0, 0, keydef[i].length + - keydef[i].rb_tree.size_of_element, - (qsort_cmp2)keys_compare, 1, NULL, NULL); - keyinfo->delete_key = hp_rb_delete_key; - keyinfo->write_key = hp_rb_write_key; + init_tree(&keyinfo->rb_tree, 0, 0, 0, (qsort_cmp2)keys_compare, 1, + NULL, NULL); + keyinfo->delete_key= hp_rb_delete_key; + keyinfo->write_key= hp_rb_write_key; + nsegs++; } else { init_block(&keyinfo->block, sizeof(HASH_INFO), min_records, max_records); - keyinfo->delete_key = hp_delete_key; - keyinfo->write_key = hp_write_key; + keyinfo->delete_key= hp_delete_key; + keyinfo->write_key= hp_write_key; } + keyinfo->seg= keyseg; + memcpy(keyseg, keydef[i].seg, + (size_t) (sizeof(keyseg[0]) * nsegs)); + keyseg+= nsegs; } - share->min_records=min_records; - share->max_records=max_records; - share->data_length=share->index_length=0; - share->reclength=reclength; - share->blength=1; - share->keys=keys; - share->max_key_length=max_length; - share->changed=0; - if (!(share->name=my_strdup(name,MYF(0)))) + share->min_records= min_records; + share->max_records= max_records; + share->data_length= share->index_length= 0; + share->reclength= reclength; + share->blength= 1; + share->keys= keys; + share->max_key_length= max_length; + share->changed= 0; + if (!(share->name= my_strdup(name,MYF(0)))) { my_free((gptr) share,MYF(0)); pthread_mutex_unlock(&THR_LOCK_heap); @@ -125,8 +136,8 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef, thr_lock_init(&share->lock); VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST)); #endif - share->open_list.data=(void*) share; - heap_share_list=list_add(heap_share_list,&share->open_list); + share->open_list.data= (void*) share; + heap_share_list= list_add(heap_share_list,&share->open_list); } if (!(info= (HP_INFO*) my_malloc((uint) sizeof(HP_INFO)+ 2 * share->max_key_length, @@ -139,21 +150,21 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef, #ifdef THREAD thr_lock_data_init(&share->lock,&info->lock,NULL); #endif - info->open_list.data=(void*) info; - heap_open_list=list_add(heap_open_list,&info->open_list); + info->open_list.data= (void*) info; + heap_open_list= list_add(heap_open_list,&info->open_list); pthread_mutex_unlock(&THR_LOCK_heap); - info->s=share; - info->lastkey=(byte*) (info+1); - info->recbuf = (byte*) (info->lastkey + share->max_key_length); - info->mode=mode; + info->s= share; + info->lastkey= (byte*) (info + 1); + info->recbuf= (byte*) (info->lastkey + share->max_key_length); + info->mode= mode; info->current_record= (ulong) ~0L; /* No current record */ - info->current_ptr=0; - info->current_hash_ptr=0; - info->lastinx= info->errkey= -1; - info->update=0; + info->current_ptr= 0; + info->current_hash_ptr= 0; + info->lastinx= info->errkey= -1; + info->update= 0; #ifndef DBUG_OFF - info->opt_flag=READ_CHECK_USED; /* Check when changing */ + info->opt_flag= READ_CHECK_USED; /* Check when changing */ #endif DBUG_PRINT("exit",("heap: %lx reclength: %d records_in_block: %d", info,share->reclength,share->block.records_in_block)); diff --git a/heap/hp_rfirst.c b/heap/hp_rfirst.c index 390d18fc58f..39b0d4385f2 100644 --- a/heap/hp_rfirst.c +++ b/heap/hp_rfirst.c @@ -31,7 +31,8 @@ int heap_rfirst(HP_INFO *info, byte *record, int inx) if ((pos = tree_search_edge(&keyinfo->rb_tree, info->parents, &info->last_pos, offsetof(TREE_ELEMENT, left)))) { - memcpy(&pos, pos + keyinfo->ref_offs, sizeof(byte*)); + memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos), + sizeof(byte*)); info->current_ptr = pos; memcpy(record, pos, (size_t)share->reclength); info->update = HA_STATE_AKTIV; diff --git a/heap/hp_rkey.c b/heap/hp_rkey.c index 649370cf0b0..4e47fd52e9b 100644 --- a/heap/hp_rkey.c +++ b/heap/hp_rkey.c @@ -20,56 +20,56 @@ int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key, uint key_len, enum ha_rkey_function find_flag) { byte *pos; - HP_SHARE *share=info->s; - HP_KEYDEF *keyinfo = share->keydef+inx; + HP_SHARE *share= info->s; + HP_KEYDEF *keyinfo= share->keydef + inx; DBUG_ENTER("heap_rkey"); DBUG_PRINT("enter",("base: %lx inx: %d",info,inx)); if ((uint) inx >= share->keys) { - DBUG_RETURN(my_errno=HA_ERR_WRONG_INDEX); + DBUG_RETURN(my_errno= HA_ERR_WRONG_INDEX); } - info->lastinx=inx; - info->current_record = (ulong) ~0L; /* For heap_rrnd() */ + info->lastinx= inx; + info->current_record= (ulong) ~0L; /* For heap_rrnd() */ if (keyinfo->algorithm == HA_KEY_ALG_BTREE) { heap_rb_param custom_arg; - hp_rb_pack_key(info, inx, info->recbuf, key, key_len); + hp_rb_pack_key(keyinfo, info->recbuf, key); - custom_arg.keyseg = info->s->keydef[inx].seg; - custom_arg.key_length = key_len; - custom_arg.search_flag = SEARCH_FIND | SEARCH_SAME; + custom_arg.keyseg= info->s->keydef[inx].seg; + custom_arg.key_length= key_len; + custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME; /* for next rkey() after deletion */ if (find_flag == HA_READ_AFTER_KEY) - info->last_find_flag = HA_READ_KEY_OR_NEXT; + info->last_find_flag= HA_READ_KEY_OR_NEXT; else if (find_flag == HA_READ_BEFORE_KEY) - info->last_find_flag = HA_READ_KEY_OR_PREV; + info->last_find_flag= HA_READ_KEY_OR_PREV; else - info->last_find_flag = find_flag; - info->lastkey_len = key_len; - if (!(pos = tree_search_key(&keyinfo->rb_tree, info->recbuf, info->parents, - &info->last_pos, find_flag, &custom_arg))) + info->last_find_flag= find_flag; + info->lastkey_len= key_len; + if (!(pos= tree_search_key(&keyinfo->rb_tree, info->recbuf, info->parents, + &info->last_pos, find_flag, &custom_arg))) { - info->update = 0; - DBUG_RETURN(my_errno = HA_ERR_KEY_NOT_FOUND); + info->update= 0; + DBUG_RETURN(my_errno= HA_ERR_KEY_NOT_FOUND); } - memcpy(&pos, pos + keyinfo->ref_offs, sizeof(byte*)); - info->current_ptr = pos; + memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos), sizeof(byte*)); + info->current_ptr= pos; } else { - if (!(pos=hp_search(info,share->keydef+inx,key,0))) + if (!(pos= hp_search(info, share->keydef + inx, key, 0))) { - info->update=0; + info->update= 0; DBUG_RETURN(my_errno); } if (!(keyinfo->flag & HA_NOSAME)) - memcpy(info->lastkey,key,(size_t) keyinfo->length); + memcpy(info->lastkey, key, (size_t) keyinfo->length); } - memcpy(record,pos,(size_t) share->reclength); - info->update=HA_STATE_AKTIV; + memcpy(record, pos, (size_t) share->reclength); + info->update= HA_STATE_AKTIV; DBUG_RETURN(0); } diff --git a/heap/hp_rlast.c b/heap/hp_rlast.c index 4c2379427b0..e51a0e8a8f1 100644 --- a/heap/hp_rlast.c +++ b/heap/hp_rlast.c @@ -32,7 +32,8 @@ int heap_rlast(HP_INFO *info, byte *record, int inx) if ((pos = tree_search_edge(&keyinfo->rb_tree, info->parents, &info->last_pos, offsetof(TREE_ELEMENT, right)))) { - memcpy(&pos, pos + keyinfo->ref_offs, sizeof(byte*)); + memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos), + sizeof(byte*)); info->current_ptr = pos; memcpy(record, pos, (size_t)share->reclength); info->update = HA_STATE_AKTIV; diff --git a/heap/hp_rnext.c b/heap/hp_rnext.c index 12ce354335d..a1bc480333e 100644 --- a/heap/hp_rnext.c +++ b/heap/hp_rnext.c @@ -47,7 +47,8 @@ int heap_rnext(HP_INFO *info, byte *record) } if (pos) { - memcpy(&pos, pos + keyinfo->ref_offs, sizeof(byte*)); + memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos), + sizeof(byte*)); info->current_ptr = pos; } else diff --git a/heap/hp_rprev.c b/heap/hp_rprev.c index 98f7a02d55b..d8f5c01dcea 100644 --- a/heap/hp_rprev.c +++ b/heap/hp_rprev.c @@ -47,7 +47,8 @@ int heap_rprev(HP_INFO *info, byte *record) } if (pos) { - memcpy(&pos, pos + keyinfo->ref_offs, sizeof(byte*)); + memcpy(&pos, pos + (*keyinfo->get_key_length)(keyinfo, pos), + sizeof(byte*)); info->current_ptr = pos; } else diff --git a/heap/hp_write.c b/heap/hp_write.c index 801505216bd..fcfe922d9c0 100644 --- a/heap/hp_write.c +++ b/heap/hp_write.c @@ -93,25 +93,25 @@ int hp_rb_write_key(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *record, { heap_rb_param custom_arg; - info->last_pos = NULL; /* For heap_rnext/heap_rprev */ - hp_rb_make_key(keyinfo, info->recbuf, record, recpos); - custom_arg.keyseg = keyinfo->seg; - custom_arg.key_length = keyinfo->length; + info->last_pos= NULL; /* For heap_rnext/heap_rprev */ + custom_arg.keyseg= keyinfo->seg; + custom_arg.key_length= hp_rb_make_key(keyinfo, info->recbuf, record, recpos); if ((keyinfo->flag & HA_NOSAME) && (!(keyinfo->flag & HA_NULL_PART_KEY) || !hp_if_null_in_key(keyinfo, record))) { - custom_arg.search_flag = SEARCH_FIND | SEARCH_SAME; + custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME; if (tree_search_key(&keyinfo->rb_tree, info->recbuf, info->parents, &info->last_pos, 0, &custom_arg)) { - my_errno = HA_ERR_FOUND_DUPP_KEY; + my_errno= HA_ERR_FOUND_DUPP_KEY; return 1; } } - custom_arg.search_flag = SEARCH_SAME; - return tree_insert(&keyinfo->rb_tree, (void*)info->recbuf, keyinfo->length + - sizeof(byte*), &custom_arg) ? 0 : 1; + custom_arg.search_flag= SEARCH_SAME; + return tree_insert(&keyinfo->rb_tree, (void*)info->recbuf, + custom_arg.key_length + sizeof(byte*), + &custom_arg) ? 0 : 1; } /* Find where to place new record */ diff --git a/include/heap.h b/include/heap.h index 8cc62df9250..53757f51e73 100644 --- a/include/heap.h +++ b/include/heap.h @@ -84,7 +84,6 @@ typedef struct st_hp_keydef /* Key definition with open */ uint keysegs; /* Number of key-segment */ uint length; /* Length of key (automatic) */ uint8 algorithm; /* HASH / BTREE */ - uint ref_offs; /* Data reference offset */ HA_KEYSEG *seg; HP_BLOCK block; /* Where keys are saved */ TREE rb_tree; @@ -92,6 +91,7 @@ typedef struct st_hp_keydef /* Key definition with open */ const byte *record, byte *recpos); int (*delete_key)(struct st_heap_info *info, struct st_hp_keydef *keyinfo, const byte *record, byte *recpos, int flag); + uint (*get_key_length)(struct st_hp_keydef *keydef, const byte *key); } HP_KEYDEF; typedef struct st_heap_share @@ -131,7 +131,7 @@ typedef struct st_heap_info byte *lastkey; /* Last used key with rkey */ byte *recbuf; /* Record buffer for rb-tree keys */ enum ha_rkey_function last_find_flag; - TREE_ELEMENT *parents[MAX_TREE_HIGHT+1]; + TREE_ELEMENT *parents[MAX_TREE_HEIGHT+1]; TREE_ELEMENT **last_pos; uint lastkey_len; #ifdef THREAD diff --git a/include/my_base.h b/include/my_base.h index bb589fa59cc..22bc3355cd5 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -147,11 +147,11 @@ enum ha_base_keytype { #define HA_NOSAME 1 /* Set if not dupplicated records */ #define HA_PACK_KEY 2 /* Pack string key to previous key */ -#define HA_AUTO_KEY 1024 +#define HA_AUTO_KEY 16 #define HA_BINARY_PACK_KEY 32 /* Packing of all keys to prev key */ -#define HA_FULLTEXT 128 /* SerG: for full-text search */ +#define HA_FULLTEXT 128 /* For full-text search */ #define HA_UNIQUE_CHECK 256 /* Check the key for uniqueness */ -#define HA_SPATIAL 16 /* Alex Barkov: for spatial search */ +#define HA_SPATIAL 1024 /* For spatial search */ #define HA_NULL_ARE_EQUAL 2048 /* NULL in key are cmp as equal */ diff --git a/include/my_handler.h b/include/my_handler.h index 0fa30f580b6..629a0974d93 100644 --- a/include/my_handler.h +++ b/include/my_handler.h @@ -50,14 +50,10 @@ typedef struct st_HA_KEYSEG /* Key-portion */ { length=mi_uint2korr((key)+1); (key)+=3; length_pack=3; } \ } -extern int _mi_compare_text(CHARSET_INFO *, uchar *, uint, uchar *, uint , - my_bool); +extern int mi_compare_text(CHARSET_INFO *, uchar *, uint, uchar *, uint , + my_bool); extern int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, - register uchar *b, uint key_length, uint nextflag, - uint *diff_pos); - -extern int hp_rb_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, - register uchar *b, uint key_length, uint nextflag, - uint *diff_pos); + register uchar *b, uint key_length, uint nextflag, + uint *diff_pos); #endif /* _my_handler_h */ diff --git a/include/my_tree.h b/include/my_tree.h index 265bf69b1e7..826c2b7c808 100644 --- a/include/my_tree.h +++ b/include/my_tree.h @@ -20,7 +20,7 @@ extern "C" { #endif -#define MAX_TREE_HIGHT 40 /* = max 1048576 leafs in tree */ +#define MAX_TREE_HEIGHT 40 /* = max 1048576 leafs in tree */ #define ELEMENT_KEY(tree,element)\ (tree->offset_to_key ? (void*)((byte*) element+tree->offset_to_key) :\ *((void**) (element+1))) @@ -52,7 +52,7 @@ typedef struct st_tree_element { typedef struct st_tree { TREE_ELEMENT *root,null_element; - TREE_ELEMENT **parents[MAX_TREE_HIGHT]; + TREE_ELEMENT **parents[MAX_TREE_HEIGHT]; uint offset_to_key,elements_in_tree,size_of_element,memory_limit,allocated; qsort_cmp2 compare; void* custom_arg; diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c index 9b51601be40..0c5efcb50df 100644 --- a/myisam/ft_boolean_search.c +++ b/myisam/ft_boolean_search.c @@ -104,7 +104,7 @@ int FTB_WORD_cmp(void *v __attribute__((unused)), FTB_WORD *a, FTB_WORD *b) int FTB_WORD_cmp_list(void *v __attribute__((unused)), FTB_WORD **a, FTB_WORD **b) { /* ORDER BY word DESC, ndepth DESC */ - int i=_mi_compare_text(default_charset_info, (*b)->word+1,(*b)->len-1, + int i= mi_compare_text(default_charset_info, (*b)->word+1,(*b)->len-1, (*a)->word+1,(*a)->len-1,0); if (!i) i=CMP_NUM((*b)->ndepth,(*a)->ndepth); @@ -203,7 +203,7 @@ void _ftb_init_index_search(FT_INFO *ftb) SEARCH_FIND | SEARCH_BIGGER, keyroot); if (!r) { - r=_mi_compare_text(default_charset_info, + r= mi_compare_text(default_charset_info, info->lastkey + (ftbw->flags&FTB_FLAG_TRUNC), ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC), ftbw->word + (ftbw->flags&FTB_FLAG_TRUNC), @@ -359,7 +359,7 @@ int ft_boolean_read_next(FT_INFO *ftb, char *record) SEARCH_BIGGER , keyroot); if (!r) { - r=_mi_compare_text(default_charset_info, + r= mi_compare_text(default_charset_info, info->lastkey + (ftbw->flags&FTB_FLAG_TRUNC), ftbw->len - (ftbw->flags&FTB_FLAG_TRUNC), ftbw->word + (ftbw->flags&FTB_FLAG_TRUNC), @@ -443,7 +443,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) for (a=0, b=ftb->queue.elements, c=(a+b)/2; b-a>1; c=(a+b)/2) { ftbw=(FTB_WORD *)(ftb->list[c]); - if (_mi_compare_text(default_charset_info, word.pos,word.len, + if (mi_compare_text(default_charset_info, word.pos,word.len, (uchar*) ftbw->word+1,ftbw->len-1, (ftbw->flags&FTB_FLAG_TRUNC) ) >0) b=c; @@ -453,7 +453,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) for (; c>=0; c--) { ftbw=(FTB_WORD *)(ftb->list[c]); - if (_mi_compare_text(default_charset_info, word.pos,word.len, + if (mi_compare_text(default_charset_info, word.pos,word.len, (uchar*) ftbw->word+1,ftbw->len-1, (ftbw->flags&FTB_FLAG_TRUNC) )) break; diff --git a/myisam/ft_nlq_search.c b/myisam/ft_nlq_search.c index 635d6239359..5b12c4d4571 100644 --- a/myisam/ft_nlq_search.c +++ b/myisam/ft_nlq_search.c @@ -93,9 +93,9 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) while(!r) { - if (_mi_compare_text(default_charset_info, - aio->info->lastkey,keylen, - aio->keybuff,keylen,0)) break; + if (mi_compare_text(default_charset_info, + aio->info->lastkey,keylen, + aio->keybuff,keylen,0)) break; #if HA_FT_WTYPE == HA_KEYTYPE_FLOAT #ifdef EVAL_RUN diff --git a/myisam/ft_parser.c b/myisam/ft_parser.c index c514a923b63..93c574841f7 100644 --- a/myisam/ft_parser.c +++ b/myisam/ft_parser.c @@ -37,10 +37,10 @@ typedef struct st_ft_docstat { static int FT_WORD_cmp(void* cmp_arg, FT_WORD *w1, FT_WORD *w2) { - return _mi_compare_text(default_charset_info, - (uchar*) w1->pos, w1->len, - (uchar*) w2->pos, w2->len, - (my_bool) (cmp_arg != 0)); + return mi_compare_text(default_charset_info, + (uchar*) w1->pos, w1->len, + (uchar*) w2->pos, w2->len, + (my_bool) (cmp_arg != 0)); } static int walk_and_copy(FT_WORD *word,uint32 count,FT_DOCSTAT *docstat) diff --git a/myisam/ft_stopwords.c b/myisam/ft_stopwords.c index 0e4112bb29a..170442c71de 100644 --- a/myisam/ft_stopwords.c +++ b/myisam/ft_stopwords.c @@ -28,9 +28,9 @@ static TREE *stopwords3=NULL; static int FT_STOPWORD_cmp(void* cmp_arg __attribute__((unused)), FT_STOPWORD *w1, FT_STOPWORD *w2) { - return _mi_compare_text(default_charset_info, - (uchar *)w1->pos,w1->len, - (uchar *)w2->pos,w2->len,0); + return mi_compare_text(default_charset_info, + (uchar *)w1->pos,w1->len, + (uchar *)w2->pos,w2->len,0); } int ft_init_stopwords(const char **sws) diff --git a/myisam/ft_update.c b/myisam/ft_update.c index 8ffc35157d2..04b6becde86 100644 --- a/myisam/ft_update.c +++ b/myisam/ft_update.c @@ -160,7 +160,7 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2) { if ((ftsi1.pos != ftsi2.pos) && (!ftsi1.pos || !ftsi2.pos || - _mi_compare_text(default_charset_info, + mi_compare_text(default_charset_info, (uchar*) ftsi1.pos,ftsi1.len, (uchar*) ftsi2.pos,ftsi2.len,0))) return THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT; @@ -185,7 +185,7 @@ int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf, error=0; while(old_word->pos && new_word->pos) { - cmp=_mi_compare_text(default_charset_info, + cmp= mi_compare_text(default_charset_info, (uchar*) old_word->pos,old_word->len, (uchar*) new_word->pos,new_word->len,0); cmp2= cmp ? 0 : (fabs(old_word->weight - new_word->weight) > 1.e-5); diff --git a/myisam/mi_open.c b/myisam/mi_open.c index d2960c6751c..458d2d53dfc 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -920,7 +920,7 @@ uint mi_keydef_write(File file, MI_KEYDEF *keydef) uchar *ptr=buff; *ptr++ = (uchar) keydef->keysegs; - *ptr++ = keydef->key_alg; /* +BAR Rtree or Btree */ + *ptr++ = keydef->key_alg; /* Rtree or Btree */ mi_int2store(ptr,keydef->flag); ptr +=2; mi_int2store(ptr,keydef->block_length); ptr +=2; mi_int2store(ptr,keydef->keylength); ptr +=2; @@ -932,7 +932,7 @@ uint mi_keydef_write(File file, MI_KEYDEF *keydef) char *mi_keydef_read(char *ptr, MI_KEYDEF *keydef) { keydef->keysegs = (uint) *ptr++; - keydef->key_alg = *ptr++; /* +BAR Rtree or Btree */ + keydef->key_alg = *ptr++; /* Rtree or Btree */ keydef->flag = mi_uint2korr(ptr); ptr +=2; keydef->block_length = mi_uint2korr(ptr); ptr +=2; diff --git a/mysys/my_handler.c b/mysys/my_handler.c index 5544c7cc483..1e7d8a702d2 100644 --- a/mysys/my_handler.c +++ b/mysys/my_handler.c @@ -17,8 +17,8 @@ #include "my_handler.h" -int _mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length, - uchar *b, uint b_length, my_bool part_key) +int mi_compare_text(CHARSET_INFO *charset_info, uchar *a, uint a_length, + uchar *b, uint b_length, my_bool part_key) { int flag; @@ -58,18 +58,18 @@ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length, return (int) (a_length-b_length); } -#define CMP(a,b) (a0 acording to which is bigger -Key_length specifies length of key to use. Number-keys can't be splited -If flag <> SEARCH_FIND compare also position + Compare two keys + Returns <0, 0, >0 acording to which is bigger + Key_length specifies length of key to use. Number-keys can't be splited + If flag <> SEARCH_FIND compare also position */ + int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, - register uchar *b, uint key_length, uint nextflag, - uint *diff_pos) + register uchar *b, uint key_length, uint nextflag, + uint *diff_pos) { int flag; int16 s_1,s_2; @@ -83,13 +83,14 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++) { uchar *end; + uint piks=! (keyseg->flag & HA_NO_SORT); (*diff_pos)++; /* Handle NULL part */ if (keyseg->null_bit) { key_length--; - if (*a != *b) + if (*a != *b && piks) { flag = (int) *a - (int) *b; return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); @@ -115,7 +116,8 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, get_key_pack_length(b_length,pack_length,b); next_key_length=key_length-b_length-pack_length; - if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length, + if (piks && + (flag= mi_compare_text(keyseg->charset,a,a_length,b,b_length, (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); @@ -133,7 +135,8 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, while (b_length && b[b_length-1] == ' ') b_length--; } - if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length, + if (piks && + (flag= mi_compare_text(keyseg->charset,a,a_length,b,b_length, (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); @@ -149,7 +152,8 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, get_key_pack_length(b_length,pack_length,b); next_key_length=key_length-b_length-pack_length; - if ((flag=compare_bin(a,a_length,b,b_length, + if (piks && + (flag=compare_bin(a,a_length,b,b_length, (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); @@ -160,7 +164,8 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, else { uint length=keyseg->length; - if ((flag=compare_bin(a,length,b,length, + if (piks && + (flag=compare_bin(a,length,b,length, (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); @@ -175,7 +180,8 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, get_key_pack_length(b_length,pack_length,b); next_key_length=key_length-b_length-pack_length; - if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length, + if (piks && + (flag= mi_compare_text(keyseg->charset,a,a_length,b,b_length, (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); @@ -191,7 +197,8 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, get_key_pack_length(b_length,pack_length,b); next_key_length=key_length-b_length-pack_length; - if ((flag=compare_bin(a,a_length,b,b_length, + if (piks && + (flag=compare_bin(a,a_length,b,b_length, (my_bool) ((nextflag & SEARCH_PREFIX) && next_key_length <= 0)))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); @@ -204,7 +211,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, { int i_1= (int) *((signed char*) a); int i_2= (int) *((signed char*) b); - if ((flag = CMP(i_1,i_2))) + if (piks && (flag = CMP_NUM(i_1,i_2))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a= end; b++; @@ -213,7 +220,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, case HA_KEYTYPE_SHORT_INT: s_1= mi_sint2korr(a); s_2= mi_sint2korr(b); - if ((flag = CMP(s_1,s_2))) + if (piks && (flag = CMP_NUM(s_1,s_2))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a= end; b+= 2; /* sizeof(short int); */ @@ -223,7 +230,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, uint16 us_1,us_2; us_1= mi_sint2korr(a); us_2= mi_sint2korr(b); - if ((flag = CMP(us_1,us_2))) + if (piks && (flag = CMP_NUM(us_1,us_2))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a= end; b+=2; /* sizeof(short int); */ @@ -232,7 +239,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, case HA_KEYTYPE_LONG_INT: l_1= mi_sint4korr(a); l_2= mi_sint4korr(b); - if ((flag = CMP(l_1,l_2))) + if (piks && (flag = CMP_NUM(l_1,l_2))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a= end; b+= 4; /* sizeof(long int); */ @@ -240,7 +247,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, case HA_KEYTYPE_ULONG_INT: u_1= mi_sint4korr(a); u_2= mi_sint4korr(b); - if ((flag = CMP(u_1,u_2))) + if (piks && (flag = CMP_NUM(u_1,u_2))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a= end; b+= 4; /* sizeof(long int); */ @@ -248,7 +255,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, case HA_KEYTYPE_INT24: l_1=mi_sint3korr(a); l_2=mi_sint3korr(b); - if ((flag = CMP(l_1,l_2))) + if (piks && (flag = CMP_NUM(l_1,l_2))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a= end; b+= 3; @@ -256,7 +263,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, case HA_KEYTYPE_UINT24: l_1=mi_uint3korr(a); l_2=mi_uint3korr(b); - if ((flag = CMP(l_1,l_2))) + if (piks && (flag = CMP_NUM(l_1,l_2))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a= end; b+= 3; @@ -264,7 +271,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, case HA_KEYTYPE_FLOAT: mi_float4get(f_1,a); mi_float4get(f_2,b); - if ((flag = CMP(f_1,f_2))) + if (piks && (flag = CMP_NUM(f_1,f_2))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a= end; b+= 4; /* sizeof(float); */ @@ -272,7 +279,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, case HA_KEYTYPE_DOUBLE: mi_float8get(d_1,a); mi_float8get(d_2,b); - if ((flag = CMP(d_1,d_2))) + if (piks && (flag = CMP_NUM(d_1,d_2))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a= end; b+= 8; /* sizeof(double); */ @@ -303,32 +310,40 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, for ( ; blength && *b == ' ' ; b++, blength--) ; } - if (*a == '-') + if (piks) { - if (*b != '-') - return -1; - a++; b++; - swap(uchar*,a,b); - swap(int,alength,blength); - swap_flag=1-swap_flag; - alength--; blength--; - end=a+alength; + if (*a == '-') + { + if (*b != '-') + return -1; + a++; b++; + swap(uchar*,a,b); + swap(int,alength,blength); + swap_flag=1-swap_flag; + alength--; blength--; + end=a+alength; + } + else if (*b == '-') + return 1; + while (alength && (*a == '+' || *a == '0')) + { + a++; alength--; + } + while (blength && (*b == '+' || *b == '0')) + { + b++; blength--; + } + if (alength != blength) + return (alength < blength) ? -1 : 1; + while (a < end) + if (*a++ != *b++) + return ((int) a[-1] - (int) b[-1]); } - else if (*b == '-') - return 1; - while (alength && (*a == '+' || *a == '0')) + else { - a++; alength--; + b+=(end-a); + a=end; } - while (blength && (*b == '+' || *b == '0')) - { - b++; blength--; - } - if (alength != blength) - return (alength < blength) ? -1 : 1; - while (a < end) - if (*a++ != *b++) - return ((int) a[-1] - (int) b[-1]); if (swap_flag) /* Restore pointers */ swap(uchar*,a,b); @@ -340,7 +355,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, longlong ll_a,ll_b; ll_a= mi_sint8korr(a); ll_b= mi_sint8korr(b); - if ((flag = CMP(ll_a,ll_b))) + if (piks && (flag = CMP_NUM(ll_a,ll_b))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a= end; b+= 8; @@ -351,7 +366,7 @@ int ha_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, ulonglong ll_a,ll_b; ll_a= mi_uint8korr(a); ll_b= mi_uint8korr(b); - if ((flag = CMP(ll_a,ll_b))) + if (piks && (flag = CMP_NUM(ll_a,ll_b))) return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); a= end; b+= 8; @@ -385,333 +400,4 @@ end: return (flag < 0 ? -1 : 1); /* read previous */ } return 0; -} /* my_key_cmp */ - -/* -Compare two keys -Returns <0, 0, >0 acording to which is bigger -Key_length specifies length of key to use. Number-keys can't be splited -If flag <> SEARCH_FIND compare also position -*/ -int hp_rb_key_cmp(register HA_KEYSEG *keyseg, register uchar *a, - register uchar *b, uint key_length, uint nextflag, - uint *diff_pos) -{ - int flag; - int16 s_1,s_2; - int32 l_1,l_2; - uint32 u_1,u_2; - float f_1,f_2; - double d_1,d_2; - uint next_key_length; - - *diff_pos=0; - for ( ; (int) key_length >0 ; key_length=next_key_length, keyseg++) - { - uchar *end; - (*diff_pos)++; - - /* Handle NULL part */ - if (keyseg->null_bit) - { - key_length--; - if (*a != *b) - { - flag = (int) *a - (int) *b; - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - } - b++; - if (!*a++) /* If key was NULL */ - { - if (nextflag == (SEARCH_FIND | SEARCH_UPDATE)) - nextflag=SEARCH_SAME; /* Allow duplicate keys */ - next_key_length=key_length; - a+= keyseg->length; - b+= keyseg->length; - key_length-= keyseg->length; - continue; /* To next key part */ - } - } - end= a+ min(keyseg->length,key_length); - next_key_length=key_length-keyseg->length; - - switch ((enum ha_base_keytype) keyseg->type) { - case HA_KEYTYPE_TEXT: /* Ascii; Key is converted */ - if (keyseg->flag & HA_SPACE_PACK) - { - int a_length,b_length,pack_length; - get_key_length(a_length,a); - get_key_pack_length(b_length,pack_length,b); - next_key_length=key_length-b_length-pack_length; - - if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && - next_key_length <= 0)))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a+=a_length; - b+=b_length; - break; - } - else - { - uint length=(uint) (end-a), a_length=length, b_length=length; - if (!(nextflag & SEARCH_PREFIX)) - { - while (a_length && a[a_length-1] == ' ') - a_length--; - while (b_length && b[b_length-1] == ' ') - b_length--; - } - if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && - next_key_length <= 0)))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a=end; - b+=length; - } - break; - case HA_KEYTYPE_BINARY: - if (keyseg->flag & HA_SPACE_PACK) - { - int a_length,b_length,pack_length; - get_key_length(a_length,a); - get_key_pack_length(b_length,pack_length,b); - next_key_length=key_length-b_length-pack_length; - - if ((flag=compare_bin(a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && - next_key_length <= 0)))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a+=a_length; - b+=b_length; - break; - } - else - { - uint length=keyseg->length; - if ((flag=compare_bin(a,length,b,length, - (my_bool) ((nextflag & SEARCH_PREFIX) && - next_key_length <= 0)))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a+=length; - b+=length; - } - break; - case HA_KEYTYPE_VARTEXT: - { - int a_length,b_length,pack_length; - get_key_length(a_length,a); - get_key_pack_length(b_length,pack_length,b); - next_key_length=key_length-b_length-pack_length; - - if ((flag=_mi_compare_text(keyseg->charset,a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && - next_key_length <= 0)))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a+=a_length; - b+=b_length; - break; - } - break; - case HA_KEYTYPE_VARBINARY: - { - int a_length,b_length,pack_length; - get_key_length(a_length,a); - get_key_pack_length(b_length,pack_length,b); - next_key_length=key_length-b_length-pack_length; - - if ((flag=compare_bin(a,a_length,b,b_length, - (my_bool) ((nextflag & SEARCH_PREFIX) && - next_key_length <= 0)))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a+=a_length; - b+=b_length; - break; - } - break; - case HA_KEYTYPE_INT8: - { - int i_1= (int) *((signed char*) a); - int i_2= (int) *((signed char*) b); - if ((flag = CMP(i_1,i_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b++; - break; - } - case HA_KEYTYPE_SHORT_INT: - s_1= mi_sint2korr(a); - s_2= mi_sint2korr(b); - if ((flag = CMP(s_1,s_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 2; /* sizeof(short int); */ - break; - case HA_KEYTYPE_USHORT_INT: - { - uint16 us_1,us_2; - us_1= mi_sint2korr(a); - us_2= mi_sint2korr(b); - if ((flag = CMP(us_1,us_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+=2; /* sizeof(short int); */ - break; - } - case HA_KEYTYPE_LONG_INT: - l_1= mi_sint4korr(a); - l_2= mi_sint4korr(b); - if ((flag = CMP(l_1,l_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 4; /* sizeof(long int); */ - break; - case HA_KEYTYPE_ULONG_INT: - u_1= mi_sint4korr(a); - u_2= mi_sint4korr(b); - if ((flag = CMP(u_1,u_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 4; /* sizeof(long int); */ - break; - case HA_KEYTYPE_INT24: - l_1=mi_sint3korr(a); - l_2=mi_sint3korr(b); - if ((flag = CMP(l_1,l_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 3; - break; - case HA_KEYTYPE_UINT24: - l_1=mi_uint3korr(a); - l_2=mi_uint3korr(b); - if ((flag = CMP(l_1,l_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 3; - break; - case HA_KEYTYPE_FLOAT: - mi_float4get(f_1,a); - mi_float4get(f_2,b); - if ((flag = CMP(f_1,f_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 4; /* sizeof(float); */ - break; - case HA_KEYTYPE_DOUBLE: - mi_float8get(d_1,a); - mi_float8get(d_2,b); - if ((flag = CMP(d_1,d_2))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 8; /* sizeof(double); */ - break; - case HA_KEYTYPE_NUM: /* Numeric key */ - { - int swap_flag= 0; - int alength,blength; - - if (keyseg->flag & HA_REVERSE_SORT) - { - swap(uchar*,a,b); - swap_flag=1; /* Remember swap of a & b */ - end= a+ (int) (end-b); - } - if (keyseg->flag & HA_SPACE_PACK) - { - alength= *a++; blength= *b++; - end=a+alength; - next_key_length=key_length-blength-1; - } - else - { - alength= (int) (end-a); - blength=keyseg->length; - /* remove pre space from keys */ - for ( ; alength && *a == ' ' ; a++, alength--) ; - for ( ; blength && *b == ' ' ; b++, blength--) ; - } - - if (*a == '-') - { - if (*b != '-') - return -1; - a++; b++; - swap(uchar*,a,b); - swap(int,alength,blength); - swap_flag=1-swap_flag; - alength--; blength--; - end=a+alength; - } - else if (*b == '-') - return 1; - while (alength && (*a == '+' || *a == '0')) - { - a++; alength--; - } - while (blength && (*b == '+' || *b == '0')) - { - b++; blength--; - } - if (alength != blength) - return (alength < blength) ? -1 : 1; - while (a < end) - if (*a++ != *b++) - return ((int) a[-1] - (int) b[-1]); - - if (swap_flag) /* Restore pointers */ - swap(uchar*,a,b); - break; - } -#ifdef HAVE_LONG_LONG - case HA_KEYTYPE_LONGLONG: - { - longlong ll_a,ll_b; - ll_a= mi_sint8korr(a); - ll_b= mi_sint8korr(b); - if ((flag = CMP(ll_a,ll_b))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 8; - break; - } - case HA_KEYTYPE_ULONGLONG: - { - ulonglong ll_a,ll_b; - ll_a= mi_uint8korr(a); - ll_b= mi_uint8korr(b); - if ((flag = CMP(ll_a,ll_b))) - return ((keyseg->flag & HA_REVERSE_SORT) ? -flag : flag); - a= end; - b+= 8; - break; - } -#endif - case HA_KEYTYPE_END: /* Ready */ - goto end; /* diff_pos is incremented */ - } - } - (*diff_pos)++; -end: - if (!(nextflag & SEARCH_FIND)) - { - uint i; - if (nextflag & (SEARCH_NO_FIND | SEARCH_LAST)) /* Find record after key */ - return (nextflag & (SEARCH_BIGGER | SEARCH_LAST)) ? -1 : 1; - flag=0; - for (i=keyseg->length ; i-- > 0 ; ) - { - if (*a++ != *b++) - { - flag= FCMP(a[-1],b[-1]); - break; - } - } - if (nextflag & SEARCH_SAME) - return (flag); /* read same */ - if (nextflag & SEARCH_BIGGER) - return (flag <= 0 ? -1 : 1); /* read next */ - return (flag < 0 ? -1 : 1); /* read previous */ - } - return 0; -} /* my_key_cmp */ +} /* ha_key_cmp */ diff --git a/mysys/tree.c b/mysys/tree.c index 632660344b5..1bd49ef5182 100644 --- a/mysys/tree.c +++ b/mysys/tree.c @@ -380,17 +380,17 @@ void *tree_search_key(TREE *tree, const void *key, Search first (the most left) or last (the most right) tree element */ void *tree_search_edge(TREE *tree, TREE_ELEMENT **parents, - TREE_ELEMENT ***last_pos, int child_offs) + TREE_ELEMENT ***last_pos, int child_offs) { - TREE_ELEMENT *element = tree->root; + TREE_ELEMENT *element= tree->root; - *parents = &tree->null_element; + *parents= &tree->null_element; while (element != &tree->null_element) { - *++parents = element; - element = ELEMENT_CHILD(element, child_offs); + *++parents= element; + element= ELEMENT_CHILD(element, child_offs); } - *last_pos = parents; + *last_pos= parents; return **last_pos != &tree->null_element ? ELEMENT_KEY(tree, **last_pos) : NULL; } @@ -398,26 +398,26 @@ void *tree_search_edge(TREE *tree, TREE_ELEMENT **parents, void *tree_search_next(TREE *tree, TREE_ELEMENT ***last_pos, int l_offs, int r_offs) { - TREE_ELEMENT *x = **last_pos; + TREE_ELEMENT *x= **last_pos; if (ELEMENT_CHILD(x, r_offs) != &tree->null_element) { - x = ELEMENT_CHILD(x, r_offs); - *++*last_pos = x; + x= ELEMENT_CHILD(x, r_offs); + *++*last_pos= x; while (ELEMENT_CHILD(x, l_offs) != &tree->null_element) { - x = ELEMENT_CHILD(x, l_offs); - *++*last_pos = x; + x= ELEMENT_CHILD(x, l_offs); + *++*last_pos= x; } return ELEMENT_KEY(tree, x); } else { - TREE_ELEMENT *y = *--*last_pos; + TREE_ELEMENT *y= *--*last_pos; while (y != &tree->null_element && x == ELEMENT_CHILD(y, r_offs)) { - x = y; - y = *--*last_pos; + x= y; + y= *--*last_pos; } return y == &tree->null_element ? NULL : ELEMENT_KEY(tree, y); } @@ -431,28 +431,26 @@ uint tree_record_pos(TREE *tree, const void *key, enum ha_rkey_function flag, void *custom_arg) { int cmp; - TREE_ELEMENT *element = tree->root; - uint left = 1; - uint right = tree->elements_in_tree; - uint last_left_step_pos = tree->elements_in_tree; - uint last_right_step_pos = 1; - uint last_equal_pos = HA_POS_ERROR; + TREE_ELEMENT *element= tree->root; + double left= 1; + double right= tree->elements_in_tree; + uint last_equal_pos= HA_POS_ERROR; while (element != &tree->null_element) { - if ((cmp = (*tree->compare)(custom_arg, ELEMENT_KEY(tree, element), - key)) == 0) + if ((cmp= (*tree->compare)(custom_arg, ELEMENT_KEY(tree, element), + key)) == 0) { switch (flag) { case HA_READ_KEY_EXACT: - last_equal_pos = (left + right) >> 1; - cmp = 1; + last_equal_pos= (left + right) / 2; + cmp= 1; break; case HA_READ_BEFORE_KEY: - cmp = 1; + cmp= 1; break; case HA_READ_AFTER_KEY: - cmp = -1; + cmp= -1; break; default: return HA_POS_ERROR; @@ -460,24 +458,22 @@ uint tree_record_pos(TREE *tree, const void *key, } if (cmp < 0) /* element < key */ { - last_right_step_pos = (left + right) >> 1; - element = element->right; - left = last_right_step_pos; + element= element->right; + left= (left + right) / 2; } else { - last_left_step_pos = (left + right) >> 1; - element = element->left; - right = last_left_step_pos; + element= element->left; + right= (left + right) / 2; } } switch (flag) { case HA_READ_KEY_EXACT: return last_equal_pos; case HA_READ_BEFORE_KEY: - return last_right_step_pos; + return (uint) right; case HA_READ_AFTER_KEY: - return last_left_step_pos; + return (uint) left; default: return HA_POS_ERROR; } diff --git a/sql/field.cc b/sql/field.cc index bd4b8e9f29d..75cbedbb71b 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -257,7 +257,7 @@ bool Field::send(THD *thd, String *packet) if (is_null()) return net_store_null(packet); char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff),default_charset_info); val_str(&tmp,&tmp); CONVERT *convert; if ((convert=thd->convert_set)) @@ -320,7 +320,7 @@ uint Field::fill_cache_field(CACHE_FIELD *copy) bool Field::get_date(TIME *ltime,bool fuzzydate) { char buff[40]; - String tmp(buff,sizeof(buff)),tmp2,*res; + String tmp(buff,sizeof(buff),default_charset_info),tmp2,*res; if (!(res=val_str(&tmp,&tmp2)) || str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE) return 1; @@ -330,7 +330,7 @@ bool Field::get_date(TIME *ltime,bool fuzzydate) bool Field::get_time(TIME *ltime) { char buff[40]; - String tmp(buff,sizeof(buff)),tmp2,*res; + String tmp(buff,sizeof(buff),default_charset_info),tmp2,*res; if (!(res=val_str(&tmp,&tmp2)) || str_to_time(res->ptr(),res->length(),ltime)) return 1; @@ -344,22 +344,22 @@ void Field::store_time(TIME *ltime,timestamp_type type) char buff[25]; switch (type) { case TIMESTAMP_NONE: - store("",0); // Probably an error + store("",0,default_charset_info); // Probably an error break; case TIMESTAMP_DATE: sprintf(buff,"%04d-%02d-%02d", ltime->year,ltime->month,ltime->day); - store(buff,10); + store(buff,10,default_charset_info); break; case TIMESTAMP_FULL: sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d", ltime->year,ltime->month,ltime->day, ltime->hour,ltime->minute,ltime->second); - store(buff,19); + store(buff,19,default_charset_info); break; case TIMESTAMP_TIME: sprintf(buff, "%02d:%02d:%02d", ltime->hour,ltime->minute,ltime->second); - store(buff,(uint) strlen(buff)); + store(buff,(uint) strlen(buff),default_charset_info); break; } } @@ -378,7 +378,7 @@ bool Field::optimize_range(uint idx) void Field_decimal::reset(void) { - Field_decimal::store("0",1); + Field_decimal::store("0",1,default_charset_info); } void Field_decimal::overflow(bool negative) @@ -397,7 +397,7 @@ void Field_decimal::overflow(bool negative) } -void Field_decimal::store(const char *from,uint len) +void Field_decimal::store(const char *from,uint len,CHARSET_INFO *cs) { reg3 int i; uint tmp_dec; @@ -589,7 +589,7 @@ String *Field_decimal::val_str(String *val_buffer __attribute__((unused)), if (field_length < tmp_length) // Error in data val_ptr->length(0); else - val_ptr->set((const char*) str,field_length-tmp_length); + val_ptr->set((const char*) str,field_length-tmp_length,default_charset_info); return val_ptr; } @@ -672,9 +672,9 @@ void Field_decimal::sql_type(String &res) const ** tiny int ****************************************************************************/ -void Field_tiny::store(const char *from,uint len) +void Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); long tmp= strtol(tmp_str.c_ptr(),NULL,10); if (unsigned_flag) @@ -843,9 +843,9 @@ void Field_tiny::sql_type(String &res) const // Note: Sometimes this should be fixed to use one strtol() to use // len and check for garbage after number. -void Field_short::store(const char *from,uint len) +void Field_short::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); long tmp= strtol(tmp_str.c_ptr(),NULL,10); if (unsigned_flag) { @@ -1083,9 +1083,9 @@ void Field_short::sql_type(String &res) const // Note: Sometimes this should be fixed to use one strtol() to use // len and check for garbage after number. -void Field_medium::store(const char *from,uint len) +void Field_medium::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); long tmp= strtol(tmp_str.c_ptr(),NULL,10); if (unsigned_flag) @@ -1268,14 +1268,14 @@ void Field_medium::sql_type(String &res) const // Note: Sometimes this should be fixed to use one strtol() to use // len and check for garbage after number. -void Field_long::store(const char *from,uint len) +void Field_long::store(const char *from,uint len,CHARSET_INFO *cs) { while (len && my_isspace(system_charset_info,*from)) { len--; from++; } long tmp; - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); errno=0; if (unsigned_flag) { @@ -1496,14 +1496,14 @@ void Field_long::sql_type(String &res) const ** longlong int ****************************************************************************/ -void Field_longlong::store(const char *from,uint len) +void Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) { while (len && my_isspace(system_charset_info,*from)) { // For easy error check len--; from++; } longlong tmp; - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); errno=0; if (unsigned_flag) { @@ -1703,9 +1703,9 @@ void Field_longlong::sql_type(String &res) const ** single precision float ****************************************************************************/ -void Field_float::store(const char *from,uint len) +void Field_float::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); errno=0; Field_float::store(atof(tmp_str.c_ptr())); if (errno || current_thd->count_cuted_fields && !test_if_real(from,len)) @@ -1953,9 +1953,9 @@ void Field_float::sql_type(String &res) const ** double precision floating point numbers ****************************************************************************/ -void Field_double::store(const char *from,uint len) +void Field_double::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); errno=0; double j= atof(tmp_str.c_ptr()); if (errno || current_thd->count_cuted_fields && !test_if_real(from,len)) @@ -2209,7 +2209,7 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, } -void Field_timestamp::store(const char *from,uint len) +void Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) { long tmp=(long) str_to_timestamp(from,len); #ifdef WORDS_BIGENDIAN @@ -2548,7 +2548,7 @@ void Field_timestamp::set_time() ** Stored as a 3 byte unsigned int ****************************************************************************/ -void Field_time::store(const char *from,uint len) +void Field_time::store(const char *from,uint len,CHARSET_INFO *cs) { TIME ltime; long tmp; @@ -2688,7 +2688,7 @@ void Field_time::sort_string(char *to,uint length __attribute__((unused))) void Field_time::sql_type(String &res) const { - res.set("time",4); + res.set("time",4,default_charset_info); } /**************************************************************************** @@ -2697,9 +2697,9 @@ void Field_time::sql_type(String &res) const ** Can handle 2 byte or 4 byte years! ****************************************************************************/ -void Field_year::store(const char *from, uint len) +void Field_year::store(const char *from, uint len,CHARSET_INFO *cs) { - String tmp_str(from,len); + String tmp_str(from,len,default_charset_info); long nr= strtol(tmp_str.c_ptr(),NULL,10); if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155) @@ -2786,7 +2786,7 @@ void Field_year::sql_type(String &res) const ** Stored as a 4 byte unsigned int ****************************************************************************/ -void Field_date::store(const char *from, uint len) +void Field_date::store(const char *from, uint len,CHARSET_INFO *cs) { TIME l_time; uint32 tmp; @@ -2934,7 +2934,7 @@ void Field_date::sort_string(char *to,uint length __attribute__((unused))) void Field_date::sql_type(String &res) const { - res.set("date",4); + res.set("date",4,default_charset_info); } /**************************************************************************** @@ -2943,7 +2943,7 @@ void Field_date::sql_type(String &res) const ** In number context: YYYYMMDD ****************************************************************************/ -void Field_newdate::store(const char *from,uint len) +void Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) { TIME l_time; long tmp; @@ -3085,7 +3085,7 @@ void Field_newdate::sort_string(char *to,uint length __attribute__((unused))) void Field_newdate::sql_type(String &res) const { - res.set("date",4); + res.set("date",4,default_charset_info); } @@ -3096,7 +3096,7 @@ void Field_newdate::sql_type(String &res) const ** Stored as a 8 byte unsigned int. Should sometimes be change to a 6 byte int. ****************************************************************************/ -void Field_datetime::store(const char *from,uint len) +void Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) { longlong tmp=str_to_datetime(from,len,1); #ifdef WORDS_BIGENDIAN @@ -3302,7 +3302,7 @@ void Field_datetime::sort_string(char *to,uint length __attribute__((unused))) void Field_datetime::sql_type(String &res) const { - res.set("datetime",8); + res.set("datetime",8,default_charset_info); } /**************************************************************************** @@ -3312,8 +3312,9 @@ void Field_datetime::sql_type(String &res) const /* Copy a string and fill with space */ -void Field_string::store(const char *from,uint length) +void Field_string::store(const char *from,uint length,CHARSET_INFO *cs) { + field_charset=cs; #ifdef USE_TIS620 if(!binary_flag) { ThNormalize((uchar *)ptr, field_length, (uchar *)from, length); @@ -3354,7 +3355,7 @@ void Field_string::store(double nr) int width=min(field_length,DBL_DIG+5); sprintf(buff,"%-*.*g",width,max(width-5,0),nr); end=strcend(buff,' '); - Field_string::store(buff,(uint) (end - buff)); + Field_string::store(buff,(uint) (end - buff), default_charset_info); } @@ -3362,7 +3363,7 @@ void Field_string::store(longlong nr) { char buff[22]; char *end=longlong10_to_str(nr,buff,-10); - Field_string::store(buff,(uint) (end-buff)); + Field_string::store(buff,(uint) (end-buff), default_charset_info); } @@ -3397,7 +3398,7 @@ String *Field_string::val_str(String *val_buffer __attribute__((unused)), #endif while (end > ptr && end[-1] == ' ') end--; - val_ptr->set((const char*) ptr,(uint) (end - ptr)); + val_ptr->set((const char*) ptr,(uint) (end - ptr),field_charset); return val_ptr; } @@ -3516,8 +3517,9 @@ uint Field_string::max_packed_col_length(uint max_length) ****************************************************************************/ -void Field_varstring::store(const char *from,uint length) +void Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) { + field_charset=cs; #ifdef USE_TIS620 if(!binary_flag) { @@ -3545,7 +3547,7 @@ void Field_varstring::store(double nr) int width=min(field_length,DBL_DIG+5); sprintf(buff,"%-*.*g",width,max(width-5,0),nr); end=strcend(buff,' '); - Field_varstring::store(buff,(uint) (end - buff)); + Field_varstring::store(buff,(uint) (end - buff), default_charset_info); } @@ -3553,7 +3555,7 @@ void Field_varstring::store(longlong nr) { char buff[22]; char *end=longlong10_to_str(nr,buff,-10); - Field_varstring::store(buff,(uint) (end-buff)); + Field_varstring::store(buff,(uint) (end-buff), default_charset_info); } @@ -3585,7 +3587,7 @@ String *Field_varstring::val_str(String *val_buffer __attribute__((unused)), String *val_ptr) { uint length=uint2korr(ptr); - val_ptr->set((const char*) ptr+2,length); + val_ptr->set((const char*) ptr+2,length,field_charset); return val_ptr; } @@ -3741,7 +3743,7 @@ Field_blob::Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, bool binary_arg) :Field_str(ptr_arg, (1L << min(blob_pack_length,3)*8)-1L, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, - table_arg), + table_arg, default_charset_info), packlength(blob_pack_length),binary_flag(binary_arg), geom_flag(true) { flags|= BLOB_FLAG; @@ -3833,8 +3835,9 @@ uint32 Field_blob::get_length(const char *pos) } -void Field_blob::store(const char *from,uint len) +void Field_blob::store(const char *from,uint len,CHARSET_INFO *cs) { + field_charset=cs; if (!len) { bzero(ptr,Field_blob::pack_length()); @@ -3872,14 +3875,14 @@ void Field_blob::store(const char *from,uint len) void Field_blob::store(double nr) { value.set(nr); - Field_blob::store(value.ptr(),(uint) value.length()); + Field_blob::store(value.ptr(),(uint) value.length(), default_charset_info); } void Field_blob::store(longlong nr) { value.set(nr); - Field_blob::store(value.ptr(), (uint) value.length()); + Field_blob::store(value.ptr(), (uint) value.length(), default_charset_info); } @@ -3922,9 +3925,9 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)), char *blob; memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); if (!blob) - val_ptr->set("",0); // A bit safer than ->length(0) + val_ptr->set("",0,default_charset_info); // A bit safer than ->length(0) else - val_ptr->set((const char*) blob,get_length(ptr)); + val_ptr->set((const char*) blob,get_length(ptr),default_charset_info); return val_ptr; } @@ -4026,7 +4029,7 @@ void Field_blob::get_key_image(char *buff,uint length, imagetype type) void Field_blob::set_key_image(char *buff,uint length) { length=uint2korr(buff); - Field_blob::store(buff+2,length); + Field_blob::store(buff+2,length, default_charset_info); } void Field_geom::get_key_image(char *buff,uint length, imagetype type) @@ -4121,7 +4124,7 @@ void Field_blob::sql_type(String &res) const case 3: str="medium"; break; case 4: str="long"; break; } - res.set(str,(uint) strlen(str)); + res.set(str,(uint) strlen(str),default_charset_info); res.append(binary_flag ? "blob" : "text"); } @@ -4342,7 +4345,7 @@ uint find_enum(TYPELIB *lib,const char *x, uint length) ** (if there isn't a empty value in the enum) */ -void Field_enum::store(const char *from,uint length) +void Field_enum::store(const char *from,uint length,CHARSET_INFO *cs) { uint tmp=find_enum(typelib,from,length); if (!tmp) @@ -4448,7 +4451,8 @@ String *Field_enum::val_str(String *val_buffer __attribute__((unused)), val_ptr->length(0); else val_ptr->set((const char*) typelib->type_names[tmp-1], - (uint) strlen(typelib->type_names[tmp-1])); + (uint) strlen(typelib->type_names[tmp-1]), + default_charset_info); return val_ptr; } @@ -4534,7 +4538,7 @@ ulonglong find_set(TYPELIB *lib,const char *x,uint length) } -void Field_set::store(const char *from,uint length) +void Field_set::store(const char *from,uint length,CHARSET_INFO *cs) { ulonglong tmp=find_set(typelib,from,length); if (!tmp && length && length < 22) @@ -4585,7 +4589,8 @@ String *Field_set::val_str(String *val_buffer, if (val_buffer->length()) val_buffer->append(field_separator); String str(typelib->type_names[bitnr], - (uint) strlen(typelib->type_names[bitnr])); + (uint) strlen(typelib->type_names[bitnr]), + default_charset_info); val_buffer->append(str); } tmp>>=1; @@ -4723,7 +4728,7 @@ Field *make_field(char *ptr, uint32 field_length, if (!f_is_packed(pack_flag)) return new Field_string(ptr,field_length,null_pos,null_bit, unireg_check, field_name, table, - f_is_binary(pack_flag) != 0); + f_is_binary(pack_flag) != 0, default_charset_info); uint pack_length=calc_pack_length((enum_field_types) f_packtype(pack_flag), @@ -4853,7 +4858,7 @@ create_field::create_field(Field *old_field,Field *orig_field) orig_field) { char buff[MAX_FIELD_WIDTH],*pos; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff),default_charset_info); /* Get the value from record[2] (the default value row) */ my_ptrdiff_t diff= (my_ptrdiff_t) (orig_field->table->rec_buff_length*2); @@ -4865,7 +4870,7 @@ create_field::create_field(Field *old_field,Field *orig_field) { pos= (char*) sql_memdup(tmp.ptr(),tmp.length()+1); pos[tmp.length()]=0; - def=new Item_string(pos,tmp.length()); + def=new Item_string(pos,tmp.length(),default_charset_info); } } } diff --git a/sql/field.h b/sql/field.h index baedf9e78e7..cf7c2a50218 100644 --- a/sql/field.h +++ b/sql/field.h @@ -59,7 +59,7 @@ public: utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg); virtual ~Field() {} - virtual void store(const char *to,uint length)=0; + virtual void store(const char *to,uint length,CHARSET_INFO *cs)=0; virtual void store(double nr)=0; virtual void store(longlong nr)=0; virtual void store_time(TIME *ltime,timestamp_type t_type); @@ -242,16 +242,17 @@ public: Field_str(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg) + struct st_table *table_arg,CHARSET_INFO *charset) :Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, table_arg) - { field_charset=default_charset_info; } + { field_charset=charset; } Item_result result_type () const { return STRING_RESULT; } uint decimals() const { return NOT_FIXED_DEC; } friend class create_field; void make_field(Send_field *); uint size_of() const { return sizeof(*this); } inline CHARSET_INFO *charset() const { return field_charset; } + inline void set_charset(CHARSET_INFO *charset) { field_charset=charset; } inline int cmp_image(char *buff,uint length) { if (binary()) @@ -278,7 +279,7 @@ public: enum ha_base_keytype key_type() const { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; } void reset(void); - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); double val_real(void); @@ -307,7 +308,7 @@ public: enum_field_types type() const { return FIELD_TYPE_TINY;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_BINARY : HA_KEYTYPE_INT8; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=0; } @@ -336,7 +337,7 @@ public: enum_field_types type() const { return FIELD_TYPE_SHORT;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_USHORT_INT : HA_KEYTYPE_SHORT_INT;} - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=ptr[1]=0; } @@ -365,7 +366,7 @@ public: enum_field_types type() const { return FIELD_TYPE_INT24;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_UINT24 : HA_KEYTYPE_INT24; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } @@ -399,7 +400,7 @@ public: enum_field_types type() const { return FIELD_TYPE_LONG;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_ULONG_INT : HA_KEYTYPE_LONG_INT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } @@ -435,7 +436,7 @@ public: enum_field_types type() const { return FIELD_TYPE_LONGLONG;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_ULONGLONG : HA_KEYTYPE_LONGLONG; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; } @@ -462,7 +463,7 @@ public: {} enum_field_types type() const { return FIELD_TYPE_FLOAT;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { bzero(ptr,sizeof(float)); } @@ -494,7 +495,7 @@ public: {} enum_field_types type() const { return FIELD_TYPE_DOUBLE;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { bzero(ptr,sizeof(double)); } @@ -517,10 +518,10 @@ public: enum utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str(ptr_arg, len_arg, null, 1, - unireg_check_arg, field_name_arg, table_arg) + unireg_check_arg, field_name_arg, table_arg, default_charset_info) {} enum_field_types type() const { return FIELD_TYPE_NULL;} - void store(const char *to, uint length) { null[0]=1; } + void store(const char *to, uint length, CHARSET_INFO *cs) { null[0]=1; } void store(double nr) { null[0]=1; } void store(longlong nr) { null[0]=1; } void reset(void) {} @@ -531,7 +532,7 @@ public: int cmp(const char *a, const char *b) { return 0;} void sort_string(char *buff, uint length) {} uint32 pack_length() const { return 0; } - void sql_type(String &str) const { str.set("null",4); } + void sql_type(String &str) const { str.set("null",4,default_charset_info); } uint size_of() const { return sizeof(*this); } }; @@ -544,7 +545,7 @@ public: enum Item_result result_type () const { return field_length == 8 || field_length == 14 ? INT_RESULT : STRING_RESULT; } enum_field_types type() const { return FIELD_TYPE_TIMESTAMP;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } @@ -584,7 +585,7 @@ public: unireg_check_arg, field_name_arg, table_arg, 1, 1) {} enum_field_types type() const { return FIELD_TYPE_YEAR;} - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); double val_real(void); @@ -600,16 +601,16 @@ public: enum utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg) + unireg_check_arg, field_name_arg, table_arg, default_charset_info) {} Field_date(bool maybe_null_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str((char*) 0,10, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg) {} + NONE, field_name_arg, table_arg, default_charset_info) {} enum_field_types type() const { return FIELD_TYPE_DATE;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; } enum Item_result cmp_type () const { return INT_RESULT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } @@ -630,13 +631,13 @@ public: enum utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg) + unireg_check_arg, field_name_arg, table_arg, default_charset_info) {} enum_field_types type() const { return FIELD_TYPE_DATE;} enum_field_types real_type() const { return FIELD_TYPE_NEWDATE; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; } enum Item_result cmp_type () const { return INT_RESULT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void store_time(TIME *ltime,timestamp_type type); @@ -661,16 +662,16 @@ public: enum utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str(ptr_arg, 8, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg) + unireg_check_arg, field_name_arg, table_arg, default_charset_info) {} Field_time(bool maybe_null_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str((char*) 0,8, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg) {} + NONE, field_name_arg, table_arg, default_charset_info) {} enum_field_types type() const { return FIELD_TYPE_TIME;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; } enum Item_result cmp_type () const { return INT_RESULT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } @@ -693,18 +694,18 @@ public: enum utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str(ptr_arg, 19, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg) + unireg_check_arg, field_name_arg, table_arg, default_charset_info) {} Field_datetime(bool maybe_null_arg, const char *field_name_arg, struct st_table *table_arg) :Field_str((char*) 0,19, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg) {} + NONE, field_name_arg, table_arg, default_charset_info) {} enum_field_types type() const { return FIELD_TYPE_DATETIME;} #ifdef HAVE_LONG_LONG enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; } #endif enum Item_result cmp_type () const { return INT_RESULT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void store_time(TIME *ltime,timestamp_type type); @@ -729,18 +730,18 @@ public: Field_string(char *ptr_arg, uint32 len_arg,uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg,bool binary_arg) + struct st_table *table_arg,bool binary_arg, CHARSET_INFO *cs) :Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg), + unireg_check_arg, field_name_arg, table_arg,cs), binary_flag(binary_arg) { if (binary_arg) flags|=BINARY_FLAG; } Field_string(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, bool binary_arg) + struct st_table *table_arg, bool binary_arg, CHARSET_INFO *cs) :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg), + NONE, field_name_arg, table_arg, cs), binary_flag(binary_arg) { if (binary_arg) @@ -758,7 +759,7 @@ public: bool zero_pack() const { return 0; } bool binary() const { return binary_flag; } void reset(void) { bfill(ptr,field_length,' '); } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); double val_real(void); @@ -784,18 +785,18 @@ public: Field_varstring(char *ptr_arg, uint32 len_arg,uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg,bool binary_arg) + struct st_table *table_arg,bool binary_arg, CHARSET_INFO *cs) :Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg), + unireg_check_arg, field_name_arg, table_arg, cs), binary_flag(binary_arg) { if (binary_arg) flags|=BINARY_FLAG; } Field_varstring(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, bool binary_arg) + struct st_table *table_arg, bool binary_arg, CHARSET_INFO *cs) :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg), + NONE, field_name_arg, table_arg, cs), binary_flag(binary_arg) { if (binary_arg) @@ -810,7 +811,7 @@ public: void reset(void) { bzero(ptr,field_length+2); } uint32 pack_length() const { return (uint32) field_length+2; } uint32 key_length() const { return (uint32) field_length; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); double val_real(void); @@ -843,7 +844,7 @@ public: Field_blob(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, struct st_table *table_arg, bool binary_arg) :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg), + NONE, field_name_arg, table_arg, default_charset_info), packlength(3),binary_flag(binary_arg), geom_flag(true) { flags|= BLOB_FLAG; @@ -853,7 +854,7 @@ public: enum_field_types type() const { return FIELD_TYPE_BLOB;} enum ha_base_keytype key_type() const { return binary_flag ? HA_KEYTYPE_VARBINARY : HA_KEYTYPE_VARTEXT; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); double val_real(void); @@ -950,7 +951,7 @@ public: struct st_table *table_arg,uint packlength_arg, TYPELIB *typelib_arg) :Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg), + unireg_check_arg, field_name_arg, table_arg, default_charset_info), packlength(packlength_arg),typelib(typelib_arg) { flags|=ENUM_FLAG; @@ -958,7 +959,7 @@ public: enum_field_types type() const { return FIELD_TYPE_STRING; } enum Item_result cmp_type () const { return INT_RESULT; } enum ha_base_keytype key_type() const; - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr); void store(longlong nr); void reset() { bzero(ptr,packlength); } @@ -993,7 +994,7 @@ public: { flags=(flags & ~ENUM_FLAG) | SET_FLAG; } - void store(const char *to,uint length); + void store(const char *to,uint length,CHARSET_INFO *charset); void store(double nr) { Field_set::store((longlong) nr); } void store(longlong nr); virtual bool zero_pack() const { return 1; } diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 02be0365002..3b6de1383e2 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -228,7 +228,7 @@ static void do_conv_blob(Copy_field *copy) { copy->from_field->val_str(©->tmp,©->tmp); ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(), - copy->tmp.length()); + copy->tmp.length(),default_charset_info); } /* Save blob in copy->tmp for GROUP BY */ @@ -236,20 +236,20 @@ static void do_conv_blob(Copy_field *copy) static void do_save_blob(Copy_field *copy) { char buff[MAX_FIELD_WIDTH]; - String res(buff,sizeof(buff)); + String res(buff,sizeof(buff),default_charset_info); copy->from_field->val_str(&res,&res); copy->tmp.copy(res); ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(), - copy->tmp.length()); + copy->tmp.length(),default_charset_info); } static void do_field_string(Copy_field *copy) { char buff[MAX_FIELD_WIDTH]; - copy->tmp.set_quick(buff,sizeof(buff)); + copy->tmp.set_quick(buff,sizeof(buff),default_charset_info); copy->from_field->val_str(©->tmp,©->tmp); - copy->to_field->store(copy->tmp.c_ptr_quick(),copy->tmp.length()); + copy->to_field->store(copy->tmp.c_ptr_quick(),copy->tmp.length(),default_charset_info); } @@ -508,7 +508,7 @@ void field_conv(Field *to,Field *from) if (!blob->value.is_alloced() && from->real_type() != FIELD_TYPE_STRING) blob->value.copy(); - blob->store(blob->value.ptr(),blob->value.length()); + blob->store(blob->value.ptr(),blob->value.length(),default_charset_info); return; } if ((from->result_type() == STRING_RESULT && @@ -518,9 +518,9 @@ void field_conv(Field *to,Field *from) to->type() == FIELD_TYPE_DECIMAL) { char buff[MAX_FIELD_WIDTH]; - String result(buff,sizeof(buff)); + String result(buff,sizeof(buff),default_charset_info); from->val_str(&result,&result); - to->store(result.c_ptr_quick(),result.length()); + to->store(result.c_ptr_quick(),result.length(),default_charset_info); } else if (from->result_type() == REAL_RESULT) to->store(from->val_real()); diff --git a/sql/filesort.cc b/sql/filesort.cc index 3bde4eeae14..b7745ccb8ca 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -77,10 +77,19 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length, SORTPARAM param; DBUG_ENTER("filesort"); DBUG_EXECUTE("info",TEST_filesort(sortorder,s_length,special);); + CHARSET_INFO *charset=table->table_charset; + uint i; #ifdef SKIP_DBUG_IN_FILESORT DBUG_PUSH(""); /* No DBUG here */ #endif + // BAR TODO: this is not absolutely correct, but OK for now + for(i=0;ifields;i++) + if (!table->field[i]->binary()) + charset=((Field_str*)(table->field[i]))->charset(); + charset=charset?charset:default_charset_info; + // /BAR TODO + outfile= table->io_cache; my_b_clear(&tempfile); my_b_clear(&buffpek_pointers); @@ -129,7 +138,7 @@ ha_rows filesort(TABLE *table, SORT_FIELD *sortorder, uint s_length, records=param.max_rows; /* purecov: inspected */ #ifdef USE_STRCOLL - if (use_strcoll(default_charset_info) && + if (use_strcoll(charset) && !(param.tmp_buffer=my_malloc(param.sort_length,MYF(MY_WME)))) goto err; #endif @@ -467,12 +476,10 @@ static void make_sortkey(register SORTPARAM *param, switch (sort_field->result_type) { case STRING_RESULT: { - CHARSET_INFO *cs=item->str_value.charset(); - if (item->maybe_null) *to++=1; /* All item->str() to use some extra byte for end null.. */ - String tmp((char*) to,sort_field->length+4); + String tmp((char*) to,sort_field->length+4,default_charset_info); String *res=item->val_str(&tmp); if (!res) { @@ -487,6 +494,7 @@ static void make_sortkey(register SORTPARAM *param, break; } length=res->length(); + CHARSET_INFO *cs=res->charset(); int diff=(int) (sort_field->length-length); if (diff < 0) { @@ -923,7 +931,6 @@ sortlength(SORT_FIELD *sortorder, uint s_length) #ifdef USE_STRCOLL if (!sortorder->field->binary()) { - // BAR TODO: need checking that it is really Field_str based class CHARSET_INFO *cs=((Field_str*)(sortorder->field))->charset(); if (use_strcoll(cs)) sortorder->length= sortorder->length*cs->strxfrm_multiply; diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 43485a97fe3..70409be4e42 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -42,9 +42,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) { parts+=table->key_info[key].key_parts; if (table->key_info[key].algorithm == HA_KEY_ALG_BTREE) - { parts++; /* additional HA_KEYTYPE_END keyseg */ - } } if (!(keydef=(HP_KEYDEF*) my_malloc(table->keys*sizeof(HP_KEYDEF)+ @@ -55,7 +53,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) { KEY *pos=table->key_info+key; KEY_PART_INFO *key_part= pos->key_part; - KEY_PART_INFO *key_part_end= key_part+pos->key_parts; + KEY_PART_INFO *key_part_end= key_part + pos->key_parts; mem_per_row+= (pos->key_length + (sizeof(char*) * 2)); @@ -85,7 +83,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) seg->start= (uint) key_part->offset; seg->length= (uint) key_part->length; seg->flag = 0; - seg->charset= default_charset_info; + seg->charset= field->binary() ? NULL : ((Field_str*)field)->charset(); if (field->null_ptr) { seg->null_bit= field->null_bit; @@ -94,14 +92,13 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked) } else { - seg->null_bit=0; - seg->null_pos=0; + seg->null_bit= 0; + seg->null_pos= 0; } } if (pos->algorithm == HA_KEY_ALG_BTREE) { /* additional HA_KEYTYPE_END keyseg */ - keydef[key].keysegs++; seg->type= HA_KEYTYPE_END; seg->length= sizeof(byte*); seg->flag= 0; diff --git a/sql/handler.cc b/sql/handler.cc index 7947ae5a9f0..47c59be0166 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -665,7 +665,7 @@ void handler::print_error(int error, myf errflag) { /* Write the dupplicated key in the error message */ char key[MAX_KEY_LENGTH]; - String str(key,sizeof(key)); + String str(key,sizeof(key),default_charset_info); key_unpack(&str,table,(uint) key_nr); uint max_length=MYSQL_ERRMSG_SIZE-(uint) strlen(ER(ER_DUP_ENTRY)); if (str.length() >= max_length) diff --git a/sql/item.cc b/sql/item.cc index 13141ade2a8..8a785ee3902 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -89,7 +89,7 @@ bool Item_string::eq(const Item *item, bool binary_cmp) const bool Item::get_date(TIME *ltime,bool fuzzydate) { char buff[40]; - String tmp(buff,sizeof(buff)),*res; + String tmp(buff,sizeof(buff),default_charset_info),*res; if (!(res=val_str(&tmp)) || str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE) { @@ -107,7 +107,7 @@ bool Item::get_date(TIME *ltime,bool fuzzydate) bool Item::get_time(TIME *ltime) { char buff[40]; - String tmp(buff,sizeof(buff)),*res; + String tmp(buff,sizeof(buff),default_charset_info),*res; if (!(res=val_str(&tmp)) || str_to_time(res->ptr(),res->length(),ltime)) { @@ -484,14 +484,15 @@ bool Item::save_in_field(Field *field) field->result_type() == STRING_RESULT) { String *result; + CHARSET_INFO *cs=field->binary()?default_charset_info:((Field_str*)field)->charset(); char buff[MAX_FIELD_WIDTH]; // Alloc buffer for small columns - str_value.set_quick(buff,sizeof(buff)); + str_value.set_quick(buff,sizeof(buff),cs); result=val_str(&str_value); if (null_value) return set_field_to_null(field); field->set_notnull(); - field->store(result->ptr(),result->length()); - str_value.set_quick(0, 0); + field->store(result->ptr(),result->length(),cs); + str_value.set_quick(0, 0, cs); } else if (result_type() == REAL_RESULT) { @@ -515,11 +516,12 @@ bool Item::save_in_field(Field *field) bool Item_string::save_in_field(Field *field) { String *result; + CHARSET_INFO *cs=field->binary()?default_charset_info:((Field_str*)field)->charset(); result=val_str(&str_value); if (null_value) return set_field_to_null(field); field->set_notnull(); - field->store(result->ptr(),result->length()); + field->store(result->ptr(),result->length(),cs); return 0; } @@ -556,14 +558,14 @@ inline uint char_val(char X) X-'a'+10); } -Item_varbinary::Item_varbinary(const char *str, uint str_length) +Item_varbinary::Item_varbinary(const char *str, uint str_length, CHARSET_INFO *cs) { name=(char*) str-2; // Lex makes this start with 0x max_length=(str_length+1)/2; char *ptr=(char*) sql_alloc(max_length+1); if (!ptr) return; - str_value.set(ptr,max_length); + str_value.set(ptr,max_length,cs); char *end=ptr+max_length; if (max_length*2 != str_length) *ptr++=char_val(*str++); // Not even, assume 0 prefix @@ -590,10 +592,11 @@ longlong Item_varbinary::val_int() bool Item_varbinary::save_in_field(Field *field) { + CHARSET_INFO *cs=field->binary()?default_charset_info:((Field_str*)field)->charset(); field->set_notnull(); if (field->result_type() == STRING_RESULT) { - field->store(str_value.ptr(),str_value.length()); + field->store(str_value.ptr(),str_value.length(),cs); } else { @@ -617,7 +620,7 @@ bool Item::send(THD *thd, String *packet) { char buff[MAX_FIELD_WIDTH]; CONVERT *convert; - String s(buff,sizeof(buff)),*res; + String s(buff,sizeof(buff),packet->charset()),*res; if (!(res=val_str(&s))) return net_store_null(packet); if ((convert=thd->convert_set)) @@ -676,7 +679,7 @@ Item *resolve_const_item(Item *item,Item *comp_item) if (res_type == STRING_RESULT) { char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)),*result; + String tmp(buff,sizeof(buff),default_charset_info),*result; result=item->val_str(&tmp); if (item->null_value) { @@ -690,7 +693,7 @@ Item *resolve_const_item(Item *item,Item *comp_item) #ifdef DELETE_ITEMS delete item; #endif - return new Item_string(name,tmp_str,length); + return new Item_string(name,tmp_str,length,default_charset_info); } if (res_type == INT_RESULT) { @@ -731,8 +734,8 @@ bool field_is_equal_to_item(Field *field,Item *item) { char item_buff[MAX_FIELD_WIDTH]; char field_buff[MAX_FIELD_WIDTH]; - String item_tmp(item_buff,sizeof(item_buff)),*item_result; - String field_tmp(field_buff,sizeof(field_buff)); + String item_tmp(item_buff,sizeof(item_buff),default_charset_info),*item_result; + String field_tmp(field_buff,sizeof(field_buff),default_charset_info); item_result=item->val_str(&item_tmp); if (item->null_value) return 1; // This must be true diff --git a/sql/item.h b/sql/item.h index 2bd1cb99bf5..f9879f2f70d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -241,16 +241,16 @@ public: class Item_string :public Item { public: - Item_string(const char *str,uint length) + Item_string(const char *str,uint length,CHARSET_INFO *cs) { - str_value.set(str,length); + str_value.set(str,length,cs); max_length=length; name=(char*) str_value.ptr(); decimals=NOT_FIXED_DEC; } - Item_string(const char *name_par,const char *str,uint length) + Item_string(const char *name_par,const char *str,uint length,CHARSET_INFO *cs) { - str_value.set(str,length); + str_value.set(str,length,cs); max_length=length; name=(char*) name_par; decimals=NOT_FIXED_DEC; @@ -265,7 +265,7 @@ public: enum Item_result result_type () const { return STRING_RESULT; } bool basic_const_item() const { return 1; } bool eq(const Item *item, bool binary_cmp) const; - Item *new_item() { return new Item_string(name,str_value.ptr(),max_length); } + Item *new_item() { return new Item_string(name,str_value.ptr(),max_length,default_charset_info); } String *const_string() { return &str_value; } inline void append(char *str,uint length) { str_value.append(str,length); } void print(String *str); @@ -276,7 +276,7 @@ public: class Item_datetime :public Item_string { public: - Item_datetime(const char *item_name): Item_string(item_name,"",0) + Item_datetime(const char *item_name): Item_string(item_name,"",0,default_charset_info) { max_length=19;} void make_field(Send_field *field); }; @@ -284,14 +284,14 @@ public: class Item_empty_string :public Item_string { public: - Item_empty_string(const char *header,uint length) :Item_string("",0) + Item_empty_string(const char *header,uint length) :Item_string("",0,default_charset_info) { name=(char*) header; max_length=length;} }; class Item_varbinary :public Item { public: - Item_varbinary(const char *str,uint str_length); + Item_varbinary(const char *str,uint str_length,CHARSET_INFO *cs); ~Item_varbinary() {} enum Type type() const { return VARBIN_ITEM; } double val() { return (double) Item_varbinary::val_int(); } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index c34440d92d4..072eaf51567 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -687,7 +687,7 @@ String *Item_func_case::val_str(String *str) longlong Item_func_case::val_int() { char buff[MAX_FIELD_WIDTH]; - String dummy_str(buff,sizeof(buff)); + String dummy_str(buff,sizeof(buff),default_charset_info); Item *item=find_item(&dummy_str); longlong res; @@ -704,7 +704,7 @@ longlong Item_func_case::val_int() double Item_func_case::val() { char buff[MAX_FIELD_WIDTH]; - String dummy_str(buff,sizeof(buff)); + String dummy_str(buff,sizeof(buff),default_charset_info); Item *item=find_item(&dummy_str); double res; @@ -876,7 +876,7 @@ int in_vector::find(Item *item) in_string::in_string(uint elements,qsort_cmp cmp_func) - :in_vector(elements,sizeof(String),cmp_func),tmp(buff,sizeof(buff)) + :in_vector(elements,sizeof(String),cmp_func),tmp(buff,sizeof(buff),default_charset_info) {} in_string::~in_string() @@ -1272,7 +1272,7 @@ Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables) if (!regex_compiled && args[1]->const_item()) { char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff),default_charset_info); String *res=args[1]->val_str(&tmp); if (args[1]->null_value) { // Will always return NULL @@ -1301,7 +1301,7 @@ Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables) longlong Item_func_regex::val_int() { char buff[MAX_FIELD_WIDTH]; - String *res, tmp(buff,sizeof(buff)); + String *res, tmp(buff,sizeof(buff),default_charset_info); res=args[0]->val_str(&tmp); if (args[0]->null_value) @@ -1312,7 +1312,7 @@ longlong Item_func_regex::val_int() if (!regex_is_const) { char buff2[MAX_FIELD_WIDTH]; - String *res2, tmp2(buff2,sizeof(buff2)); + String *res2, tmp2(buff2,sizeof(buff2),default_charset_info); res2= args[1]->val_str(&tmp2); if (args[1]->null_value) diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index b8f21f21008..350e369eaac 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -341,7 +341,7 @@ class cmp_item_sort_string :public cmp_item { char value_buff[80]; String value,*value_res; public: - cmp_item_sort_string() :value(value_buff,sizeof(value_buff)) {} + cmp_item_sort_string() :value(value_buff,sizeof(value_buff),default_charset_info) {} void store_value(Item *item) { value_res=item->val_str(&value); @@ -349,7 +349,7 @@ public: int cmp(Item *arg) { char buff[80]; - String tmp(buff,sizeof(buff)),*res; + String tmp(buff,sizeof(buff),default_charset_info),*res; if (!(res=arg->val_str(&tmp))) return 1; /* Can't be right */ return sortcmp(value_res,res); @@ -362,7 +362,7 @@ public: int cmp(Item *arg) { char buff[80]; - String tmp(buff,sizeof(buff)),*res; + String tmp(buff,sizeof(buff),default_charset_info),*res; if (!(res=arg->val_str(&tmp))) return 1; /* Can't be right */ return stringcmp(value_res,res); diff --git a/sql/item_create.cc b/sql/item_create.cc index 79d7fcfe230..9204d23b8c2 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -227,7 +227,7 @@ Item *create_func_lpad(Item* a, Item *b, Item *c) Item *create_func_ltrim(Item* a) { - return new Item_func_ltrim(a,new Item_string(" ",1)); + return new Item_func_ltrim(a,new Item_string(" ",1,default_charset_info)); } Item *create_func_md5(Item* a) @@ -309,7 +309,7 @@ Item *create_func_rpad(Item* a, Item *b, Item *c) Item *create_func_rtrim(Item* a) { - return new Item_func_rtrim(a,new Item_string(" ",1)); + return new Item_func_rtrim(a,new Item_string(" ",1,default_charset_info)); } Item *create_func_sec_to_time(Item* a) @@ -329,7 +329,7 @@ Item *create_func_sin(Item* a) Item *create_func_space(Item *a) { - return new Item_func_repeat(new Item_string(" ",1),a); + return new Item_func_repeat(new Item_string(" ",1,default_charset_info),a); } Item *create_func_soundex(Item* a) @@ -374,7 +374,9 @@ Item *create_func_ucase(Item* a) Item *create_func_version(void) { - return new Item_string(NullS,server_version, (uint) strlen(server_version)); + return new Item_string(NullS,server_version, + (uint) strlen(server_version), + default_charset_info); } Item *create_func_weekday(Item* a) diff --git a/sql/item_func.cc b/sql/item_func.cc index 9d4895788fc..057518fb5f2 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1296,7 +1296,7 @@ String *udf_handler::val_str(String *str,String *save_str) str->length(res_length); return str; } - save_str->set(res, res_length); + save_str->set(res, res_length, default_charset_info); return save_str; } @@ -1438,7 +1438,7 @@ void item_user_lock_release(ULL *ull) THD *thd = current_thd; uint save_query_length; char buf[256]; - String tmp(buf,sizeof(buf)); + String tmp(buf,sizeof(buf), default_charset_info); tmp.length(0); tmp.append("DO RELEASE_LOCK(\""); tmp.append(ull->key,ull->key_length); @@ -1695,7 +1695,7 @@ longlong Item_func_set_last_insert_id::val_int() longlong Item_func_benchmark::val_int() { char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff), default_charset_info); THD *thd=current_thd; for (ulong loop=0 ; loop < loop_count && !thd->killed; loop++) @@ -1832,7 +1832,7 @@ Item_func_set_user_var::update() break; case STRING_RESULT: char buffer[MAX_FIELD_WIDTH]; - String tmp(buffer,sizeof(buffer)); + String tmp(buffer,sizeof(buffer),default_charset_info); (void) val_str(&tmp); break; } @@ -2006,7 +2006,7 @@ longlong Item_func_inet_aton::val_int() char c = '.'; // we mark c to indicate invalid IP in case length is 0 char buff[36]; - String *s,tmp(buff,sizeof(buff)); + String *s,tmp(buff,sizeof(buff),default_charset_info); if (!(s = args[0]->val_str(&tmp))) // If null value goto err; null_value=0; @@ -2052,17 +2052,17 @@ void Item_func_match::init_search(bool no_order) } if (key == NO_SUCH_KEY) - concat=new Item_func_concat_ws (new Item_string(" ",1), fields); + concat=new Item_func_concat_ws (new Item_string(" ",1,default_charset_info), fields); String *ft_tmp=0; char tmp1[FT_QUERY_MAXLEN]; - String tmp2(tmp1,sizeof(tmp1)); + String tmp2(tmp1,sizeof(tmp1),default_charset_info); // MATCH ... AGAINST (NULL) is meaningless, but possible if (!(ft_tmp=key_item()->val_str(&tmp2))) { ft_tmp=&tmp2; - tmp2.set("",0); + tmp2.set("",0,default_charset_info); } ft_handler=table->file->ft_init_ext(mode, key, diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9c791453fd8..e3436ac4641 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -35,7 +35,7 @@ #endif /* HAVE_OPENSSL */ #include "md5.h" -String empty_string(""); +String empty_string("",default_charset_info); uint nr_of_decimals(const char *str) { @@ -371,7 +371,7 @@ error: String *Item_func_concat_ws::val_str(String *str) { char tmp_str_buff[10]; - String tmp_sep_str(tmp_str_buff, sizeof(tmp_str_buff)), + String tmp_sep_str(tmp_str_buff, sizeof(tmp_str_buff),default_charset_info), *sep_str, *res, *res2,*use_as_buff; uint i; @@ -989,7 +989,7 @@ String *Item_func_ltrim::val_str(String *str) if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff),res->charset()); String *remove_str=args[1]->val_str(&tmp); uint remove_length; LINT_INIT(remove_length); @@ -1027,7 +1027,7 @@ String *Item_func_rtrim::val_str(String *str) if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff),res->charset()); String *remove_str=args[1]->val_str(&tmp); uint remove_length; LINT_INIT(remove_length); @@ -1099,7 +1099,7 @@ String *Item_func_trim::val_str(String *str) if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff),res->charset()); String *remove_str=args[1]->val_str(&tmp); uint remove_length; LINT_INIT(remove_length); @@ -1154,7 +1154,7 @@ String *Item_func_password::val_str(String *str) if (res->length() == 0) return &empty_string; make_scrambled_password(tmp_value,res->c_ptr()); - str->set(tmp_value,16); + str->set(tmp_value,16,res->charset()); return str; } @@ -1188,7 +1188,7 @@ String *Item_func_encrypt::val_str(String *str) } pthread_mutex_lock(&LOCK_crypt); char *tmp=crypt(res->c_ptr(),salt_ptr); - str->set(tmp,(uint) strlen(tmp)); + str->set(tmp,(uint) strlen(tmp),res->charset()); str->copy(); pthread_mutex_unlock(&LOCK_crypt); return str; @@ -1240,7 +1240,7 @@ String *Item_func_database::val_str(String *str) if (!current_thd->db) str->length(0); else - str->set((const char*) current_thd->db,(uint) strlen(current_thd->db)); + str->set((const char*) current_thd->db,(uint) strlen(current_thd->db), default_charset_info); return str; } @@ -2035,7 +2035,7 @@ String* Item_func_export_set::val_str(String* str) } break; case 3: - sep_buf.set(",", 1); + sep_buf.set(",", 1, default_charset_info); sep = &sep_buf; } null_value=0; @@ -2154,7 +2154,7 @@ String *Item_func_geometry_type::val_str(String *str) if ((null_value=(args[0]->null_value || geom.create_from_wkb(wkt->ptr(),wkt->length())))) return 0; - str->copy(geom.get_class_info()->m_name); + str->copy(geom.get_class_info()->m_name,strlen(geom.get_class_info()->m_name)); return str; } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 350c4b3d793..03ef65c352a 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -37,10 +37,12 @@ public: void left_right_max_length(); Field *tmp_table_field(TABLE *t_arg) { - if (!t_arg) return result_field; - return (max_length > 255) ? - (Field *) new Field_blob(max_length,maybe_null, name,t_arg, binary) : - (Field *) new Field_string(max_length,maybe_null, name,t_arg, binary); + if (!t_arg) + return result_field; + return (max_length > 255) ? + (Field *)new Field_blob(max_length,maybe_null, name,t_arg, binary) : + (Field *) new Field_string(max_length,maybe_null, name,t_arg, binary, + default_charset_info); } }; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index ecb908a797b..698f80928bb 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -513,7 +513,7 @@ void Item_sum_hybrid::reset_field() if (hybrid_type == STRING_RESULT) { char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)),*res; + String tmp(buff,sizeof(buff),default_charset_info),*res; res=args[0]->val_str(&tmp); if (args[0]->null_value) @@ -524,7 +524,7 @@ void Item_sum_hybrid::reset_field() else { result_field->set_notnull(); - result_field->store(res->ptr(),res->length()); + result_field->store(res->ptr(),res->length(),tmp.charset()); } } else if (hybrid_type == INT_RESULT) @@ -694,7 +694,7 @@ Item_sum_hybrid::min_max_update_str_field(int offset) if (result_field->is_null() || (cmp_sign * (binary ? stringcmp(res_str,&tmp_value) : sortcmp(res_str,&tmp_value)) < 0)) - result_field->store(res_str->ptr(),res_str->length()); + result_field->store(res_str->ptr(),res_str->length(),res_str->charset()); else { // Use old value char *res=result_field->ptr; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 404d44d7122..9bbb9e4fe19 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -29,11 +29,31 @@ ** Todo: Move month and days to language files */ -static String month_names[] = { "January", "February", "March", "April", - "May", "June", "July", "August", - "September", "October", "November", "December" }; -static String day_names[] = { "Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday" ,"Sunday" }; +static String month_names[] = +{ + String("January", default_charset_info), + String("February", default_charset_info), + String("March", default_charset_info), + String("April", default_charset_info), + String("May", default_charset_info), + String("June", default_charset_info), + String("July", default_charset_info), + String("August", default_charset_info), + String("September", default_charset_info), + String("October", default_charset_info), + String("November", default_charset_info), + String("December", default_charset_info) +}; +static String day_names[] = +{ + String("Monday", default_charset_info), + String("Tuesday", default_charset_info), + String("Wednesday", default_charset_info), + String("Thursday", default_charset_info), + String("Friday", default_charset_info), + String("Saturday", default_charset_info), + String("Sunday", default_charset_info) +}; /* ** Get a array of positive numbers from a string object. @@ -376,7 +396,7 @@ String *Item_date::val_str(String *str) return (String*) 0; if (!value) // zero daynr { - str->copy("0000-00-00"); + str->copy("0000-00-00",10); return str; } if (str->alloc(11)) diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index aa4140192ab..9ff2734f460 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -271,7 +271,7 @@ public: double val() { return (double) value; } longlong val_int() { return value; } String *val_str(String *str) - { str_value.set(buff,buff_length); return &str_value; } + { str_value.set(buff,buff_length,default_charset_info); return &str_value; } const char *func_name() const { return "curtime"; } void fix_length_and_dec(); void make_field(Send_field *tmp_field) @@ -313,7 +313,7 @@ public: longlong val_int() { return value; } bool save_in_field(Field *to); String *val_str(String *str) - { str_value.set(buff,buff_length); return &str_value; } + { str_value.set(buff,buff_length,default_charset_info); return &str_value; } const char *func_name() const { return "now"; } void fix_length_and_dec(); bool get_date(TIME *res,bool fuzzy_date); diff --git a/sql/log_event.cc b/sql/log_event.cc index fd04f8dbbaa..cd116f867c2 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -213,7 +213,7 @@ void Log_event::pack_info(String* packet) void Query_log_event::pack_info(String* packet) { char buf[256]; - String tmp(buf, sizeof(buf)); + String tmp(buf, sizeof(buf), system_charset_info); tmp.length(0); if (db && db_len) { @@ -230,7 +230,7 @@ void Query_log_event::pack_info(String* packet) void Start_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; @@ -244,7 +244,7 @@ void Start_log_event::pack_info(String* packet) void Load_log_event::pack_info(String* packet) { char buf[256]; - String tmp(buf, sizeof(buf)); + String tmp(buf, sizeof(buf), system_charset_info); tmp.length(0); if(db && db_len) { @@ -320,7 +320,7 @@ void Load_log_event::pack_info(String* packet) void Rotate_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; tmp.append(new_log_ident, ident_len); @@ -334,7 +334,7 @@ void Rotate_log_event::pack_info(String* packet) void Intvar_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; tmp.append(get_var_type_name()); @@ -346,7 +346,7 @@ void Intvar_log_event::pack_info(String* packet) void Slave_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; tmp.append("host="); @@ -1417,7 +1417,7 @@ void Create_file_log_event::print(FILE* file, bool short_form, void Create_file_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; tmp.append("db="); @@ -1475,7 +1475,7 @@ void Append_block_log_event::print(FILE* file, bool short_form, void Append_block_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; tmp.append(";file_id="); @@ -1524,7 +1524,7 @@ void Delete_file_log_event::print(FILE* file, bool short_form, void Delete_file_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; tmp.append(";file_id="); @@ -1571,7 +1571,7 @@ void Execute_load_log_event::print(FILE* file, bool short_form, void Execute_load_log_event::pack_info(String* packet) { char buf1[256]; - String tmp(buf1, sizeof(buf1)); + String tmp(buf1, sizeof(buf1), system_charset_info); tmp.length(0); char buf[22]; tmp.append(";file_id="); @@ -1690,12 +1690,12 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli) handle_dup = DUP_REPLACE; sql_exchange ex((char*)fname, sql_ex.opt_flags && DUMPFILE_FLAG ); - String field_term(sql_ex.field_term,sql_ex.field_term_len); - String enclosed(sql_ex.enclosed,sql_ex.enclosed_len); - String line_term(sql_ex.line_term,sql_ex.line_term_len); - String line_start(sql_ex.line_start,sql_ex.line_start_len); - String escaped(sql_ex.escaped,sql_ex.escaped_len); - + String field_term(sql_ex.field_term,sql_ex.field_term_len, system_charset_info); + String enclosed(sql_ex.enclosed,sql_ex.enclosed_len, system_charset_info); + String line_term(sql_ex.line_term,sql_ex.line_term_len, system_charset_info); + String line_start(sql_ex.line_start,sql_ex.line_start_len, system_charset_info); + String escaped(sql_ex.escaped,sql_ex.escaped_len, system_charset_info); + ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG); if (sql_ex.empty_flags & FIELD_TERM_EMPTY) ex.field_term->length(0); diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc index 1ab3e18424f..a201651fc2f 100644 --- a/sql/net_pkg.cc +++ b/sql/net_pkg.cc @@ -334,7 +334,7 @@ net_store_data(String *packet,struct tm *tmp) bool net_store_data(String* packet, I_List* str_list) { char buf[256]; - String tmp(buf, sizeof(buf)); + String tmp(buf, sizeof(buf), default_charset_info); tmp.length(0); I_List_iterator it(*str_list); i_string* s; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 9f547c6e0ca..ccee7192682 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -930,7 +930,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, { bool like_error; char buff1[MAX_FIELD_WIDTH],*min_str,*max_str; - String tmp(buff1,sizeof(buff1)),*res; + String tmp(buff1,sizeof(buff1),default_charset_info),*res; uint length,offset,min_length,max_length; if (!field->optimize_range((uint) key_part->key)) @@ -2836,7 +2836,7 @@ static void print_key(KEY_PART *key_part,const char *key,uint used_length) { char buff[1024]; - String tmp(buff,sizeof(buff)); + String tmp(buff,sizeof(buff),default_charset_info); for (uint length=0; length < used_length ; diff --git a/sql/spatial.cc b/sql/spatial.cc index 32942a70dc2..bb6e03c3c03 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -680,13 +680,16 @@ int GPolygon::centroid_xy(double *x, double *y) const uint32 i; double res_area, res_cx, res_cy; const char *data = m_data; + LINT_INIT(res_area); + LINT_INIT(res_cx); + LINT_INIT(res_cy); if (no_data(data, 4)) return 1; n_linear_rings = uint4korr(data); data += 4; - for(i = 0; i < n_linear_rings; ++i) + for (i = 0; i < n_linear_rings; ++i) { if (no_data(data, 4)) return 1; @@ -720,7 +723,8 @@ int GPolygon::centroid_xy(double *x, double *y) const cur_area = fabs(cur_area) / 2; cur_cx = cur_cx / (n_points - 1); cur_cy = cur_cy / (n_points - 1); - if(i) + + if (i) { double d_area = res_area - cur_area; if (d_area <= 0) @@ -1195,6 +1199,10 @@ int GMultiPolygon::centroid(String *result) const double res_area, res_cx, res_cy; double cur_area, cur_cx, cur_cy; + LINT_INIT(res_area); + LINT_INIT(res_cx); + LINT_INIT(res_cy); + const char *data = m_data; if (no_data(data, 4)) return 1; @@ -1211,7 +1219,7 @@ int GMultiPolygon::centroid(String *result) const if (p.centroid_xy(&cur_cx, &cur_cy)) return 1; - if(i) + if (i) { double sum_area = res_area + cur_area; res_cx = (res_area * res_cx + cur_area * cur_cx) / sum_area; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 1398b2ce84f..f8f13c35e35 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -377,7 +377,7 @@ static uint get_access(TABLE *form,uint fieldnr) { uint access_bits=0,bit; char buff[2]; - String res(buff,sizeof(buff)); + String res(buff,sizeof(buff),default_charset_info); Field **pos; for (pos=form->field+fieldnr,bit=1 ; *pos ; pos++ , bit<<=1) @@ -1091,8 +1091,8 @@ static bool update_user_table(THD *thd, const char *host, const char *user, tables.db=(char*) "mysql"; if (!(table=open_ltable(thd,&tables,TL_WRITE))) DBUG_RETURN(1); /* purecov: deadcode */ - table->field[0]->store(host,(uint) strlen(host)); - table->field[1]->store(user,(uint) strlen(user)); + table->field[0]->store(host,(uint) strlen(host), system_charset_info); + table->field[1]->store(user,(uint) strlen(user), system_charset_info); if (table->file->index_read_idx(table->record[0],0, (byte*) table->field[0]->ptr,0, @@ -1102,7 +1102,7 @@ static bool update_user_table(THD *thd, const char *host, const char *user, DBUG_RETURN(1); /* purecov: deadcode */ } store_record(table,1); - table->field[2]->store(new_password,(uint) strlen(new_password)); + table->field[2]->store(new_password,(uint) strlen(new_password), system_charset_info); if ((error=table->file->update_row(table->record[1],table->record[0]))) { table->file->print_error(error,MYF(0)); /* purecov: deadcode */ @@ -1161,8 +1161,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, empty_string[0]=0; } - table->field[0]->store(combo.host.str,combo.host.length); - table->field[1]->store(combo.user.str,combo.user.length); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(combo.user.str,combo.user.length, system_charset_info); table->file->index_init(0); if (table->file->index_read(table->record[0], (byte*) table->field[0]->ptr,0, @@ -1183,17 +1183,17 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, goto end; } old_row_exists = 0; - restore_record(table,2); // cp empty row from record[2] - table->field[0]->store(combo.host.str,combo.host.length); - table->field[1]->store(combo.user.str,combo.user.length); - table->field[2]->store(password,(uint) strlen(password)); + restore_record(table,2); // cp empty row from record[2] + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(combo.user.str,combo.user.length, system_charset_info); + table->field[2]->store(password,(uint) strlen(password), system_charset_info); } else { old_row_exists = 1; store_record(table,1); // Save copy for update if (combo.password.str) // If password given - table->field[2]->store(password,(uint) strlen(password)); + table->field[2]->store(password,(uint) strlen(password), system_charset_info); } for (i = 3, j = SELECT_ACL; // starting from reload @@ -1201,7 +1201,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, i++, j <<= 1) { if (j & rights) // set requested privileges - table->field[i]->store(&what,1); + table->field[i]->store(&what,1, system_charset_info); } rights=get_access(table,3); #ifdef HAVE_OPENSSL @@ -1209,30 +1209,30 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, DBUG_PRINT("info",("table->fields=%d",table->fields)); if (table->fields >= 21) /* From 4.0.0 we have more fields */ { - table->field[18]->store("",0); - table->field[19]->store("",0); - table->field[20]->store("",0); + table->field[18]->store("",0, system_charset_info); + table->field[19]->store("",0, system_charset_info); + table->field[20]->store("",0, system_charset_info); switch (thd->lex.ssl_type) { case SSL_TYPE_ANY: - table->field[17]->store("ANY",3); + table->field[17]->store("ANY",3, system_charset_info); break; case SSL_TYPE_X509: - table->field[17]->store("X509",4); + table->field[17]->store("X509",4, system_charset_info); break; case SSL_TYPE_SPECIFIED: - table->field[17]->store("SPECIFIED",9); + table->field[17]->store("SPECIFIED",9, system_charset_info); if (thd->lex.ssl_cipher) table->field[18]->store(thd->lex.ssl_cipher, - strlen(thd->lex.ssl_cipher)); + strlen(thd->lex.ssl_cipher), system_charset_info); if (thd->lex.x509_issuer) table->field[19]->store(thd->lex.x509_issuer, - strlen(thd->lex.x509_issuer)); + strlen(thd->lex.x509_issuer), system_charset_info); if (thd->lex.x509_subject) table->field[20]->store(thd->lex.x509_subject, - strlen(thd->lex.x509_subject)); + strlen(thd->lex.x509_subject), system_charset_info); break; default: - table->field[17]->store("NONE",4); + table->field[17]->store("NONE",4, system_charset_info); } } #endif /* HAVE_OPENSSL */ @@ -1315,9 +1315,9 @@ static int replace_db_table(TABLE *table, const char *db, DBUG_RETURN(-1); } - table->field[0]->store(combo.host.str,combo.host.length); - table->field[1]->store(db,(uint) strlen(db)); - table->field[2]->store(combo.user.str,combo.user.length); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); table->file->index_init(0); if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr,0, HA_READ_KEY_EXACT)) @@ -1330,9 +1330,9 @@ static int replace_db_table(TABLE *table, const char *db, } old_row_exists = 0; restore_record(table,2); // cp empty row from record[2] - table->field[0]->store(combo.host.str,combo.host.length); - table->field[1]->store(db,(uint) strlen(db)); - table->field[2]->store(combo.user.str,combo.user.length); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); } else { @@ -1344,7 +1344,7 @@ static int replace_db_table(TABLE *table, const char *db, for (i = 3, j = 1; i < table->fields; i++, j <<= 1) { if (j & store_rights) // do it if priv is chosen - table->field [i]->store(&what,1); // set requested privileges + table->field [i]->store(&what,1, system_charset_info);// set requested privileges } rights=get_access(table,3); rights=fix_rights_for_db(rights); @@ -1466,16 +1466,16 @@ public: if (cols) { int key_len; - col_privs->field[0]->store(host,(uint) strlen(host)); - col_privs->field[1]->store(db,(uint) strlen(db)); - col_privs->field[2]->store(user,(uint) strlen(user)); - col_privs->field[3]->store(tname,(uint) strlen(tname)); + col_privs->field[0]->store(host,(uint) strlen(host), system_charset_info); + col_privs->field[1]->store(db,(uint) strlen(db), system_charset_info); + col_privs->field[2]->store(user,(uint) strlen(user), system_charset_info); + col_privs->field[3]->store(tname,(uint) strlen(tname), system_charset_info); key_len=(col_privs->field[0]->pack_length()+ col_privs->field[1]->pack_length()+ col_privs->field[2]->pack_length()+ col_privs->field[3]->pack_length()); key_copy(key,col_privs,0,key_len); - col_privs->field[4]->store("",0); + col_privs->field[4]->store("",0, system_charset_info); col_privs->file->index_init(0); if (col_privs->file->index_read(col_privs->record[0], (byte*) col_privs->field[0]->ptr, @@ -1574,10 +1574,10 @@ static int replace_column_table(GRANT_TABLE *g_t, byte key[MAX_KEY_LENGTH]; DBUG_ENTER("replace_column_table"); - table->field[0]->store(combo.host.str,combo.host.length); - table->field[1]->store(db,(uint) strlen(db)); - table->field[2]->store(combo.user.str,combo.user.length); - table->field[3]->store(table_name,(uint) strlen(table_name)); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); + table->field[3]->store(table_name,(uint) strlen(table_name), system_charset_info); key_length=(table->field[0]->pack_length()+ table->field[1]->pack_length()+ table->field[2]->pack_length()+ table->field[3]->pack_length()); key_copy(key,table,0,key_length); @@ -1594,7 +1594,7 @@ static int replace_column_table(GRANT_TABLE *g_t, uint privileges = xx->rights; bool old_row_exists=0; key_restore(table,key,0,key_length); - table->field[4]->store(xx->column.ptr(),xx->column.length()); + table->field[4]->store(xx->column.ptr(),xx->column.length(),system_charset_info); if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr, 0, HA_READ_KEY_EXACT)) @@ -1608,9 +1608,9 @@ static int replace_column_table(GRANT_TABLE *g_t, continue; /* purecov: inspected */ } old_row_exists = 0; - restore_record(table,2); // Get empty record + restore_record(table,2); // Get empty record key_restore(table,key,0,key_length); - table->field[4]->store(xx->column.ptr(),xx->column.length()); + table->field[4]->store(xx->column.ptr(),xx->column.length(), system_charset_info); } else { @@ -1682,7 +1682,7 @@ static int replace_column_table(GRANT_TABLE *g_t, { GRANT_COLUMN *grant_column = NULL; char colum_name_buf[HOSTNAME_LENGTH+1]; - String column_name(colum_name_buf,sizeof(colum_name_buf)); + String column_name(colum_name_buf,sizeof(colum_name_buf),system_charset_info); privileges&= ~rights; table->field[6]->store((longlong) @@ -1749,10 +1749,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } restore_record(table,2); // Get empty record - table->field[0]->store(combo.host.str,combo.host.length); - table->field[1]->store(db,(uint) strlen(db)); - table->field[2]->store(combo.user.str,combo.user.length); - table->field[3]->store(table_name,(uint) strlen(table_name)); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); + table->field[3]->store(table_name,(uint) strlen(table_name), system_charset_info); store_record(table,1); // store at pos 1 if (table->file->index_read_idx(table->record[0],0, @@ -1797,7 +1797,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } } - table->field[4]->store(grantor,(uint) strlen(grantor)); + table->field[4]->store(grantor,(uint) strlen(grantor), system_charset_info); table->field[6]->store((longlong) store_table_rights); table->field[7]->store((longlong) store_col_rights); rights=fix_rights_for_table(store_table_rights); @@ -2612,7 +2612,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) DBUG_RETURN(-1); } - Item_string *field=new Item_string("",0); + Item_string *field=new Item_string("",0,system_charset_info); List field_list; field->name=buff; field->max_length=1024; @@ -2628,7 +2628,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) if (acl_user->access || acl_user->password) { want_access=acl_user->access; - String global(buff,sizeof(buff)); + String global(buff,sizeof(buff),system_charset_info); global.length(0); global.append("GRANT ",6); @@ -2734,7 +2734,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) want_access=acl_db->access; if (want_access) { - String db(buff,sizeof(buff)); + String db(buff,sizeof(buff),system_charset_info); db.length(0); db.append("GRANT ",6); @@ -2793,7 +2793,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) want_access=grant_table->privs; if ((want_access | grant_table->cols) != 0) { - String global(buff,sizeof(buff)); + String global(buff,sizeof(buff),system_charset_info); global.length(0); global.append("GRANT ",6); diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 8f086863a4e..cc3406d0f54 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -270,7 +270,7 @@ void free_string(String *s) void field_str::add() { char buff[MAX_FIELD_WIDTH], *ptr; - String s(buff, sizeof(buff)), *res; + String s(buff, sizeof(buff),default_charset_info), *res; ulong length; if (!(res = item->val_str(&s))) @@ -573,8 +573,9 @@ bool analyse::end_of_records() { field_info **f = f_info; char buff[MAX_FIELD_WIDTH]; - String *res, s_min(buff, sizeof(buff)), s_max(buff, sizeof(buff)), - ans(buff, sizeof(buff)); + String *res, s_min(buff, sizeof(buff),default_charset_info), + s_max(buff, sizeof(buff),default_charset_info), + ans(buff, sizeof(buff),default_charset_info); for (; f != f_end; f++) { @@ -620,14 +621,14 @@ bool analyse::end_of_records() ((*f)->tree.elements_in_tree * 3 - 1 + 6)))) { char tmp[331]; //331, because one double prec. num. can be this long - String tmp_str(tmp, sizeof(tmp)); + String tmp_str(tmp, sizeof(tmp),default_charset_info); TREE_INFO tree_info; tree_info.str = &tmp_str; tree_info.found = 0; tree_info.item = (*f)->item; - tmp_str.set("ENUM(", 5); + tmp_str.set("ENUM(", 5,default_charset_info); tree_walk(&(*f)->tree, (*f)->collect_enum(), (char*) &tree_info, left_root_right); tmp_str.append(')'); @@ -891,7 +892,7 @@ int collect_real(double *element, element_count count __attribute__((unused)), TREE_INFO *info) { char buff[MAX_FIELD_WIDTH]; - String s(buff, sizeof(buff)); + String s(buff, sizeof(buff),default_charset_info); if (info->found) info->str->append(','); @@ -910,7 +911,7 @@ int collect_longlong(longlong *element, TREE_INFO *info) { char buff[MAX_FIELD_WIDTH]; - String s(buff, sizeof(buff)); + String s(buff, sizeof(buff),default_charset_info); if (info->found) info->str->append(','); @@ -929,7 +930,7 @@ int collect_ulonglong(ulonglong *element, TREE_INFO *info) { char buff[MAX_FIELD_WIDTH]; - String s(buff, sizeof(buff)); + String s(buff, sizeof(buff),default_charset_info); if (info->found) info->str->append(','); diff --git a/sql/sql_analyse.h b/sql/sql_analyse.h index 1c60d0c150f..3e8ddd67023 100644 --- a/sql/sql_analyse.h +++ b/sql/sql_analyse.h @@ -110,8 +110,9 @@ class field_str :public field_info EV_NUM_INFO ev_num_info; public: - field_str(Item* a, analyse* b) :field_info(a,b), min_arg(""), - max_arg(""), sum(0), + field_str(Item* a, analyse* b) :field_info(a,b), + min_arg("",default_charset_info), + max_arg("",default_charset_info), sum(0), must_be_blob(0), was_zero_fill(0), was_maybe_zerofill(0), can_be_still_num(1) { init_tree(&tree, 0, 0, sizeof(String), a->binary ? diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 031c83a2aeb..5e3bf90c4a5 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -197,7 +197,8 @@ send_fields(THD *thd,List &list,uint flag) char buff[80]; CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->convert_set; - String tmp((char*) buff,sizeof(buff)),*res,*packet= &thd->packet; + String tmp((char*) buff,sizeof(buff),default_charset_info); + String *res,*packet= &thd->packet; if (thd->fatal_error) // We have got an error goto err; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 95c10112a9b..751e4d25d41 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -363,8 +363,10 @@ select_result::select_result() thd=current_thd; } -static String default_line_term("\n"),default_escaped("\\"), - default_field_term("\t"); +static String + default_line_term("\n",default_charset_info), + default_escaped("\\",default_charset_info), + default_field_term("\t",default_charset_info); sql_exchange::sql_exchange(char *name,bool flag) :file_name(name), opt_enclosed(0), dumpfile(flag), skip_lines(0) @@ -508,7 +510,7 @@ bool select_export::send_data(List &items) DBUG_ENTER("send_data"); char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH]; bool space_inited=0; - String tmp(buff,sizeof(buff)),*res; + String tmp(buff,sizeof(buff),default_charset_info),*res; tmp.length(0); if (unit->offset_limit_cnt) @@ -717,7 +719,7 @@ bool select_dump::send_data(List &items) { List_iterator_fast li(items); char buff[MAX_FIELD_WIDTH]; - String tmp(buff,sizeof(buff)),*res; + String tmp(buff,sizeof(buff),default_charset_info),*res; tmp.length(0); Item *item; DBUG_ENTER("send_data"); diff --git a/sql/sql_class.h b/sql/sql_class.h index 10d6bf84b22..16c67375d99 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -221,9 +221,6 @@ public: List columns; const char *Name; - Key(enum Keytype type_par,const char *name_arg,List &cols) - :type(type_par), columns(cols),Name(name_arg) {} - Key(enum Keytype type_par, enum ha_key_alg alg_par, const char *name_arg, List &cols) :type(type_par), algorithm(alg_par), columns(cols), Name(name_arg) {} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 32a98615390..22e682fef38 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -317,6 +317,7 @@ typedef struct st_lex { bool drop_primary,drop_if_exists,local_file; bool in_comment,ignore_space,verbose,simple_alter, option_type, derived_tables; uint slave_thd_opt; + CHARSET_INFO *charset; } LEX; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 419e3fccabd..faeeaf2812e 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -358,7 +358,7 @@ read_fixed_length(THD *thd,COPY_INFO &info,TABLE *table,List &fields, field->field_length) length=field->field_length; save_chr=pos[length]; pos[length]='\0'; // Safeguard aganst malloc - field->store((char*) pos,length); + field->store((char*) pos,length,default_charset_info); pos[length]=save_chr; if ((pos+=length) > read_info.row_end) pos= read_info.row_end; /* Fills rest with space */ @@ -427,7 +427,7 @@ read_sep_field(THD *thd,COPY_INFO &info,TABLE *table, } field->set_notnull(); read_info.row_end[0]=0; // Safe to change end marker - field->store((char*) read_info.row_start,length); + field->store((char*) read_info.row_start,length,default_charset_info); } if (read_info.error) break; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e9a8ef2f449..8abd7a15bd4 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2794,14 +2794,14 @@ bool add_field_to_list(char *field_name, enum_field_types type, if (type_modifier & PRI_KEY_FLAG) { lex->col_list.push_back(new key_part_spec(field_name,0)); - lex->key_list.push_back(new Key(Key::PRIMARY,NullS, + lex->key_list.push_back(new Key(Key::PRIMARY, HA_KEY_ALG_UNDEF, NullS, lex->col_list)); lex->col_list.empty(); } if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG)) { lex->col_list.push_back(new key_part_spec(field_name,0)); - lex->key_list.push_back(new Key(Key::UNIQUE,NullS, + lex->key_list.push_back(new Key(Key::UNIQUE, HA_KEY_ALG_UNDEF, NullS, lex->col_list)); lex->col_list.empty(); } @@ -2865,6 +2865,7 @@ bool add_field_to_list(char *field_name, enum_field_types type, case FIELD_TYPE_STRING: case FIELD_TYPE_VAR_STRING: case FIELD_TYPE_NULL: + case FIELD_TYPE_GEOMETRY: break; case FIELD_TYPE_DECIMAL: if (!length) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 115e5a058ed..60b092652aa 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3494,14 +3494,14 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case Item_sum::AVG_FUNC: /* Place for sum & count */ if (group) return new Field_string(sizeof(double)+sizeof(longlong), - maybe_null, item->name,table,1); + maybe_null, item->name,table,1,default_charset_info); else return new Field_double(item_sum->max_length,maybe_null, item->name, table, item_sum->decimals); case Item_sum::STD_FUNC: /* Place for sum & count */ if (group) return new Field_string(sizeof(double)*2+sizeof(longlong), - maybe_null, item->name,table,1); + maybe_null, item->name,table,1,default_charset_info); else return new Field_double(item_sum->max_length, maybe_null, item->name,table,item_sum->decimals); @@ -3520,7 +3520,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, return new Field_blob(item_sum->max_length,maybe_null, item->name,table,item->binary); return new Field_string(item_sum->max_length,maybe_null, - item->name,table,item->binary); + item->name,table,item->binary,default_charset_info); } } thd->fatal_error=1; @@ -3574,7 +3574,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, item->name,table,item->binary); else new_field= new Field_string(item->max_length,maybe_null, - item->name,table,item->binary); + item->name,table,item->binary,default_charset_info); break; } if (copy_func) @@ -3994,7 +3994,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, (uchar*) 0, (uint) 0, Field::NONE, - NullS, table, (bool) 1); + NullS, table, (bool) 1, default_charset_info); key_part_info->key_type=FIELDFLAG_BINARY; key_part_info->type= HA_KEYTYPE_BINARY; key_part_info++; @@ -6909,7 +6909,7 @@ change_to_use_tmp_fields(List &items) if (_db_on_ && !item_field->name) { char buff[256]; - String str(buff,sizeof(buff)); + String str(buff,sizeof(buff),default_charset_info); str.length(0); item->print(&str); item_field->name=sql_strmake(str.ptr(),str.length()); @@ -7140,7 +7140,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, item_list.push_back(new Item_empty_string("",0)); item_list.push_back(new Item_empty_string("",0)); item_list.push_back(new Item_empty_string("",0)); - item_list.push_back(new Item_string(message,strlen(message))); + item_list.push_back(new Item_string(message,strlen(message),default_charset_info)); if (result->send_data(item_list)) result->send_error(0,NullS); } @@ -7153,13 +7153,13 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, TABLE *table=tab->table; char buff[512],*buff_ptr=buff; char buff1[512], buff2[512], bufff[512]; - String tmp1(buff1,sizeof(buff1)); - String tmp2(buff2,sizeof(buff2)); + String tmp1(buff1,sizeof(buff1),default_charset_info); + String tmp2(buff2,sizeof(buff2),default_charset_info); item_list.empty(); if (tab->type == JT_ALL && tab->select && tab->select->quick) tab->type= JT_RANGE; - item_list.push_back(new Item_string(table->table_name,strlen(table->table_name))); - item_list.push_back(new Item_string(join_type_str[tab->type],strlen(join_type_str[tab->type]))); + item_list.push_back(new Item_string(table->table_name,strlen(table->table_name),default_charset_info)); + item_list.push_back(new Item_string(join_type_str[tab->type],strlen(join_type_str[tab->type]),default_charset_info)); tmp1.length(0); tmp2.length(0); key_map bits; uint j; @@ -7173,12 +7173,12 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, } } if (tmp1.length()) - item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length())); + item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length(),default_charset_info)); else item_list.push_back(new Item_null()); if (tab->ref.key_parts) { - item_list.push_back(new Item_string(table->key_info[tab->ref.key].name,strlen(table->key_info[tab->ref.key].name))); + item_list.push_back(new Item_string(table->key_info[tab->ref.key].name,strlen(table->key_info[tab->ref.key].name),default_charset_info)); item_list.push_back(new Item_int((int) tab->ref.key_length)); for (store_key **ref=tab->ref.key_copy ; *ref ; ref++) { @@ -7186,17 +7186,17 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, tmp2.append(','); tmp2.append((*ref)->name()); } - item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length())); + item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),default_charset_info)); } else if (tab->type == JT_NEXT) { - item_list.push_back(new Item_string(table->key_info[tab->index].name,strlen(table->key_info[tab->index].name))); + item_list.push_back(new Item_string(table->key_info[tab->index].name,strlen(table->key_info[tab->index].name),default_charset_info)); item_list.push_back(new Item_int((int) table->key_info[tab->index].key_length)); item_list.push_back(new Item_null()); } else if (tab->select && tab->select->quick) { - item_list.push_back(new Item_string(table->key_info[tab->select->quick->index].name,strlen(table->key_info[tab->select->quick->index].name))); + item_list.push_back(new Item_string(table->key_info[tab->select->quick->index].name,strlen(table->key_info[tab->select->quick->index].name),default_charset_info)); item_list.push_back(new Item_int((int) tab->select->quick->max_used_key_length)); item_list.push_back(new Item_null()); } @@ -7207,14 +7207,14 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, item_list.push_back(new Item_null()); } sprintf(bufff,"%.0f",join->best_positions[i].records_read); - item_list.push_back(new Item_string(bufff,strlen(bufff))); + item_list.push_back(new Item_string(bufff,strlen(bufff),default_charset_info)); my_bool key_read=table->key_read; if (tab->type == JT_NEXT && ((table->used_keys & ((key_map) 1 << tab->index)))) key_read=1; if (tab->info) - item_list.push_back(new Item_string(tab->info,strlen(tab->info))); + item_list.push_back(new Item_string(tab->info,strlen(tab->info),default_charset_info)); else if (tab->select) { if (tab->use_quick == 2) @@ -7268,7 +7268,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, } buff_ptr=strmov(buff_ptr,"Distinct"); } - item_list.push_back(new Item_string(buff,(uint) (buff_ptr - buff))); + item_list.push_back(new Item_string(buff,(uint) (buff_ptr - buff),default_charset_info)); // For next iteration used_tables|=table->map; if (result->send_data(item_list)) diff --git a/sql/sql_select.h b/sql/sql_select.h index 84d4207bdb5..3062747a08f 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -286,7 +286,7 @@ class store_key :public Sql_alloc if (field_arg->type() == FIELD_TYPE_BLOB) to_field=new Field_varstring(ptr, length, (uchar*) null, 1, Field::NONE, field_arg->field_name, - field_arg->table, field_arg->binary()); + field_arg->table, field_arg->binary(), default_charset_info); else { to_field=field_arg->new_field(&thd->mem_root,field_arg->table); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 95705c19d68..849a803a622 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -57,7 +57,7 @@ extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd; int mysqld_show_dbs(THD *thd,const char *wild) { - Item_string *field=new Item_string("",0); + Item_string *field=new Item_string("",0,default_charset_info); List field_list; char *end; List files; @@ -138,7 +138,7 @@ int mysqld_show_open_tables(THD *thd,const char *wild) int mysqld_show_tables(THD *thd,const char *db,const char *wild) { - Item_string *field=new Item_string("",0); + Item_string *field=new Item_string("",0,default_charset_info); List field_list; char path[FN_LEN],*end; List files; @@ -262,7 +262,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) (void) sprintf(path,"%s/%s",mysql_data_home,db); (void) unpack_dirname(path,path); - +//,default_charset_info field_list.push_back(item=new Item_empty_string("Name",NAME_LEN)); item->maybe_null=1; field_list.push_back(item=new Item_empty_string("Type",10)); @@ -483,7 +483,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, { byte *pos; uint flags=field->flags; - String type(tmp,sizeof(tmp)); + String type(tmp,sizeof(tmp),default_charset_info); uint col_access; bool null_default_value=0; @@ -506,7 +506,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, null_default_value=1; if (!null_default_value && !field->is_null()) { // Not null by default - type.set(tmp,sizeof(tmp)); + type.set(tmp,sizeof(tmp),default_charset_info); field->val_str(&type,&type); net_store_data(packet,convert,type.ptr(),type.length()); } @@ -810,7 +810,7 @@ store_create_info(THD *thd, TABLE *table, String *packet) List field_list; char tmp[MAX_FIELD_WIDTH]; - String type(tmp, sizeof(tmp)); + String type(tmp, sizeof(tmp),default_charset_info); if (table->tmp_table) packet->append("CREATE TEMPORARY TABLE ", 23); else @@ -830,7 +830,7 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append(' '); // check for surprises from the previous call to Field::sql_type() if (type.ptr() != tmp) - type.set(tmp, sizeof(tmp)); + type.set(tmp, sizeof(tmp),default_charset_info); field->sql_type(type); packet->append(type.ptr(),type.length()); @@ -846,7 +846,7 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append(" default ", 9); if (!field->is_null()) { // Not null by default - type.set(tmp,sizeof(tmp)); + type.set(tmp,sizeof(tmp),default_charset_info); field->val_str(&type,&type); packet->append('\''); if (type.length()) @@ -1143,7 +1143,7 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables) { uint i; char buff[8192]; - String packet2(buff,sizeof(buff)); + String packet2(buff,sizeof(buff),default_charset_info); List field_list; CONVERT *convert=thd->convert_set; DBUG_ENTER("mysqld_show"); diff --git a/sql/sql_string.cc b/sql/sql_string.cc index cf9e9f62507..b8e2ba7b536 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -123,7 +123,7 @@ bool String::set(double num,uint decimals) char *pos,*to; VOID(fconvert(num,(int) decimals,&decpt,&sign,buff+1)); - if (!isdigit(buff[1])) + if (!my_isdigit(system_charset_info, buff[1])) { // Nan or Inf pos=buff+1; if (sign) @@ -203,6 +203,7 @@ bool String::copy(const String &str) str_length=str.str_length; bmove(Ptr,str.Ptr,str_length); // May be overlapping Ptr[str_length]=0; + str_charset=str.str_charset; return FALSE; } @@ -489,7 +490,7 @@ void String::qs_append(double d) void String::qs_append(double *d) { double ld; - float8get(ld, d); + float8get(ld, (char*) d); qs_append(ld); } @@ -586,6 +587,7 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length) return from; // Actually an error if ((to->str_length=min(from->str_length,from_length))) memcpy(to->Ptr,from->Ptr,to->str_length); + to->str_charset=from->str_charset; return to; } diff --git a/sql/sql_string.h b/sql/sql_string.h index 9bf13b93628..5e5c9001590 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -46,22 +46,22 @@ public: String(uint32 length_arg) { alloced=0; Alloced_length=0; (void) real_alloc(length_arg); - str_charset=default_charset_info; + str_charset=default_charset_info; } - String(const char *str) + String(const char *str, CHARSET_INFO *cs) { Ptr=(char*) str; str_length=(uint) strlen(str); Alloced_length=0; alloced=0; - str_charset=default_charset_info; + str_charset=cs; } - String(const char *str,uint32 len) + String(const char *str,uint32 len, CHARSET_INFO *cs) { Ptr=(char*) str; str_length=len; Alloced_length=0; alloced=0; - str_charset=default_charset_info; + str_charset=cs; } - String(char *str,uint32 len) + String(char *str,uint32 len, CHARSET_INFO *cs) { Ptr=(char*) str; Alloced_length=str_length=len; alloced=0; - str_charset=default_charset_info; + str_charset=cs; } String(const String &str) { @@ -103,23 +103,27 @@ public: Alloced_length=str.Alloced_length-offset; else Alloced_length=0; + str_charset=str.str_charset; } - inline void set(char *str,uint32 arg_length) + inline void set(char *str,uint32 arg_length, CHARSET_INFO *cs) { free(); Ptr=(char*) str; str_length=Alloced_length=arg_length ; alloced=0; + str_charset=cs; } - inline void set(const char *str,uint32 arg_length) + inline void set(const char *str,uint32 arg_length, CHARSET_INFO *cs) { free(); Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0; + str_charset=cs; } - inline void set_quick(char *str,uint32 arg_length) + inline void set_quick(char *str,uint32 arg_length, CHARSET_INFO *cs) { if (!alloced) { Ptr=(char*) str; str_length=Alloced_length=arg_length; } + str_charset=cs; } bool set(longlong num); /* bool set(long num); */ diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 782caa8fa51..bdcb325774b 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -156,7 +156,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, { if (wrong_tables.length()) wrong_tables.append(','); - wrong_tables.append(String(table->real_name)); + wrong_tables.append(String(table->real_name,default_charset_info)); } } if (some_tables_deleted) @@ -476,23 +476,22 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, checking for proper key parts number: */ -printf("key_info->flags=%d key_info->algorithm=%d\n", - key_info->flags,key_info->algorithm); - - if(key_info->flags == HA_SPATIAL){ - if(key_info->key_parts!=1){ + if (key_info->flags == HA_SPATIAL) + { + if (key_info->key_parts != 1) + { my_printf_error(ER_WRONG_ARGUMENTS, ER(ER_WRONG_ARGUMENTS),MYF(0),"SPATIAL INDEX"); DBUG_RETURN(-1); } - }else + } + else if (key_info->algorithm == HA_KEY_ALG_RTREE) { - if(key_info->algorithm == HA_KEY_ALG_RTREE){ - if((key_info->key_parts&1)==1){ - my_printf_error(ER_WRONG_ARGUMENTS, - ER(ER_WRONG_ARGUMENTS),MYF(0),"RTREE INDEX"); - DBUG_RETURN(-1); - } + if ((key_info->key_parts & 1) == 1) + { + my_printf_error(ER_WRONG_ARGUMENTS, + ER(ER_WRONG_ARGUMENTS),MYF(0),"RTREE INDEX"); + DBUG_RETURN(-1); } } diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 43c24da85a2..0bc1feed839 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -33,7 +33,7 @@ print_where(COND *cond,const char *info) if (cond) { char buff[256]; - String str(buff,(uint32) sizeof(buff)); + String str(buff,(uint32) sizeof(buff), default_charset_info); str.length(0); cond->print(&str); str.append('\0'); @@ -99,7 +99,8 @@ void print_cached_tables(void) void TEST_filesort(SORT_FIELD *sortorder,uint s_length, ha_rows special) { char buff[256],buff2[256]; - String str(buff,sizeof(buff)),out(buff2,sizeof(buff2)); + String str(buff,sizeof(buff),default_charset_info); + String out(buff2,sizeof(buff2),default_charset_info); const char *sep; DBUG_ENTER("TEST_filesort"); diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index f44fa3b7321..225c0ea26a4 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -412,9 +412,9 @@ int mysql_create_function(THD *thd,udf_func *udf) goto err; restore_record(table,2); // Get default values for fields - table->field[0]->store(u_d->name, u_d->name_length); + table->field[0]->store(u_d->name, u_d->name_length, default_charset_info); table->field[1]->store((longlong) u_d->returns); - table->field[2]->store(u_d->dl,(uint) strlen(u_d->dl)); + table->field[2]->store(u_d->dl,(uint) strlen(u_d->dl), default_charset_info); if (table->fields >= 4) // If not old func format table->field[3]->store((longlong) u_d->type); error = table->file->write_row(table->record[0]); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 7e3d10ee202..1bb0537a731 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -468,7 +468,8 @@ multi_update::prepare(List &values, SELECT_LEX_UNIT *u) if (counter) { Field_string offset(table_ref->table->file->ref_length, false, - "offset", table_ref->table, true); + "offset", table_ref->table, true, + default_charset_info); temp_fields->push_front(new Item_field(((Field *)&offset))); // Here I make tmp tables int cnt=counter-1; @@ -621,7 +622,8 @@ bool multi_update::send_data(List &values) { // Here we insert into each temporary table values_by_table.push_front(new Item_string((char*) table->file->ref, - table->file->ref_length)); + table->file->ref_length, + system_charset_info)); fill_record(tmp_tables[secure_counter]->field,values_by_table); error= write_record(tmp_tables[secure_counter], &(infos[secure_counter])); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8d981f05a1f..c5addfee15e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -777,7 +777,7 @@ create: lex->key_list.push_back(new Key($2,$5,$4.str,lex->col_list)); lex->col_list.empty(); } - | CREATE DATABASE opt_if_not_exists ident + | CREATE DATABASE opt_if_not_exists ident default_charset { LEX *lex=Lex; lex->sql_command=SQLCOM_CREATE_DB; @@ -1095,8 +1095,31 @@ attribute: | UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; } opt_binary: - /* empty */ {} - | BINARY { Lex->type|=BINARY_FLAG; } + /* empty */ { Lex->charset=default_charset_info; } + | BINARY { Lex->type|=BINARY_FLAG; Lex->charset=default_charset_info; } + | CHAR_SYM SET ident + { + CHARSET_INFO *cs=get_charset_by_name($3.str,MYF(MY_WME)); + if (!cs) + { + net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$3); + YYABORT; + } + Lex->charset=cs; + } + +default_charset: + /* empty */ { Lex->charset-default_charset_info; } + | DEFAULT CHAR_SYM SET ident + { + CHARSET_INFO *cs=get_charset_by_name($4.str,MYF(MY_WME)); + if (!cs) + { + net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$4); + YYABORT; + } + Lex->charset=cs; + } references: REFERENCES table_ident opt_on_delete {} @@ -1912,7 +1935,7 @@ simple_expr: | SUBSTRING_INDEX '(' expr ',' expr ',' expr ')' { $$= new Item_func_substr_index($3,$5,$7); } | TRIM '(' expr ')' - { $$= new Item_func_trim($3,new Item_string(" ",1)); } + { $$= new Item_func_trim($3,new Item_string(" ",1,default_charset_info)); } | TRIM '(' LEADING opt_pad FROM expr ')' { $$= new Item_func_ltrim($6,$4); } | TRIM '(' TRAILING opt_pad FROM expr ')' @@ -2097,7 +2120,7 @@ when_list2: } opt_pad: - /* empty */ { $$=new Item_string(" ",1); } + /* empty */ { $$=new Item_string(" ",1,default_charset_info); } | expr { $$=$1; } join_table_list: @@ -2211,11 +2234,11 @@ key_usage_list: key_usage_list2: key_usage_list2 ',' ident - { Select->interval_list.push_back(new String((const char*) $3.str,$3.length)); } + { Select->interval_list.push_back(new String((const char*) $3.str,$3.length,default_charset_info)); } | ident - { Select->interval_list.push_back(new String((const char*) $1.str,$1.length)); } + { Select->interval_list.push_back(new String((const char*) $1.str,$1.length,default_charset_info)); } | PRIMARY_SYM - { Select->interval_list.push_back(new String("PRIMARY",7)); } + { Select->interval_list.push_back(new String("PRIMARY",7,default_charset_info)); } using_list: ident @@ -2822,7 +2845,7 @@ describe_command: opt_describe_column: /* empty */ {} | text_string { Lex->wild= $1; } - | ident { Lex->wild= new String((const char*) $1.str,$1.length); } + | ident { Lex->wild= new String((const char*) $1.str,$1.length,default_charset_info); } /* flush things */ @@ -2990,15 +3013,15 @@ opt_ignore_lines: /* Common definitions */ text_literal: - TEXT_STRING { $$ = new Item_string($1.str,$1.length); } + TEXT_STRING { $$ = new Item_string($1.str,$1.length,default_charset_info); } | text_literal TEXT_STRING { ((Item_string*) $1)->append($2.str,$2.length); } text_string: - TEXT_STRING { $$= new String($1.str,$1.length); } + TEXT_STRING { $$= new String($1.str,$1.length,default_charset_info); } | HEX_NUM { - Item *tmp = new Item_varbinary($1.str,$1.length); + Item *tmp = new Item_varbinary($1.str,$1.length,default_charset_info); $$= tmp ? tmp->val_str((String*) 0) : (String*) 0; } @@ -3011,7 +3034,7 @@ literal: | FLOAT_NUM { $$ = new Item_float($1.str, $1.length); } | NULL_SYM { $$ = new Item_null(); Lex->next_state=STATE_OPERATOR_OR_IDENT;} - | HEX_NUM { $$ = new Item_varbinary($1.str,$1.length);} + | HEX_NUM { $$ = new Item_varbinary($1.str,$1.length,default_charset_info);} | DATE_SYM text_literal { $$ = $2; } | TIME_SYM text_literal { $$ = $2; } | TIMESTAMP text_literal { $$ = $2; } @@ -3738,7 +3761,7 @@ column_list: column_list_id: ident { - String *new_str = new String((const char*) $1.str,$1.length); + String *new_str = new String((const char*) $1.str,$1.length,default_charset_info); List_iterator iter(Lex->columns); class LEX_COLUMN *point; LEX *lex=Lex; diff --git a/sql/table.cc b/sql/table.cc index 3c217ced03c..05a5c5e6bd2 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -199,7 +199,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, /* Read key types */ keyinfo=outparam->key_info; for (i=0 ; i < keys ; i++, keyinfo++) + { keyinfo->algorithm= (enum ha_key_alg) *(strpos++); + /* Temporary fix to get spatial index to work */ + if (keyinfo->algorithm == HA_KEY_ALG_RTREE) + keyinfo->flags|= HA_SPATIAL; + } } else { @@ -341,6 +346,15 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, (hash_get_key) get_field_name,0, HASH_CASE_INSENSITIVE); +// BAR: dirty hack while waiting for new FRM +// BAR: take a charset information from table name +{ + const char* csname=strstr(alias,"_cs_"); + if(!csname || + !(outparam->table_charset=get_charset_by_name(csname+4,MYF(MY_WME)))) + outparam->table_charset=default_charset_info; +} + for (i=0 ; i < outparam->fields; i++, strpos+= 11, field_ptr++) { uint pack_flag= uint2korr(strpos+6); @@ -357,6 +371,18 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, (TYPELIB*) 0), outparam->fieldnames.type_names[i], outparam); + if (!reg_field->binary()) + { + // BAR: dirty hack while waiting for new FRM + // BAR: take a charset information from field name + + Field_str* str_field=(Field_str*)reg_field; + const char* csname=strstr(str_field->field_name,"_cs_"); + CHARSET_INFO *fcs; + if (!csname || (!(fcs=get_charset_by_name(csname+4,MYF(MY_WME))))) + fcs=outparam->table_charset; + str_field->set_charset(fcs); + } if (!(reg_field->flags & NOT_NULL_FLAG)) { if ((null_bit<<=1) == 256) @@ -1051,7 +1077,7 @@ char *get_field(MEM_ROOT *mem, TABLE *table, uint fieldnr) { Field *field=table->field[fieldnr]; char buff[MAX_FIELD_WIDTH]; - String str(buff,sizeof(buff)); + String str(buff,sizeof(buff),table->table_charset); field->val_str(&str,&str); uint length=str.length(); if (!length) diff --git a/sql/table.h b/sql/table.h index 1c65c2a7ce2..b89701bfc8e 100644 --- a/sql/table.h +++ b/sql/table.h @@ -104,6 +104,7 @@ struct st_table { *rowid_field; Field_timestamp *timestamp_field; my_string comment; /* Comment about table */ + CHARSET_INFO *table_charset; /* Default charset of string fields */ REGINFO reginfo; /* field connections */ MEM_ROOT mem_root; GRANT_INFO grant; diff --git a/sql/unireg.cc b/sql/unireg.cc index 1c35f7a6a08..16f51658313 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -484,7 +484,7 @@ static bool pack_fields(File file,List &create_fields) /* Write intervals */ if (int_count) { - String tmp((char*) buff,sizeof(buff)); + String tmp((char*) buff,sizeof(buff), default_charset_info); tmp.length(0); it.rewind(); int_count=0; @@ -561,6 +561,7 @@ static bool make_empty_rec(File file,enum db_type table_type, field->interval, field->field_name, &table); + if (!(field->flags & NOT_NULL_FLAG)) null_count++; @@ -581,9 +582,9 @@ static bool make_empty_rec(File file,enum db_type table_type, regfield->store((longlong) 1); } else if (type == Field::YES) // Old unireg type - regfield->store(ER(ER_YES),(uint) strlen(ER(ER_YES))); + regfield->store(ER(ER_YES),(uint) strlen(ER(ER_YES)),default_charset_info); else if (type == Field::NO) // Old unireg type - regfield->store(ER(ER_NO), (uint) strlen(ER(ER_NO))); + regfield->store(ER(ER_NO), (uint) strlen(ER(ER_NO)),default_charset_info); else regfield->reset(); delete regfield;