diff options
-rw-r--r-- | mysql-test/r/merge.result | 6 | ||||
-rw-r--r-- | mysql-test/t/merge.test | 11 | ||||
-rw-r--r-- | mysys/queues.c | 48 | ||||
-rw-r--r-- | storage/myisammrg/myrg_open.c | 7 | ||||
-rw-r--r-- | storage/myisammrg/myrg_queue.c | 2 |
5 files changed, 43 insertions, 31 deletions
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 6e2da3126cd..b08b985983d 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -771,6 +771,12 @@ Table Op Msg_type Msg_text test.t1 check status OK test.t2 check status OK drop table t1, t2, t3; +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(2),(1); +CREATE TABLE t2(a INT, KEY(a)) ENGINE=MERGE UNION=(t1); +SELECT * FROM t2 WHERE a=2; +ERROR HY000: Got error 124 from storage engine +DROP TABLE t1, t2; CREATE TABLE t1(a INT) ENGINE=MEMORY; CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t1); SELECT * FROM t2; diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index d3a2928608d..4006fa27fe3 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -382,6 +382,17 @@ check table t1, t2; drop table t1, t2, t3; # +# BUG#21617 - crash when selecting from merge table with inconsistent +# indexes +# +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(2),(1); +CREATE TABLE t2(a INT, KEY(a)) ENGINE=MERGE UNION=(t1); +--error 1030 +SELECT * FROM t2 WHERE a=2; +DROP TABLE t1, t2; + +# # BUG#10974 - No error message if merge table based on union of innodb, # memory # diff --git a/mysys/queues.c b/mysys/queues.c index 8e572a0f195..3900ecad3f2 100644 --- a/mysys/queues.c +++ b/mysys/queues.c @@ -208,28 +208,22 @@ void delete_queue(QUEUE *queue) void queue_insert(register QUEUE *queue, byte *element) { - reg2 uint idx,next; + reg2 uint idx, next; int cmp; - -#ifndef DBUG_OFF - if (queue->elements < queue->max_elements) -#endif + DBUG_ASSERT(queue->elements < queue->max_elements); + queue->root[0]= element; + idx= ++queue->elements; + /* max_at_top swaps the comparison if we want to order by desc */ + while ((cmp= queue->compare(queue->first_cmp_arg, + element + queue->offset_to_key, + queue->root[(next= idx >> 1)] + + queue->offset_to_key)) && + (cmp ^ queue->max_at_top) < 0) { - queue->root[0]=element; - idx= ++queue->elements; - - /* max_at_top swaps the comparison if we want to order by desc */ - while ((cmp=queue->compare(queue->first_cmp_arg, - element+queue->offset_to_key, - queue->root[(next=idx >> 1)] + - queue->offset_to_key)) && - (cmp ^ queue->max_at_top) < 0) - { - queue->root[idx]=queue->root[next]; - idx=next; - } - queue->root[idx]=element; + queue->root[idx]= queue->root[next]; + idx= next; } + queue->root[idx]= element; } /* @@ -262,16 +256,12 @@ int queue_insert_safe(register QUEUE *queue, byte *element) byte *queue_remove(register QUEUE *queue, uint idx) { -#ifndef DBUG_OFF - if (idx >= queue->max_elements) - return 0; -#endif - { - byte *element=queue->root[++idx]; /* Intern index starts from 1 */ - queue->root[idx]=queue->root[queue->elements--]; - _downheap(queue,idx); - return element; - } + byte *element; + DBUG_ASSERT(idx < queue->max_elements); + element= queue->root[++idx]; /* Intern index starts from 1 */ + queue->root[idx]= queue->root[queue->elements--]; + _downheap(queue, idx); + return element; } /* Fix when element on top has been replaced */ diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c index 862201ed841..dafb3246cbf 100644 --- a/storage/myisammrg/myrg_open.c +++ b/storage/myisammrg/myrg_open.c @@ -33,7 +33,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) { int save_errno,errpos=0; - uint files=0,i,dir_length,length,key_parts; + uint files= 0, i, dir_length, length, key_parts, min_keys= 0; ulonglong file_offset=0; char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end; MYRG_INFO *m_info=0; @@ -110,6 +110,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) files= 0; } m_info->reclength=isam->s->base.reclength; + min_keys= isam->s->base.keys; errpos=3; } m_info->open_tables[files].table= isam; @@ -125,6 +126,8 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) m_info->records+= isam->state->records; m_info->del+= isam->state->del; m_info->data_file_length+= isam->state->data_file_length; + if (min_keys > isam->s->base.keys) + min_keys= isam->s->base.keys; for (i=0; i < key_parts; i++) m_info->rec_per_key_part[i]+= (isam->s->state.rec_per_key_part[i] / m_info->tables); @@ -142,7 +145,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) my_errno=HA_ERR_RECORD_FILE_FULL; goto err; } - m_info->keys= files ? isam->s->base.keys : 0; + m_info->keys= min_keys; bzero((char*) &m_info->by_key,sizeof(m_info->by_key)); /* this works ok if the table list is empty */ diff --git a/storage/myisammrg/myrg_queue.c b/storage/myisammrg/myrg_queue.c index 2e600a526c0..74fdddc7748 100644 --- a/storage/myisammrg/myrg_queue.c +++ b/storage/myisammrg/myrg_queue.c @@ -65,6 +65,8 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag) error=my_errno; } } + else + my_errno= error= HA_ERR_WRONG_INDEX; return error; } |