← Back to team overview

maria-developers team mailing list archive

Re: Storage Engine API changes


Konstantin Osipov wrote:
* Jay Pipes <Jay.Pipes@xxxxxxx> [09/07/09 00:02]:
The current aim is to remove things that obviously aren't related to a
cursor and move them up.
e.g. create table is now in StorageEngine.
at some point s/handler/cursor/
Bad idea IMHO. You don't need to keep all cursors in the table cache
and look every cursor with thr_lock.

What is the suggested way of getting hold of a cursor? open_table(),
But open_table() is overloaded: - it protects the table from being altered in another connection
- it has bits of StorageInterface in it.
- finally, it's a cursor.

Exactly! Too much going on in the handler class and in methods like open_table() :)

So the current way to read from a storage engine cursor, and you're not changing that it seems, is to get hold of a TABLE
instance, a handler instance, and then do
rnd_init()/rnd_next()/rnd_end() on it.

If you want to read from two different indexes of the same table
simultaneously, you need two TABLE and handler instances.

This is at the core of the problem.

Instead, one needs to be able to do:

Table *table= storage_interface->get_table();

Cursor *cursor1= table->create_rnd_scan_cursor();
Cursor *cursor2= table->create_index_scan_cursor(index);

cursor1->open(); cursor2->open();
cursor1->read_next(); cursor2->read_next();

printf("First row in index: %s, First row physically %s\n",

delete cursor1;
delete cursor2;
delete table;

This is actually very similar to the efforts underway in my local trees. Although, I have to admit, I've tried killing the term "rnd" since nobody seems to understand what the heck it means ;)

If you just move stuff that logically belongs to StorageInterface, and then rename handler to cursor you still have to:

 - have an own handler instance for each independent read/scan or
   update. An update is also part of the cursor API, but more
   advanced one - class Updatable_cursor: public Cursor.

Sure, but first things first...get the basic stuff fine-tuned and working correctly before we try to bite off more than we can chew (or that the kernel should chew itself vs. a plugin...) :)

 - have an own TABLE instance for each independent read/scan/update.
   of table->field[], table->auto_increment* and table->record[],
   which is, really, not part of the table, but a structure to
   exchange data with the table.

These are more appropriately handled by a TableShare with a built-in version or timestamp, no?

 - use a different method depending on whether you want to read
   the next record from an index (index_next), or in physical
   order (rnd_next())

This is fairly simple to do with abstract base classes and subclass implementations in C++... Basically, the READ_RECORD structure currently does this work in a C-style way, no?

To change the server to use the new cursor API you need to change
the execution layer -- JOIN::execute(), READ_RECORD,
join_read* functions and sub_select code, the parser to not
add another TABLE_LIST to thd->lex->query_tables for each time a
table is mentioned in a statement, open_tables
to open no more than one instance of the same table,
the table cache, to not hold more than one instance of the same

Yes, exactly.  This is the work we are currently doing.

Put it this way: once you have a correct solution for the problem, Bug#7742 will get solved naturally.

Cool :)

Hi! I'm not sure what you mean by "look every cursor with thr_lock"? Do you mean "lock every cursor with thr_lock"? If so, we're in the process of removing the thr_lock stuff entirely (a lot easier now that MyISAM is TEMP TABLE ONLY in Drizzle...

You should be able to
create cursors at leisure during execution, and destroy them when
not needed.
Agreed. Part of the work we are doing is reducing and simplifiying the Handler class before it gets converted to a stand-alone Cursor class that can be allocated, used, and destroyed without worrying about thr_lock mess...