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

Reply via email to