Commit 586ee5d6 authored by Mattias Jonsson's avatar Mattias Jonsson

Bug#46639: 1030 (HY000): Got error 124 from storage engine on

INSERT ... SELECT ...

Problem was that when bulk insert is used on an empty
table/partition, it disables the indexes for better
performance, but in this specific case it also tries
to read from that partition using an index, which is
not possible since it has been disabled.

Solution was to allow index reads on disabled indexes
if there are no records.

Also reverted the patch for bug#38005, since that was a workaround
in the partitioning engine instead of a fix in myisam.
parent 43851cb8
drop table if exists t1, t2; drop table if exists t1, t2;
CREATE TABLE t1 ( CREATE TABLE t1 (
a int NOT NULL,
b int NOT NULL);
CREATE TABLE t2 (
a int NOT NULL,
b int NOT NULL,
INDEX(b)
)
PARTITION BY HASH(a) PARTITIONS 2;
INSERT INTO t1 VALUES (399, 22);
INSERT INTO t2 VALUES (1, 22), (1, 42);
INSERT INTO t2 SELECT 1, 399 FROM t2, t1
WHERE t1.b = t2.b;
DROP TABLE t1, t2;
CREATE TABLE t1 (
a timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, a timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
b varchar(10), b varchar(10),
PRIMARY KEY (a) PRIMARY KEY (a)
......
...@@ -14,6 +14,28 @@ ...@@ -14,6 +14,28 @@
drop table if exists t1, t2; drop table if exists t1, t2;
--enable_warnings --enable_warnings
#
# Bug#46639: 1030 (HY000): Got error 124 from storage engine on
# INSERT ... SELECT ...
CREATE TABLE t1 (
a int NOT NULL,
b int NOT NULL);
CREATE TABLE t2 (
a int NOT NULL,
b int NOT NULL,
INDEX(b)
)
PARTITION BY HASH(a) PARTITIONS 2;
INSERT INTO t1 VALUES (399, 22);
INSERT INTO t2 VALUES (1, 22), (1, 42);
INSERT INTO t2 SELECT 1, 399 FROM t2, t1
WHERE t1.b = t2.b;
DROP TABLE t1, t2;
# #
# Bug#46478: timestamp field incorrectly defaulted when partition is reorganized # Bug#46478: timestamp field incorrectly defaulted when partition is reorganized
# #
......
...@@ -4414,17 +4414,6 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf) ...@@ -4414,17 +4414,6 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf)
break; break;
case partition_index_first: case partition_index_first:
DBUG_PRINT("info", ("index_first on partition %d", i)); DBUG_PRINT("info", ("index_first on partition %d", i));
/* MyISAM engine can fail if we call index_first() when indexes disabled */
/* that happens if the table is empty. */
/* Here we use file->stats.records instead of file->records() because */
/* file->records() is supposed to return an EXACT count, and it can be */
/* possibly slow. We don't need an exact number, an approximate one- from*/
/* the last ::info() call - is sufficient. */
if (file->stats.records == 0)
{
error= HA_ERR_END_OF_FILE;
break;
}
error= file->index_first(buf); error= file->index_first(buf);
break; break;
case partition_index_first_unordered: case partition_index_first_unordered:
...@@ -4512,32 +4501,10 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) ...@@ -4512,32 +4501,10 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
m_start_key.flag); m_start_key.flag);
break; break;
case partition_index_first: case partition_index_first:
/* MyISAM engine can fail if we call index_first() when indexes disabled */
/* that happens if the table is empty. */
/* Here we use file->stats.records instead of file->records() because */
/* file->records() is supposed to return an EXACT count, and it can be */
/* possibly slow. We don't need an exact number, an approximate one- from*/
/* the last ::info() call - is sufficient. */
if (file->stats.records == 0)
{
error= HA_ERR_END_OF_FILE;
break;
}
error= file->index_first(rec_buf_ptr); error= file->index_first(rec_buf_ptr);
reverse_order= FALSE; reverse_order= FALSE;
break; break;
case partition_index_last: case partition_index_last:
/* MyISAM engine can fail if we call index_last() when indexes disabled */
/* that happens if the table is empty. */
/* Here we use file->stats.records instead of file->records() because */
/* file->records() is supposed to return an EXACT count, and it can be */
/* possibly slow. We don't need an exact number, an approximate one- from*/
/* the last ::info() call - is sufficient. */
if (file->stats.records == 0)
{
error= HA_ERR_END_OF_FILE;
break;
}
error= file->index_last(rec_buf_ptr); error= file->index_last(rec_buf_ptr);
reverse_order= TRUE; reverse_order= TRUE;
break; break;
......
...@@ -28,9 +28,15 @@ int _mi_check_index(MI_INFO *info, int inx) ...@@ -28,9 +28,15 @@ int _mi_check_index(MI_INFO *info, int inx)
{ {
if (inx == -1) /* Use last index */ if (inx == -1) /* Use last index */
inx=info->lastinx; inx=info->lastinx;
if (inx < 0 || ! mi_is_key_active(info->s->state.key_map, inx)) if (inx < 0)
{ {
my_errno=HA_ERR_WRONG_INDEX; my_errno= HA_ERR_WRONG_INDEX;
return -1;
}
if (!mi_is_key_active(info->s->state.key_map, inx))
{
my_errno= info->s->state.state.records ? HA_ERR_WRONG_INDEX :
HA_ERR_END_OF_FILE;
return -1; return -1;
} }
if (info->lastinx != inx) /* Index changed */ if (info->lastinx != inx) /* Index changed */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment