Commit f6cd0148 authored by patg@krsna.patg.net's avatar patg@krsna.patg.net

BUG #14524

Patch that fixes crashing when partition uses blackole for 
underlying tables.
parent 6c4a4d18
...@@ -108,3 +108,11 @@ insert into t1 values (3); ...@@ -108,3 +108,11 @@ insert into t1 values (3);
insert into t1 values (4); insert into t1 values (4);
UNLOCK TABLES; UNLOCK TABLES;
drop table t1; drop table t1;
DROP TABLE IF EXISTS `t1`;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE `t1` (
`id` int(11) default NULL
) ENGINE=BLACKHOLE DEFAULT CHARSET=latin1 PARTITION BY HASH (id) ;
SELECT * FROM t1;
id
...@@ -162,3 +162,13 @@ UNLOCK TABLES; ...@@ -162,3 +162,13 @@ UNLOCK TABLES;
drop table t1; drop table t1;
#
# BUG 14524
#
--disable-warnings
DROP TABLE IF EXISTS `t1`;
--enable-warnings
CREATE TABLE `t1` (
`id` int(11) default NULL
) ENGINE=BLACKHOLE DEFAULT CHARSET=latin1 PARTITION BY HASH (id) ;
SELECT * FROM t1;
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* /*
This handler was developed by Mikael Ronström for version 5.1 of MySQL. This handler was developed by Mikael Ronstrom for version 5.1 of MySQL.
It is an abstraction layer on top of other handlers such as MyISAM, It is an abstraction layer on top of other handlers such as MyISAM,
InnoDB, Federated, Berkeley DB and so forth. Partitioned tables can also InnoDB, Federated, Berkeley DB and so forth. Partitioned tables can also
be handled by a storage engine. The current example of this is NDB be handled by a storage engine. The current example of this is NDB
...@@ -167,6 +167,10 @@ void ha_partition::init_handler_variables() ...@@ -167,6 +167,10 @@ void ha_partition::init_handler_variables()
m_last_part= 0; m_last_part= 0;
m_rec0= 0; m_rec0= 0;
m_curr_key_info= 0; m_curr_key_info= 0;
/*
this allows blackhole to work properly
*/
m_no_locks= 0;
#ifdef DONT_HAVE_TO_BE_INITALIZED #ifdef DONT_HAVE_TO_BE_INITALIZED
m_start_key.flag= 0; m_start_key.flag= 0;
...@@ -912,6 +916,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) ...@@ -912,6 +916,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
if ((error= (*file)->ha_open((const char*) name_buff, mode, if ((error= (*file)->ha_open((const char*) name_buff, mode,
test_if_locked))) test_if_locked)))
goto err_handler; goto err_handler;
m_no_locks+= (*file)->lock_count();
name_buffer_ptr+= strlen(name_buffer_ptr) + 1; name_buffer_ptr+= strlen(name_buffer_ptr) + 1;
set_if_bigger(ref_length, ((*file)->ref_length)); set_if_bigger(ref_length, ((*file)->ref_length));
} while (*(++file)); } while (*(++file));
...@@ -1098,6 +1103,9 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type) ...@@ -1098,6 +1103,9 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type)
uint ha_partition::lock_count() const uint ha_partition::lock_count() const
{ {
DBUG_ENTER("ha_partition::lock_count"); DBUG_ENTER("ha_partition::lock_count");
if (m_no_locks == 0)
DBUG_RETURN(0);
DBUG_RETURN(m_tot_parts); DBUG_RETURN(m_tot_parts);
} }
...@@ -1143,7 +1151,7 @@ void ha_partition::unlock_row() ...@@ -1143,7 +1151,7 @@ void ha_partition::unlock_row()
ADDITIONAL INFO: ADDITIONAL INFO:
Most handlers set timestamp when calling write row if any such fields Most handlers set timestamp when calling write row if any such fields
exists. Since we are calling an underlying handler we assume the´ exists. Since we are calling an underlying handler we assume the
underlying handler will assume this responsibility. underlying handler will assume this responsibility.
Underlying handlers will also call update_auto_increment to calculate Underlying handlers will also call update_auto_increment to calculate
......
...@@ -67,6 +67,7 @@ class ha_partition :public handler ...@@ -67,6 +67,7 @@ class ha_partition :public handler
u_long m_low_byte_first; u_long m_low_byte_first;
uint m_tot_parts; // Total number of partitions; uint m_tot_parts; // Total number of partitions;
uint m_no_locks; // For engines like ha_blackhole, which needs no locks
uint m_last_part; // Last file that we update,write uint m_last_part; // Last file that we update,write
int m_lock_type; // Remembers type of last int m_lock_type; // Remembers type of last
// external_lock // external_lock
......
...@@ -146,6 +146,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, ...@@ -146,6 +146,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
} }
thd->proc_info="System lock"; thd->proc_info="System lock";
DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
if (lock_external(thd, tables, count)) if (lock_external(thd, tables, count))
{ {
my_free((gptr) sql_lock,MYF(0)); my_free((gptr) sql_lock,MYF(0));
...@@ -153,6 +154,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, ...@@ -153,6 +154,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
break; break;
} }
thd->proc_info="Table lock"; thd->proc_info="Table lock";
DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info));
thd->locked=1; thd->locked=1;
rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks, rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks,
sql_lock->lock_count, sql_lock->lock_count,
...@@ -218,6 +220,7 @@ static int lock_external(THD *thd, TABLE **tables, uint count) ...@@ -218,6 +220,7 @@ static int lock_external(THD *thd, TABLE **tables, uint count)
int lock_type,error; int lock_type,error;
DBUG_ENTER("lock_external"); DBUG_ENTER("lock_external");
DBUG_PRINT("info", ("count %d", count));
for (i=1 ; i <= count ; i++, tables++) for (i=1 ; i <= count ; i++, tables++)
{ {
DBUG_ASSERT((*tables)->reginfo.lock_type >= TL_READ); DBUG_ASSERT((*tables)->reginfo.lock_type >= TL_READ);
...@@ -460,6 +463,8 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, ...@@ -460,6 +463,8 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
THR_LOCK_DATA **locks; THR_LOCK_DATA **locks;
TABLE **to; TABLE **to;
DBUG_ENTER("get_lock_data");
DBUG_PRINT("info", ("count %d", count));
*write_lock_used=0; *write_lock_used=0;
for (i=tables=lock_count=0 ; i < count ; i++) for (i=tables=lock_count=0 ; i < count ; i++)
{ {
...@@ -479,7 +484,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, ...@@ -479,7 +484,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
{ {
my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0), table_ptr[i]->s->db, my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0), table_ptr[i]->s->db,
table_ptr[i]->s->table_name); table_ptr[i]->s->table_name);
return 0; DBUG_RETURN(0);
} }
} }
...@@ -487,11 +492,13 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, ...@@ -487,11 +492,13 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
my_malloc(sizeof(*sql_lock)+ my_malloc(sizeof(*sql_lock)+
sizeof(THR_LOCK_DATA*)*tables+sizeof(table_ptr)*lock_count, sizeof(THR_LOCK_DATA*)*tables+sizeof(table_ptr)*lock_count,
MYF(0)))) MYF(0))))
return 0; DBUG_RETURN(0);
locks=sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1); locks=sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1);
to=sql_lock->table=(TABLE**) (locks+tables); to=sql_lock->table=(TABLE**) (locks+tables);
sql_lock->table_count=lock_count; sql_lock->table_count=lock_count;
sql_lock->lock_count=tables; sql_lock->lock_count=tables;
DBUG_PRINT("info", ("sql_lock->table_count %d sql_lock->lock_count %d",
sql_lock->table_count, sql_lock->lock_count));
for (i=0 ; i < count ; i++) for (i=0 ; i < count ; i++)
{ {
...@@ -507,7 +514,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, ...@@ -507,7 +514,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
{ {
my_error(ER_OPEN_AS_READONLY, MYF(0), table->alias); my_error(ER_OPEN_AS_READONLY, MYF(0), table->alias);
my_free((gptr) sql_lock,MYF(0)); my_free((gptr) sql_lock,MYF(0));
return 0; DBUG_RETURN(0);
} }
} }
THR_LOCK_DATA **org_locks = locks; THR_LOCK_DATA **org_locks = locks;
...@@ -517,7 +524,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, ...@@ -517,7 +524,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
for ( ; org_locks != locks ; org_locks++) for ( ; org_locks != locks ; org_locks++)
(*org_locks)->debug_print_param= (void *) table; (*org_locks)->debug_print_param= (void *) table;
} }
return sql_lock; DBUG_RETURN(sql_lock);
} }
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
used by all handlers that support partitioning, which in the first version used by all handlers that support partitioning, which in the first version
is the partitioning handler itself and the NDB handler. is the partitioning handler itself and the NDB handler.
The first version was written by Mikael Ronström. The first version was written by Mikael Ronstrom.
This version supports RANGE partitioning, LIST partitioning, HASH This version supports RANGE partitioning, LIST partitioning, HASH
partitioning and composite partitioning (hereafter called subpartitioning) partitioning and composite partitioning (hereafter called subpartitioning)
......
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