* Jay Pipes <Jay.Pipes@Sun.COM> [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(), correct? 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. 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", cursor1->record[0].to_string(), cursor2->record[0].to_string()); delete cursor1; delete cursor2; delete table; 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. - have an own TABLE instance for each independent read/scan/update. Because 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. - 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()) 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 table. Put it this way: once you have a correct solution for the problem, Bug#7742 will get solved naturally.
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...
-jay
--