~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

updating

Show diffs side-by-side

added added

removed removed

Lines of Context:
87
87
    let's fetch the database default character set and
88
88
    apply it to the table.
89
89
  */
90
 
  SchemaIdentifier identifier(db);
 
90
  identifier::Schema identifier(db);
91
91
  if (create_info->default_table_charset == NULL)
92
92
    create_info->default_table_charset= plugin::StorageEngine::getSchemaCollation(identifier);
93
93
}
141
141
*/
142
142
 
143
143
int rm_table_part2(Session *session, TableList *tables, bool if_exists,
144
 
                         bool drop_temporary)
 
144
                   bool drop_temporary)
145
145
{
146
146
  TableList *table;
147
147
  String wrong_tables;
162
162
 
163
163
    for (table= tables; table; table= table->next_local)
164
164
    {
165
 
      TableIdentifier tmp_identifier(table->getSchemaName(), table->getTableName());
 
165
      identifier::Table tmp_identifier(table->getSchemaName(), table->getTableName());
166
166
 
167
167
      error= session->drop_temporary_table(tmp_identifier);
168
168
 
198
198
          break;
199
199
        }
200
200
      }
201
 
      TableIdentifier identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
 
201
      identifier::Table identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
202
202
 
203
203
      if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
204
204
      {
1296
1296
}
1297
1297
 
1298
1298
static bool locked_create_event(Session *session,
1299
 
                                const TableIdentifier &identifier,
 
1299
                                const identifier::Table &identifier,
1300
1300
                                HA_CREATE_INFO *create_info,
1301
1301
                                message::Table &table_proto,
1302
1302
                                AlterInfo *alter_info,
1432
1432
*/
1433
1433
 
1434
1434
bool create_table_no_lock(Session *session,
1435
 
                                const TableIdentifier &identifier,
 
1435
                                const identifier::Table &identifier,
1436
1436
                                HA_CREATE_INFO *create_info,
1437
1437
                                message::Table &table_proto,
1438
1438
                                AlterInfo *alter_info,
1484
1484
  @note the following two methods implement create [temporary] table.
1485
1485
*/
1486
1486
static bool drizzle_create_table(Session *session,
1487
 
                                 const TableIdentifier &identifier,
 
1487
                                 const identifier::Table &identifier,
1488
1488
                                 HA_CREATE_INFO *create_info,
1489
1489
                                 message::Table &table_proto,
1490
1490
                                 AlterInfo *alter_info,
1543
1543
  Database locking aware wrapper for create_table_no_lock(),
1544
1544
*/
1545
1545
bool create_table(Session *session,
1546
 
                        const TableIdentifier &identifier,
 
1546
                        const identifier::Table &identifier,
1547
1547
                        HA_CREATE_INFO *create_info,
1548
1548
                        message::Table &table_proto,
1549
1549
                        AlterInfo *alter_info,
1639
1639
bool
1640
1640
rename_table(Session &session,
1641
1641
                   plugin::StorageEngine *base,
1642
 
                   const TableIdentifier &from,
1643
 
                   const TableIdentifier &to)
 
1642
                   const identifier::Table &from,
 
1643
                   const identifier::Table &to)
1644
1644
{
1645
1645
  int error= 0;
1646
1646
 
1706
1706
  session->abortLock(table);    /* end threads waiting on lock */
1707
1707
 
1708
1708
  /* Wait until all there are no other threads that has this table open */
1709
 
  TableIdentifier identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName());
 
1709
  identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName());
1710
1710
  table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG);
1711
1711
}
1712
1712
 
1857
1857
      const char *old_message=session->enter_cond(COND_refresh, table::Cache::singleton().mutex(),
1858
1858
                                                  "Waiting to get writelock");
1859
1859
      session->abortLock(table->table);
1860
 
      TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
 
1860
      identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1861
1861
      table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
1862
1862
      session->exit_cond(old_message);
1863
1863
      if (session->getKilled())
1959
1959
        else
1960
1960
        {
1961
1961
          boost::unique_lock<boost::mutex> lock(table::Cache::singleton().mutex());
1962
 
          TableIdentifier identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
 
1962
          identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1963
1963
          table::Cache::singleton().removeTable(session, identifier, RTFC_NO_FLAG);
1964
1964
        }
1965
1965
      }
1999
1999
    during the call to plugin::StorageEngine::createTable().
