Cursor::doStartTableScan can be called twice without any cleanup

Bug #585815 reported by Stewart Smith
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Drizzle
Confirmed
Low
Stewart Smith

Bug Description

first select query in count_distinct.

hit assert in libinnodb with embedded_innodb engine.

Breakpoint 1, drizzled::mysql_parse (session=0x14e0f10,
    inBuf=0x14de808 "drop table if exists t1,t2,t3", length=29)
    at drizzled/sql_parse.cc:715
715 lex_start(session);
(gdb) b EmbeddedInnoDBCursor::doStartTableScan(bool)
Breakpoint 2 at 0x7ffff3f2e9d8: file plugin/embedded_innodb/embedded_innodb_engine.cc, line 1735.
(gdb) c
Continuing.

Breakpoint 2, EmbeddedInnoDBCursor::doStartTableScan (this=0x14f7268)
    at plugin/embedded_innodb/embedded_innodb_engine.cc:1735
1735 if(*get_trx(current_session) == NULL)
(gdb) b EmbeddedInnoDBCursor::doEndTableScan()
Breakpoint 3 at 0x7ffff3f2efee: file plugin/embedded_innodb/embedded_innodb_engine.cc, line 1860.
(gdb) b EmbeddedInnoDBCursor::close()
Breakpoint 4 at 0x7ffff3f2b6b6: file plugin/embedded_innodb/embedded_innodb_engine.cc, line 628.
(gdb) b EmbeddedInnoDBCursor::reset()
Breakpoint 5 at 0x7ffff3f2fe12: file plugin/embedded_innodb/embedded_innodb_engine.cc, line 2221.
(gdb) c
Continuing.

Breakpoint 2, EmbeddedInnoDBCursor::doStartTableScan (this=0x14f7268)
    at plugin/embedded_innodb/embedded_innodb_engine.cc:1735
1735 if(*get_trx(current_session) == NULL)
(gdb)

Revision history for this message
Stewart Smith (stewart) wrote :

=== modified file 'plugin/embedded_innodb/embedded_innodb_engine.cc'
--- plugin/embedded_innodb/embedded_innodb_engine.cc 2010-05-26 10:19:08 +0000
+++ plugin/embedded_innodb/embedded_innodb_engine.cc 2010-05-26 13:14:09 +0000
@@ -620,6 +620,8 @@
     ref_length= 0; // FIXME: this is a bug. we need to work out what index it is.
   }

+ in_table_scan= false;
+
   return(0);
 }

@@ -1732,6 +1734,10 @@
 {
   ib_trx_t transaction;

+ if (in_table_scan)
+ doEndTableScan();
+ in_table_scan= true;
+
   if(*get_trx(current_session) == NULL)
   {
     EmbeddedInnoDBEngine *innodb_engine= static_cast<EmbeddedInnoDBEngine*>(engine);
@@ -1859,7 +1865,7 @@
   ib_tuple_delete(tuple);
   err= ib_cursor_reset(cursor);
   assert(err == DB_SUCCESS);
-
+ in_table_scan= false;
   return 0;
 }
You need to do something like this:

=== modified file 'plugin/embedded_innodb/embedded_innodb_engine.h'
--- plugin/embedded_innodb/embedded_innodb_engine.h 2010-05-26 10:19:08 +0000
+++ plugin/embedded_innodb/embedded_innodb_engine.h 2010-05-26 13:14:09 +0000
@@ -123,6 +123,8 @@
   bool write_can_replace;
   uint64_t hidden_autoinc_pkey_position;
   drizzled::memory::Root *blobroot;
+
+ bool in_table_scan;
 };

 #endif /* PLUGIN_EMBEDDED_INNODB_EMBEDDED_INNODB_ENGINE_H */

Revision history for this message
Stewart Smith (stewart) wrote :

What you know (from http://forge.mysql.com/wiki/MySQL_Internals_Custom_Engine#14.17.21.rnd_init):

Unlike index_init(), rnd_init() can be called two times without rnd_end() in between (it only makes sense if scan=1). then the second call should prepare for the new table scan (e.g if rnd_init allocates the cursor, second call should position it to the start of the table, no need to deallocate and allocate it again

Actually documented.

Index scanning has index_first()... why we couldn't have something sane ,who knows.

We should still fix it.

Stewart Smith (stewart)
Changed in drizzle:
importance: Undecided → Low
Changed in drizzle:
assignee: nobody → Stewart Smith (stewart)
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.