This is where I am so far.
There are obvious flaws, but this does work for I_S tables pretty well.
=== modified file 'drizzled/message/table.proto'
--- drizzled/message/table.proto 2009-10-29 00:52:58 +0000
+++ drizzled/message/table.proto 2009-11-03 23:06:44 +0000
@@ -6,6 +6,7 @@ message Table {
enum TableType {
STANDARD = 0;
TEMPORARY = 1;
+ INTERNAL_TEMPORARY = 2;
}
message StorageEngine {
=== modified file 'drizzled/show.cc'
--- drizzled/show.cc 2009-10-30 15:58:06 +0000
+++ drizzled/show.cc 2009-11-03 23:06:43 +0000
@@ -2205,97 +2205,109 @@ Table *plugin::InfoSchemaMethods::create
const
{
int field_count= 0;
- Item *item;
Table *table;
- List<Item> field_list;
- const CHARSET_INFO * const cs= system_charset_info;
const plugin::InfoSchemaTable::Columns &columns=
table_list->schema_table->getColumns();
plugin::InfoSchemaTable::Columns::const_iterator iter= columns.begin();
+ message::Table table_proto;
+
+ table_proto.set_name(table_list->schema_table->getName());
+ table_proto.set_type(message::Table::TEMPORARY);
+
+ message::Table::TableOptions *table_options= table_proto.mutable_options();
+ table_options->set_collation_id(system_charset_info->number);
+ table_options->set_collation(system_charset_info->name);
+
+
while (iter != columns.end())
{
const plugin::ColumnInfo *column= *iter;
+
+ message::Table::Field *attribute;
+
+ attribute= table_proto.add_field();
+ attribute->set_name(column->getName());
+
+ message::Table::Field::FieldOptions *field_options;
+ field_options= attribute->mutable_options();
+
switch (column->getType()) {
case DRIZZLE_TYPE_LONG:
case DRIZZLE_TYPE_LONGLONG:
- if (!(item= new Item_return_int(column->getName().c_str(),
- column->getLength(),
- column->getType(),
- column->getValue())))
- {
- return(0);
- }
- item->unsigned_flag= (column->getFlags() & MY_I_S_UNSIGNED);
+ attribute->set_type(message::Table::Field::BIGINT);
+ field_options->set_length(MAX_BIGINT_WIDTH);
+// item->unsigned_flag= (column->getFlags() & MY_I_S_UNSIGNED);
break;
case DRIZZLE_TYPE_DATE:
case DRIZZLE_TYPE_TIMESTAMP:
case DRIZZLE_TYPE_DATETIME:
- if (!(item=new Item_return_date_time(column->getName().c_str(),
- column->getType())))
- {
- return(0);
- }
+ attribute->set_type(message::Table::Field::DATETIME);
break;
case DRIZZLE_TYPE_DOUBLE:
- if ((item= new Item_float(column->getName().c_str(), 0.0, NOT_FIXED_DEC,
- column->getLength())) == NULL)
- return NULL;
+ attribute->set_type(message::Table::Field::DOUBLE);
break;
case DRIZZLE_TYPE_NEWDECIMAL:
- if (!(item= new Item_decimal((int64_t) column->getValue(), false)))
- {
- return(0);
- }
- item->unsigned_flag= (column->getFlags() & MY_I_S_UNSIGNED);
- item->decimals= column->getLength() % 10;
- item->max_length= (column->getLength()/100)%100;
- if (item->unsigned_flag == 0)
- item->max_length+= 1;
- if (item->decimals > 0)
- item->max_length+= 1;
- item->set_name(column->getName().c_str(),
- column->getName().length(), cs);
+ attribute->set_type(message::Table::Field::DECIMAL);
+
+// item->unsigned_flag= (column->getFlags() & MY_I_S_UNSIGNED);
+
+ drizzled::message::Table::Field::NumericFieldOptions
*numeric_field_options;
+
+ numeric_field_options= attribute->mutable_numeric_options();
+
+ if (column->getLength() % 10) // field_arg->decimals
+ numeric_field_options->set_precision(column->getLength() - 2); /* One
for the decimal, one for the header */
+ else
+ numeric_field_options->set_precision(column->getLength() - 1); /* for
the header */
+ numeric_field_options->set_scale(column->getLength() % 10);
+
+ // item->max_length= (column->getLength()/100)%100;
break;
case DRIZZLE_TYPE_BLOB:
- if (!(item= new Item_blob(column->getName().c_str(),
- column->getLength())))
- {
- return(0);
- }
+ attribute->set_type(message::Table::Field::BLOB);
+ break;
+ case DRIZZLE_TYPE_VARCHAR:
+ {
+ drizzled::message::Table::Field::StringFieldOptions
*string_field_options;
+ string_field_options= attribute->mutable_string_options();
+ string_field_options->set_length(column->getLength());
+
+ attribute->set_type(message::Table::Field::VARCHAR);
+ field_options->set_length(column->getLength() * 4);
+ }
break;
default:
- if (!(item= new Item_empty_string("", column->getLength(), cs)))
- {
- return(0);
- }
- item->set_name(column->getName().c_str(),
- column->getName().length(), cs);
+ assert(false);
break;
}
- field_list.push_back(item);
- item->maybe_null= (column->getFlags() & MY_I_S_MAYBE_NULL);
+/* field_list.push_back(item);
+ item->maybe_null= (column->getFlags() & MY_I_S_MAYBE_NULL);*/
+ message::Table::Field::FieldConstraints *constraints;
+
+ constraints= attribute->mutable_constraints();
+ constraints->set_is_nullable((column->getFlags() & MY_I_S_MAYBE_NULL));
+
field_count++;
++iter;
+
}
- Tmp_Table_Param *tmp_table_param =
- (Tmp_Table_Param*) (session->alloc(sizeof(Tmp_Table_Param)));
- tmp_table_param->init();
- tmp_table_param->table_charset= cs;
- tmp_table_param->field_count= field_count;
- tmp_table_param->schema_table= 1;
- Select_Lex *select_lex= session->lex->current_select;
- if (!(table= create_tmp_table(session, tmp_table_param,
- field_list, (order_st*) 0, 0, 0,
- (select_lex->options | session->options |
- TMP_TABLE_ALL_COLUMNS),
- HA_POS_ERROR, table_list->alias)))
- return(0);
- my_bitmap_map* bitmaps=
+
+ table= create_internal_temporary_table(session, &table_proto);
+
+ assert(table);
+
+ my_bitmap_map* read_bitmap=
(my_bitmap_map*) session->alloc(bitmap_buffer_size(field_count));
- table->def_read_set.init((my_bitmap_map*) bitmaps, field_count);
+ table->def_read_set.init((my_bitmap_map*) read_bitmap, field_count);
table->read_set= &table->def_read_set;
table->read_set->clearAll();
- table_list->schema_table_param= tmp_table_param;
+
+ my_bitmap_map* write_bitmap=
+ (my_bitmap_map*) session->alloc(bitmap_buffer_size(field_count));
+
+ table->def_write_set.init((my_bitmap_map*) (write_bitmap), field_count);
+ table->write_set->setAll();
+
return(table);
}
=== modified file 'drizzled/table.cc'
--- drizzled/table.cc 2009-10-29 00:52:58 +0000
+++ drizzled/table.cc 2009-11-03 23:06:44 +0000
@@ -2245,6 +2245,98 @@ static Field *create_tmp_field_for_schem
return item->tmp_table_field_from_field_type(table, 0);
}
+/* As the old method of creating internal temp tables has been linked
+ to cancer in mice. */
+Table* create_internal_temporary_table(Session *session,
+ message::Table *table_proto)
+{
+ HA_CREATE_INFO create_info;
+ char dst_path[FN_REFLEN];
+ char tmp_name[FN_REFLEN];
+
+ status_var_increment(session->status_var.created_tmp_tables);
+
+ /* Create a table name for the table... really a file path, which is ass */
+ snprintf(tmp_name, sizeof(tmp_name), "%s%lx_%"PRIx64"_%x",
+ TMP_FILE_PREFIX, (unsigned long)current_pid,
+ session->thread_id, session->tmp_table++);
+
+ fn_format(dst_path, tmp_name, drizzle_tmpdir, "",
+ MY_REPLACE_EXT|MY_UNPACK_FILENAME);
+
+ /* Set some options that callers haven't (e.g. engine) */
+
+ memset(&create_info, 0, sizeof(HA_CREATE_INFO)); /* MUST DIE */
+
+ message::Table::StorageEngine *table_engine= table_proto->mutable_engine();
+
+ table_engine->set_name("MyISAM"); /* FIXME: Currently we force heap */
+
+
+ /* Create the actual table */
+ int err= plugin::StorageEngine::createTable(session, dst_path,
+ session->db, tmp_name,
+ &create_info, false,
table_proto);
+
+ assert(!err);
+
+ /* Now open the temporary table, taking a shortcut in not
+ writing the proto to disk (just parsing the in memory copy to
+ TableShare.
+
+ This code looks a bit similar to open_temporary_table, but
+ is geared towards internal temporary tables.
+ */
+
+ Table *new_tmp_table;
+ TableShare *share;
+ char cache_key[MAX_DBKEY_LENGTH], *saved_cache_key, *tmp_path;
+ uint32_t key_length, path_length;
+ TableList table_list;
+
+ table_list.db= (char*) session->db;
+ table_list.table_name= (char*) tmp_name;
+ /* Create the cache_key for temporary tables */
+ key_length= table_list.create_table_def_key(cache_key);
+ path_length= strlen(dst_path);
+
+ if (!(new_tmp_table= (Table*) malloc(sizeof(*new_tmp_table) + sizeof(*share)
+
+ path_length + 1 + key_length)))
+ return NULL;
+
+ share= (TableShare*) (new_tmp_table+1);
+ tmp_path= (char*) (share+1);
+ saved_cache_key= strcpy(tmp_path, dst_path)+path_length+1;
+ memcpy(saved_cache_key, cache_key, key_length);
+
+ share->init(saved_cache_key, key_length, tmp_path, tmp_path);
+
+ err= parse_table_proto(session, *table_proto, share);
+
+ assert(!err);
+
+ share->table_category= TABLE_CATEGORY_TEMPORARY;
+
+ if(open_table_from_share(session, share, tmp_name,
+ (uint32_t) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
+ HA_GET_INDEX),
+ (EXTRA_RECORD),
+ HA_OPEN_INTERNAL_TABLE, /* makes drop on close() */
+ new_tmp_table, OTM_OPEN))
+ {
+ /* No need to lock share->mutex as this is not needed for tmp tables */
+ share->free_table_share();
+ free((char*) new_tmp_table);
+ return NULL;
+ }
+
+ new_tmp_table->reginfo.lock_type= TL_WRITE; // Simulate locked
+ share->tmp_table= (new_tmp_table->file->has_transactions() ?
+ TRANSACTIONAL_TMP_TABLE : NON_TRANSACTIONAL_TMP_TABLE);
+ new_tmp_table->pos_in_table_list= 0;
+
+ return new_tmp_table;
+}
/**
Create a temp table according to a field list.
=== modified file 'drizzled/table.h'
--- drizzled/table.h 2009-10-20 16:11:52 +0000
+++ drizzled/table.h 2009-11-03 23:06:44 +0000
@@ -56,6 +56,8 @@ bool create_myisam_from_heap(Session *se
MI_COLUMNDEF **recinfo,
int error, bool ignore_last_dupp_key_error);
+Table* create_internal_temporary_table(Session *session,
+ drizzled::message::Table *table_proto);
/**
* Class representing a set of records, either in a temporary,
* normal, or derived table.
--
Stewart Smith
_______________________________________________
Mailing list: https://launchpad.net/~drizzle-discuss
Post to : [email protected]
Unsubscribe : https://launchpad.net/~drizzle-discuss
More help : https://help.launchpad.net/ListHelp