2000
2000
    See bug #28614 for more info.
2001
2001
  */
2002
 
static bool create_table_wrapper(Session &session, const message::Table& create_table_proto,
2003
 
                                 const TableIdentifier &destination_identifier,
2004
 
                                 const TableIdentifier &src_table,
 
2002
static bool create_table_wrapper(Session &session,
 
2003
                                 const message::Table& create_table_proto,
 
2004
                                 identifier::Table::const_reference destination_identifier,
 
2005
                                 identifier::Table::const_reference source_identifier,
2005
2006
                                 bool is_engine_set)
2006
2007
{
2007
 
  int protoerr;
2008
 
  message::Table new_proto;
2009
 
  message::table::shared_ptr src_proto;
2010
 
 
2011
 
  protoerr= plugin::StorageEngine::getTableDefinition(session,
2012
 
                                                      src_table,
2013
 
                                                      src_proto);
2014
 
  new_proto.CopyFrom(*src_proto);
 
2008
  // We require an additional table message because during parsing we used
 
2009
  // a "new" message and it will not have all of the information that the
 
2010
  // source table message would have.
 
2011
  message::Table new_table_message;
 
2012
  drizzled::error_t error;
 
2013
 
 
2014
  message::table::shared_ptr source_table_message= plugin::StorageEngine::getTableMessage(session, source_identifier, error);
 
2015
 
 
2016
  if (not source_table_message)
 
2017
  {
 
2018
    my_error(ER_TABLE_UNKNOWN, source_identifier);
 
2019
    return false;
 
2020
  }
 
2021
 
 
2022
  new_table_message.CopyFrom(*source_table_message);
2015
2023
 
2016
2024
  if (destination_identifier.isTmp())
2017
2025
  {
2018
 
    new_proto.set_type(message::Table::TEMPORARY);
 
2026
    new_table_message.set_type(message::Table::TEMPORARY);
2019
2027
  }
2020
2028
  else
2021
2029
  {
2022
 
    new_proto.set_type(message::Table::STANDARD);
 
2030
    new_table_message.set_type(message::Table::STANDARD);
2023
2031
  }
2024
2032
 
2025
2033
  if (is_engine_set)
2026
2034
  {
2027
 
    new_proto.mutable_engine()->set_name(create_table_proto.engine().name());
 
2035
    new_table_message.mutable_engine()->set_name(create_table_proto.engine().name());
2028
2036
  }
2029
2037
 
2030
2038
  { // We now do a selective copy of elements on to the new table.
2031
 
    new_proto.set_name(create_table_proto.name());
2032
 
    new_proto.set_schema(create_table_proto.schema());
2033
 
    new_proto.set_catalog(create_table_proto.catalog());
 
2039
    new_table_message.set_name(create_table_proto.name());
 
2040
    new_table_message.set_schema(create_table_proto.schema());
 
2041
    new_table_message.set_catalog(create_table_proto.catalog());
2034
2042
  }
2035
2043
 
2036
 
  if (protoerr && protoerr != EEXIST)
 
2044
  /* Fix names of foreign keys being added */
 
2045
  for (int32_t j= 0; j < new_table_message.fk_constraint_size(); j++)
2037
2046
  {
2038
 
    if (errno == ENOENT)
2039
 
      my_error(ER_BAD_DB_ERROR,MYF(0), destination_identifier.getSchemaName().c_str());
2040
 
    else
2041
 
      my_error(ER_CANT_CREATE_FILE, MYF(0), destination_identifier.getPath().c_str(), errno);
2042
 
 
2043
 
    return false;
 
2047
    if (new_table_message.fk_constraint(j).has_name())
 
2048
    {
 
2049
      std::string name(new_table_message.name());
 
2050
      char number[20];
 
2051
 
 
2052
      name.append("_ibfk_");
 
2053
      snprintf(number, sizeof(number), "%d", j+1);
 
2054
      name.append(number);
 
2055
 
 
2056
      message::Table::ForeignKeyConstraint *pfkey= new_table_message.mutable_fk_constraint(j);
 
2057
      pfkey->set_name(name);
 
2058
    }
2044
2059
  }
2045
2060
 
2046
2061
  /*
2049
2064
  */
2050
2065
  bool success= plugin::StorageEngine::createTable(session,
2051
2066
                                                   destination_identifier,
2052
 
                                                   new_proto);
 
2067
                                                   new_table_message);
2053
2068
 
2054
2069
  if (success && not destination_identifier.isTmp())
2055
2070
  {
2056
2071
    TransactionServices &transaction_services= TransactionServices::singleton();
2057
 
    transaction_services.createTable(&session, new_proto);
 
2072
    transaction_services.createTable(&session, new_table_message);
2058
2073
  }
2059
2074
 
2060
2075
  return success;
2076
2091
*/
2077
2092
 
2078
2093
bool create_like_table(Session* session,
2079
 
                       const TableIdentifier &destination_identifier,
2080
 
                       TableList* table, TableList* src_table,
 
2094
                       identifier::Table::const_reference destination_identifier,
 
2095
                       identifier::Table::const_reference source_identifier,
2081
2096
                       message::Table &create_table_proto,
2082
2097
                       bool is_if_not_exists,
2083
2098
                       bool is_engine_set)
2084
2099
{
2085
2100
  bool res= true;
2086
 
  uint32_t not_used;
2087
 
 
2088
 
  /*
2089
 
    By opening source table we guarantee that it exists and no concurrent
2090
 
    DDL operation will mess with it. Later we also take an exclusive
2091
 
    name-lock on target table name, which makes copying of .frm cursor,
2092
 
    call to plugin::StorageEngine::createTable() and binlogging atomic
2093
 
    against concurrent DML and DDL operations on target table.
2094
 
    Thus by holding both these "locks" we ensure that our statement is
2095
 
    properly isolated from all concurrent operations which matter.
2096
 
  */
2097
 
  if (session->open_tables_from_list(&src_table, &not_used))
2098
 
    return true;
2099
 
 
2100
 
  TableIdentifier src_identifier(src_table->table->getShare()->getSchemaName(),
2101
 
                                 src_table->table->getShare()->getTableName(), src_table->table->getShare()->getType());
2102
 
 
2103
 
 
 
2101
  bool table_exists= false;
2104
2102
 
2105
2103
  /*
2106
2104
    Check that destination tables does not exist. Note that its name
2108
2106
 
2109
2107
    For temporary tables we don't aim to grab locks.
2110
2108
  */
2111
 
  bool table_exists= false;
2112
2109
  if (destination_identifier.isTmp())
2113
2110
  {
2114
2111
    if (session->find_temporary_table(destination_identifier))
2117
2114
    }
2118
2115
    else
2119
2116
    {
2120
 
      bool was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2121
 
                                             src_identifier, is_engine_set);
 
2117
      bool was_created= create_table_wrapper(*session,
 
2118
                                             create_table_proto,
 
2119
                                             destination_identifier,
 
2120
                                             source_identifier,
 
2121
                                             is_engine_set);
2122
2122
      if (not was_created) // This is pretty paranoid, but we assume something might not clean up after itself
2123
2123
      {
2124
2124
        (void) session->rm_temporary_table(destination_identifier, true);
2163
2163
      {
2164
2164
        boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* We lock for CREATE TABLE LIKE to copy table definition */
2165
2165
        was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2166
 
                                               src_identifier, is_engine_set);
 
2166
                                          source_identifier, is_engine_set);
2167
2167
      }
2168
2168
 
2169
2169
      // So we blew the creation of the table, and we scramble to clean up
2191
2191
    {
2192
2192
      char warn_buff[DRIZZLE_ERRMSG_SIZE];
2193
2193
      snprintf(warn_buff, sizeof(warn_buff),
2194
 
               ER(ER_TABLE_EXISTS_ERROR), table->getTableName());
 
2194
               ER(ER_TABLE_EXISTS_ERROR), destination_identifier.getTableName().c_str());
2195
2195
      push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2196
 
                   ER_TABLE_EXISTS_ERROR,warn_buff);
2197
 
      res= false;
2198
 
    }
2199
 
    else
2200
 
    {
2201
 
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table->getTableName());
2202
 
    }
 
2196
                   ER_TABLE_EXISTS_ERROR, warn_buff);
 
2197
      return false;
 
2198
    }
 
2199
 
 
2200
    my_error(ER_TABLE_EXISTS_ERROR, destination_identifier);
 
2201
 
 
2202
    return true;
2203
2203
  }
2204
2204
 
2205
 
  return(res);
 
2205
  return res;
2206
2206
}
2207
2207
 
2208
2208