sql_table.cc
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:49k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /* drop and alter of tables */
  14. #include "mysql_priv.h"
  15. #include <hash.h>
  16. #include <myisam.h>
  17. #ifdef __WIN__
  18. #include <io.h>
  19. #endif
  20. extern HASH open_cache;
  21. static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
  22. static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
  23. static int copy_data_between_tables(TABLE *from,TABLE *to,
  24.     List<create_field> &create,
  25.     enum enum_duplicates handle_duplicates,
  26.                                     ORDER *order,
  27.     ha_rows *copied,ha_rows *deleted);
  28. /*****************************************************************************
  29. ** Remove all possbile tables and give a compact errormessage for all
  30. ** wrong tables.
  31. ** This will wait for all users to free the table before dropping it
  32. *****************************************************************************/
  33. int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
  34. {
  35.   char path[FN_REFLEN];
  36.   String wrong_tables;
  37.   bool some_tables_deleted=0;
  38.   uint error;
  39.   db_type table_type;
  40.   TABLE_LIST *table;
  41.   DBUG_ENTER("mysql_rm_table");
  42.   /* mark for close and remove all cached entries */
  43.   pthread_mutex_lock(&thd->mysys_var->mutex);
  44.   thd->mysys_var->current_mutex= &LOCK_open;
  45.   thd->mysys_var->current_cond= &COND_refresh;
  46.   VOID(pthread_mutex_lock(&LOCK_open));
  47.   pthread_mutex_unlock(&thd->mysys_var->mutex);
  48.   if(global_read_lock)
  49.   {
  50.     if(thd->global_read_lock)
  51.     {
  52.       my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0),
  53.        tables->real_name);
  54.       error = 1;
  55.       goto err;
  56.     }
  57.     while (global_read_lock && ! thd->killed)
  58.     {
  59.       (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
  60.     }
  61.   }
  62.   
  63.   for (table=tables ; table ; table=table->next)
  64.   {
  65.     char *db=table->db ? table->db : thd->db;
  66.     if (!close_temporary_table(thd, db, table->real_name))
  67.     {
  68.       some_tables_deleted=1; // Log query
  69.       continue; // removed temporary table
  70.     }
  71.     abort_locked_tables(thd,db,table->real_name);
  72.     while (remove_table_from_cache(thd,db,table->real_name) && !thd->killed)
  73.     {
  74.       dropping_tables++;
  75.       (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
  76.       dropping_tables--;
  77.     }
  78.     drop_locked_tables(thd,db,table->real_name);
  79.     if (thd->killed)
  80.     {
  81.       VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
  82.       VOID(pthread_mutex_unlock(&LOCK_open));
  83.       pthread_mutex_lock(&thd->mysys_var->mutex);
  84.       thd->mysys_var->current_mutex= 0;
  85.       thd->mysys_var->current_cond= 0;
  86.       pthread_mutex_unlock(&thd->mysys_var->mutex);
  87.       DBUG_RETURN(-1);
  88.     }
  89.     /* remove form file and isam files */
  90.     (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,table->real_name,
  91.    reg_ext);
  92.     (void) unpack_filename(path,path);
  93.     error=0;
  94.     table_type=get_table_type(path);
  95.     if (access(path,F_OK))
  96.     {
  97.       if (!if_exists)
  98. error=1;
  99.     }
  100.     else
  101.     {
  102.       char *end;
  103.       *(end=fn_ext(path))=0; // Remove extension
  104.       error=ha_delete_table(table_type, path);
  105.       if (error == ENOENT && if_exists)
  106. error = 0;
  107.       if (!error || error == ENOENT)
  108.       {
  109. /* Delete the table definition file */
  110. strmov(end,reg_ext);
  111. if (!(error=my_delete(path,MYF(MY_WME))))
  112.   some_tables_deleted=1;
  113.       }
  114.     }
  115.     if (error)
  116.     {
  117.       if (wrong_tables.length())
  118. wrong_tables.append(',');
  119.       wrong_tables.append(String(table->real_name));
  120.     }
  121.   }
  122.   if (some_tables_deleted)
  123.   {
  124.     mysql_update_log.write(thd, thd->query,thd->query_length);
  125.     if (mysql_bin_log.is_open())
  126.     {
  127.       Query_log_event qinfo(thd, thd->query);
  128.       mysql_bin_log.write(&qinfo);
  129.     }
  130.   }
  131.   
  132.   error = 0;
  133.  err:  
  134.   VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
  135.   pthread_mutex_unlock(&LOCK_open);
  136.   pthread_mutex_lock(&thd->mysys_var->mutex);
  137.   thd->mysys_var->current_mutex= 0;
  138.   thd->mysys_var->current_cond= 0;
  139.   pthread_mutex_unlock(&thd->mysys_var->mutex);
  140.   if (wrong_tables.length())
  141.   {
  142.     my_error(ER_BAD_TABLE_ERROR,MYF(0),wrong_tables.c_ptr());
  143.     error=1;
  144.   }
  145.   if(error)
  146.     DBUG_RETURN(-1);
  147.   send_ok(&thd->net);
  148.   DBUG_RETURN(0);
  149. }
  150. int quick_rm_table(enum db_type base,const char *db,
  151.    const char *table_name)
  152. {
  153.   char path[FN_REFLEN];
  154.   int error=0;
  155.   (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,table_name,reg_ext);
  156.   unpack_filename(path,path);
  157.   if (my_delete(path,MYF(0)))
  158.     error=1; /* purecov: inspected */
  159.   sprintf(path,"%s/%s/%s",mysql_data_home,db,table_name);
  160.   unpack_filename(path,path);
  161.   return ha_delete_table(base,path) || error;
  162. }
  163. /*****************************************************************************
  164.  * Create at table.
  165.  * If one creates a temporary table, this is automaticly opened
  166.  ****************************************************************************/
  167. int mysql_create_table(THD *thd,const char *db, const char *table_name,
  168.        HA_CREATE_INFO *create_info,
  169.        List<create_field> &fields,
  170.        List<Key> &keys,bool tmp_table,bool no_log)
  171. {
  172.   char path[FN_REFLEN];
  173.   const char *key_name;
  174.   create_field *sql_field,*dup_field;
  175.   int error= -1;
  176.   uint db_options,field,null_fields,blob_columns;
  177.   ulong pos;
  178.   KEY *key_info,*key_info_buffer;
  179.   KEY_PART_INFO *key_part_info;
  180.   int auto_increment=0;
  181.   handler *file;
  182.   DBUG_ENTER("mysql_create_table");
  183.   /*
  184.   ** Check for duplicate fields and check type of table to create
  185.   */
  186.   if (!fields.elements)
  187.   {
  188.     my_error(ER_TABLE_MUST_HAVE_COLUMNS,MYF(0));
  189.     DBUG_RETURN(-1);
  190.   }
  191.   List_iterator<create_field> it(fields),it2(fields);
  192.   null_fields=blob_columns=0;
  193.   db_options=create_info->table_options;
  194.   if (create_info->row_type == ROW_TYPE_DYNAMIC)
  195.     db_options|=HA_OPTION_PACK_RECORD;
  196.   file=get_new_handler((TABLE*) 0, create_info->db_type);
  197.   /* Don't pack keys in old tables if the user has requested this */
  198.   while ((sql_field=it++))
  199.   {
  200.     if ((sql_field->flags & BLOB_FLAG) ||
  201. sql_field->sql_type == FIELD_TYPE_VAR_STRING &&
  202. create_info->row_type != ROW_TYPE_FIXED)
  203.     {
  204.       db_options|=HA_OPTION_PACK_RECORD;
  205.     }
  206.     if (!(sql_field->flags & NOT_NULL_FLAG))
  207.       null_fields++;
  208.     while ((dup_field=it2++) != sql_field)
  209.     {
  210.       if (my_strcasecmp(sql_field->field_name, dup_field->field_name) == 0)
  211.       {
  212. my_error(ER_DUP_FIELDNAME,MYF(0),sql_field->field_name);
  213. DBUG_RETURN(-1);
  214.       }
  215.     }
  216.     it2.rewind();
  217.   }
  218.   /* If fixed row records, we need on bit to check for deleted rows */
  219.   if (!(db_options & HA_OPTION_PACK_RECORD))
  220.     null_fields++;
  221.   pos=(null_fields+7)/8;
  222.   it.rewind();
  223.   while ((sql_field=it++))
  224.   {
  225.     switch (sql_field->sql_type) {
  226.     case FIELD_TYPE_BLOB:
  227.     case FIELD_TYPE_MEDIUM_BLOB:
  228.     case FIELD_TYPE_TINY_BLOB:
  229.     case FIELD_TYPE_LONG_BLOB:
  230.       sql_field->pack_flag=FIELDFLAG_BLOB |
  231. pack_length_to_packflag(sql_field->pack_length -
  232. portable_sizeof_char_ptr);
  233.       if (sql_field->flags & BINARY_FLAG)
  234. sql_field->pack_flag|=FIELDFLAG_BINARY;
  235.       sql_field->length=8; // Unireg field length
  236.       sql_field->unireg_check=Field::BLOB_FIELD;
  237.       blob_columns++;
  238.       break;
  239.     case FIELD_TYPE_VAR_STRING:
  240.     case FIELD_TYPE_STRING:
  241.       sql_field->pack_flag=0;
  242.       if (sql_field->flags & BINARY_FLAG)
  243. sql_field->pack_flag|=FIELDFLAG_BINARY;
  244.       break;
  245.     case FIELD_TYPE_ENUM:
  246.       sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
  247. FIELDFLAG_INTERVAL;
  248.       sql_field->unireg_check=Field::INTERVAL_FIELD;
  249.       break;
  250.     case FIELD_TYPE_SET:
  251.       sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
  252. FIELDFLAG_BITFIELD;
  253.       sql_field->unireg_check=Field::BIT_FIELD;
  254.       break;
  255.     case FIELD_TYPE_DATE: // Rest of string types
  256.     case FIELD_TYPE_NEWDATE:
  257.     case FIELD_TYPE_TIME:
  258.     case FIELD_TYPE_DATETIME:
  259.     case FIELD_TYPE_NULL:
  260.       sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
  261.       break;
  262.     case FIELD_TYPE_TIMESTAMP:
  263.       sql_field->unireg_check=Field::TIMESTAMP_FIELD;
  264.       /* fall through */
  265.     default:
  266.       sql_field->pack_flag=(FIELDFLAG_NUMBER |
  267.     (sql_field->flags & UNSIGNED_FLAG ? 0 :
  268.      FIELDFLAG_DECIMAL) |
  269.     (sql_field->flags & ZEROFILL_FLAG ?
  270.      FIELDFLAG_ZEROFILL : 0) |
  271.     f_settype((uint) sql_field->sql_type) |
  272.     (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
  273.       break;
  274.     }
  275.     if (!(sql_field->flags & NOT_NULL_FLAG))
  276.       sql_field->pack_flag|=FIELDFLAG_MAYBE_NULL;
  277.     sql_field->offset= pos;
  278.     if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
  279.       auto_increment++;
  280.     pos+=sql_field->pack_length;
  281.   }
  282.   if (auto_increment > 1)
  283.   {
  284.     my_error(ER_WRONG_AUTO_KEY,MYF(0));
  285.     DBUG_RETURN(-1);
  286.   }
  287.   if (auto_increment &&
  288.       (file->option_flag() & HA_WRONG_ASCII_ORDER))
  289.   {
  290.     my_error(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,MYF(0));
  291.     DBUG_RETURN(-1);
  292.   }
  293.   if (blob_columns && (file->option_flag() & HA_NO_BLOBS))
  294.   {
  295.     my_error(ER_TABLE_CANT_HANDLE_BLOB,MYF(0));
  296.     DBUG_RETURN(-1);
  297.   }
  298.   /* Create keys */
  299.   List_iterator<Key> key_iterator(keys);
  300.   uint key_parts=0,key_count=keys.elements;
  301.   List<Key> keys_in_order; // Add new keys here
  302.   Key *primary_key=0;
  303.   bool unique_key=0;
  304.   Key *key;
  305.   uint tmp;
  306.   tmp=min(file->max_keys(), MAX_KEY);
  307.   if (key_count > tmp)
  308.   {
  309.     my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
  310.     DBUG_RETURN(-1);
  311.   }
  312.   /*
  313.     Check keys;
  314.     Put PRIMARY KEY first, then UNIQUE keys and other keys last
  315.     This will make checking for duplicated keys faster and ensure that
  316.     primary keys are prioritized.
  317.   */
  318.   while ((key=key_iterator++))
  319.   {
  320.     tmp=max(file->max_key_parts(),MAX_REF_PARTS);
  321.     if (key->columns.elements > tmp)
  322.     {
  323.       my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
  324.       DBUG_RETURN(-1);
  325.     }
  326.     if (key->name() && strlen(key->name()) > NAME_LEN)
  327.     {
  328.       my_error(ER_TOO_LONG_IDENT, MYF(0), key->name());
  329.       DBUG_RETURN(-1);
  330.     }
  331.     key_parts+=key->columns.elements;
  332.     if (key->type == Key::PRIMARY)
  333.     {
  334.       if (primary_key)
  335.       {
  336. my_error(ER_MULTIPLE_PRI_KEY,MYF(0));
  337. DBUG_RETURN(-1);
  338.       }
  339.       primary_key=key;
  340.     }
  341.     else if (key->type == Key::UNIQUE)
  342.     {
  343.       unique_key=1;
  344.       if (keys_in_order.push_front(key))
  345. DBUG_RETURN(-1);
  346.     }
  347.     else if (keys_in_order.push_back(key))
  348.       DBUG_RETURN(-1);
  349.   }
  350.   if (primary_key)
  351.   {
  352.     if (keys_in_order.push_front(primary_key))
  353.       DBUG_RETURN(-1);
  354.   }
  355.   else if (!unique_key && (file->option_flag() & HA_REQUIRE_PRIMARY_KEY))
  356.   {
  357.     my_error(ER_REQUIRES_PRIMARY_KEY,MYF(0));
  358.     DBUG_RETURN(-1);
  359.   }
  360.   key_info_buffer=key_info=(KEY*) sql_calloc(sizeof(KEY)*key_count);
  361.   key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts);
  362.   if (!key_info_buffer || ! key_part_info)
  363.     DBUG_RETURN(-1); // Out of memory
  364.   List_iterator<Key> key_iterator_in_order(keys_in_order);
  365.   for (; (key=key_iterator_in_order++) ; key_info++)
  366.   {
  367.     uint key_length=0;
  368.     key_part_spec *column;
  369.     key_info->flags= (key->type == Key::MULTIPLE) ? 0 :
  370.                      (key->type == Key::FULLTEXT) ? HA_FULLTEXT : HA_NOSAME;
  371.     key_info->key_parts=(uint8) key->columns.elements;
  372.     key_info->key_part=key_part_info;
  373.     List_iterator<key_part_spec> cols(key->columns);
  374.     for (uint column_nr=0 ; (column=cols++) ; column_nr++)
  375.     {
  376.       it.rewind();
  377.       field=0;
  378.       while ((sql_field=it++) &&
  379.      my_strcasecmp(column->field_name,sql_field->field_name))
  380. field++;
  381.       if (!sql_field)
  382.       {
  383. my_printf_error(ER_KEY_COLUMN_DOES_NOT_EXITS,
  384. ER(ER_KEY_COLUMN_DOES_NOT_EXITS),MYF(0),
  385. column->field_name);
  386. DBUG_RETURN(-1);
  387.       }
  388.       if (f_is_blob(sql_field->pack_flag))
  389.       {
  390. if (!(file->option_flag() & HA_BLOB_KEY))
  391. {
  392.   my_printf_error(ER_BLOB_USED_AS_KEY,ER(ER_BLOB_USED_AS_KEY),MYF(0),
  393.   column->field_name);
  394.   DBUG_RETURN(-1);
  395. }
  396. if (!column->length)
  397. {
  398.           if (key->type == Key::FULLTEXT)
  399.             column->length=1; /* ft-code ignores it anyway :-) */
  400.           else
  401.           {
  402.     my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH,
  403.     ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0),
  404.     column->field_name);
  405.     DBUG_RETURN(-1);
  406.           }
  407. }
  408.       }
  409.       if (!(sql_field->flags & NOT_NULL_FLAG))
  410.       {
  411. if (key->type == Key::PRIMARY)
  412. {
  413.   my_error(ER_PRIMARY_CANT_HAVE_NULL, MYF(0));
  414.   DBUG_RETURN(-1);
  415. }
  416. if (!(file->option_flag() & HA_NULL_KEY))
  417. {
  418.   my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX),
  419.   MYF(0),column->field_name);
  420.   DBUG_RETURN(-1);
  421. }
  422.       }
  423.       if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
  424.       {
  425. if (column_nr == 0 || (file->option_flag() & HA_AUTO_PART_KEY))
  426.   auto_increment--; // Field is used
  427.       }
  428.       key_part_info->fieldnr= field;
  429.       key_part_info->offset=  (uint16) sql_field->offset;
  430.       key_part_info->key_type=sql_field->pack_flag;
  431.       uint length=sql_field->pack_length;
  432.       if (column->length)
  433.       {
  434. if (f_is_blob(sql_field->pack_flag))
  435. {
  436.   if ((length=column->length) > file->max_key_length() ||
  437.       length > file->max_key_part_length())
  438.   {
  439.     my_error(ER_WRONG_SUB_KEY,MYF(0));
  440.     DBUG_RETURN(-1);
  441.   }
  442. }
  443. else if (column->length > length ||
  444.     (f_is_packed(sql_field->pack_flag) && column->length != length))
  445. {
  446.   my_error(ER_WRONG_SUB_KEY,MYF(0));
  447.   DBUG_RETURN(-1);
  448. }
  449. length=column->length;
  450.       }
  451.       else if (length == 0)
  452.       {
  453. my_printf_error(ER_WRONG_KEY_COLUMN, ER(ER_WRONG_KEY_COLUMN), MYF(0),
  454. column->field_name);
  455.   DBUG_RETURN(-1);
  456.       }
  457.       key_part_info->length=(uint8) length;
  458.       /* Use packed keys for long strings on the first column */
  459.       if (!(db_options & HA_OPTION_NO_PACK_KEYS) &&
  460.   (length >= KEY_DEFAULT_PACK_LENGTH &&
  461.    (sql_field->sql_type == FIELD_TYPE_STRING ||
  462.     sql_field->sql_type == FIELD_TYPE_VAR_STRING ||
  463.     sql_field->pack_flag & FIELDFLAG_BLOB)))
  464.       {
  465. if (column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB))
  466.   key_info->flags|= HA_BINARY_PACK_KEY;
  467. else
  468.   key_info->flags|= HA_PACK_KEY;
  469.       }
  470.       key_length+=length;
  471.       key_part_info++;
  472.       /* Create the key name based on the first column (if not given) */
  473.       if (column_nr == 0)
  474.       {
  475. if (key->type == Key::PRIMARY)
  476.   key_name="PRIMARY";
  477. else if (!(key_name = key->name()))
  478.   key_name=make_unique_key_name(sql_field->field_name,
  479. key_info_buffer,key_info);
  480. if (check_if_keyname_exists(key_name,key_info_buffer,key_info))
  481. {
  482.   my_error(ER_DUP_KEYNAME,MYF(0),key_name);
  483.   DBUG_RETURN(-1);
  484. }
  485. key_info->name=(char*) key_name;
  486.       }
  487.     }
  488.     key_info->key_length=(uint16) key_length;
  489.     if (key_length > file->max_key_length() && key->type != Key::FULLTEXT)
  490.     {
  491.       my_error(ER_TOO_LONG_KEY,MYF(0),file->max_key_length());
  492.       DBUG_RETURN(-1);
  493.     }
  494.   }
  495.   if (auto_increment > 0)
  496.   {
  497.     my_error(ER_WRONG_AUTO_KEY,MYF(0));
  498.     DBUG_RETURN(-1);
  499.   }
  500.       /* Check if table exists */
  501.   if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
  502.   {
  503.     sprintf(path,"%s%s%lx_%lx_%x%s",mysql_tmpdir,tmp_file_prefix,
  504.     current_pid, thd->thread_id, thd->tmp_table++,reg_ext);
  505.     create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
  506.   }
  507.   else
  508.     (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,table_name,reg_ext);
  509.   unpack_filename(path,path);
  510.   /* Check if table already exists */
  511.   if ((create_info->options & HA_LEX_CREATE_TMP_TABLE)
  512.       && find_temporary_table(thd,db,table_name))
  513.   {
  514.     if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
  515.       DBUG_RETURN(0);
  516.     my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
  517.     DBUG_RETURN(-1);
  518.   }
  519.   VOID(pthread_mutex_lock(&LOCK_open));
  520.   if (!tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
  521.   {
  522.     if (!access(path,F_OK))
  523.     {
  524.       VOID(pthread_mutex_unlock(&LOCK_open));
  525.       if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
  526. DBUG_RETURN(0);
  527.       my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
  528.       DBUG_RETURN(-1);
  529.     }
  530.   }
  531.   thd->proc_info="creating table";
  532.   create_info->table_options=db_options;
  533.   if (rea_create_table(path, create_info, fields, key_count,
  534.        key_info_buffer))
  535.   {
  536.     /* my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,my_errno); */
  537.     goto end;
  538.   }
  539.   if (!tmp_table && !no_log)
  540.   {
  541.     // Must be written before unlock
  542.     mysql_update_log.write(thd,thd->query, thd->query_length);
  543.     if (mysql_bin_log.is_open())
  544.     {
  545.       Query_log_event qinfo(thd, thd->query);
  546.       mysql_bin_log.write(&qinfo);
  547.     }
  548.   }
  549.   if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
  550.   {
  551.     /* Open table and put in temporary table list */
  552.     if (!(open_temporary_table(thd, path, db, table_name, 1)))
  553.     {
  554.       (void) rm_temporary_table(create_info->db_type, path);
  555.       goto end;
  556.     }
  557.   }
  558.   error=0;
  559. end:
  560.   VOID(pthread_mutex_unlock(&LOCK_open));
  561.   thd->proc_info="After create";
  562.   DBUG_RETURN(error);
  563. }
  564. /*
  565. ** Give the key name after the first field with an optional '_#' after
  566. **/
  567. static bool
  568. check_if_keyname_exists(const char *name, KEY *start, KEY *end)
  569. {
  570.   for (KEY *key=start ; key != end ; key++)
  571.     if (!my_strcasecmp(name,key->name))
  572.       return 1;
  573.   return 0;
  574. }
  575. static char *
  576. make_unique_key_name(const char *field_name,KEY *start,KEY *end)
  577. {
  578.   char buff[MAX_FIELD_NAME],*buff_end;
  579.   if (!check_if_keyname_exists(field_name,start,end))
  580.     return (char*) field_name; // Use fieldname
  581.   buff_end=strmake(buff,field_name,MAX_FIELD_NAME-4);
  582.   for (uint i=2 ; ; i++)
  583.   {
  584.     sprintf(buff_end,"_%d",i);
  585.     if (!check_if_keyname_exists(buff,start,end))
  586.       return sql_strdup(buff);
  587.   }
  588. }
  589. /****************************************************************************
  590. ** Create table from a list of fields and items
  591. ****************************************************************************/
  592. TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
  593.        const char *db, const char *name,
  594.        List<create_field> *extra_fields,
  595.        List<Key> *keys,
  596.        List<Item> *items,
  597.        MYSQL_LOCK **lock)
  598. {
  599.   TABLE tmp_table; // Used during 'create_field()'
  600.   TABLE *table;
  601.   tmp_table.table_name=0;
  602.   DBUG_ENTER("create_table_from_items");
  603.   /* Add selected items to field list */
  604.   List_iterator<Item> it(*items);
  605.   Item *item;
  606.   Field *tmp_field;
  607.   tmp_table.db_create_options=0;
  608.   tmp_table.null_row=tmp_table.maybe_null=0;
  609.   tmp_table.blob_ptr_size=portable_sizeof_char_ptr;
  610.   tmp_table.db_low_byte_first= test(create_info->db_type == DB_TYPE_MYISAM ||
  611.     create_info->db_type == DB_TYPE_HEAP);
  612.   while ((item=it++))
  613.   {
  614.     create_field *cr_field;
  615.     if (strlen(item->name) > NAME_LEN ||
  616. check_column_name(item->name))
  617.     {
  618.       my_error(ER_WRONG_COLUMN_NAME,MYF(0),item->name);
  619.       DBUG_RETURN(0);
  620.     }
  621.     Field *field=create_tmp_field(&tmp_table,item,item->type(),
  622.   (Item_result_field***) 0, &tmp_field,0,0);
  623.     if (!field ||
  624. !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
  625.    ((Item_field *)item)->field :
  626.    (Field*) 0))))
  627.       DBUG_RETURN(0);
  628.     extra_fields->push_back(cr_field);
  629.   }
  630.   /* create and lock table */
  631.   /* QQ: This should be done atomic ! */
  632.   if (mysql_create_table(thd,db,name,create_info,*extra_fields,
  633.  *keys,0,1)) // no logging
  634.     DBUG_RETURN(0);
  635.   if (!(table=open_table(thd,db,name,name,(bool*) 0)))
  636.   {
  637.     quick_rm_table(create_info->db_type,db,name);
  638.     DBUG_RETURN(0);
  639.   }
  640.   table->reginfo.lock_type=TL_WRITE;
  641.   if (!((*lock)=mysql_lock_tables(thd,&table,1)))
  642.   {
  643.     hash_delete(&open_cache,(byte*) table);
  644.     quick_rm_table(create_info->db_type,db,name);
  645.     DBUG_RETURN(0);
  646.   }
  647.   table->file->extra(HA_EXTRA_WRITE_CACHE);
  648.   DBUG_RETURN(table);
  649. }
  650. /****************************************************************************
  651. ** Alter a table definition
  652. ****************************************************************************/
  653. bool
  654. mysql_rename_table(enum db_type base,
  655.    const char *old_db,
  656.    const char * old_name,
  657.    const char *new_db,
  658.    const char * new_name)
  659. {
  660.   char from[FN_REFLEN],to[FN_REFLEN];
  661.   handler *file=get_new_handler((TABLE*) 0, base);
  662.   int error=0;
  663.   DBUG_ENTER("mysql_rename_table");
  664.   (void) sprintf(from,"%s/%s/%s",mysql_data_home,old_db,old_name);
  665.   (void) sprintf(to,"%s/%s/%s",mysql_data_home,new_db,new_name);
  666.   fn_format(from,from,"","",4);
  667.   fn_format(to,to,    "","",4);
  668.   if (!(error=file->rename_table((const char*) from,(const char *) to)))
  669.   {
  670.     if (rename_file_ext(from,to,reg_ext))
  671.     {
  672.       error=my_errno;
  673.       /* Restore old file name */
  674.       file->rename_table((const char*) to,(const char *) from);
  675.     }
  676.   }
  677.   delete file;
  678.   if (error)
  679.     my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error);
  680.   DBUG_RETURN(error != 0);
  681. }
  682. /*
  683.   close table in this thread and force close + reopen in other threads
  684.   This assumes that the calling thread has lock on LOCK_open
  685.   Win32 clients must also have a WRITE LOCK on the table !
  686. */
  687. bool close_cached_table(THD *thd,TABLE *table)
  688. {
  689.   bool result=0;
  690.   DBUG_ENTER("close_cached_table");
  691.   if (table)
  692.   {
  693.     DBUG_PRINT("enter",("table: %s", table->table_name));
  694.     VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Close all data files
  695.     /* Mark all tables that are in use as 'old' */
  696.     mysql_lock_abort(thd,table);  // end threads waiting on lock
  697. #ifdef REMOVE_LOCKS
  698.     /* Wait until all there are no other threads that has this table open */
  699.     while (remove_table_from_cache(thd,table->table_cache_key,
  700.    table->table_name))
  701.     {
  702.       dropping_tables++;
  703.       (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
  704.       dropping_tables--;
  705.     }
  706. #else
  707.     (void) remove_table_from_cache(thd,table->table_cache_key,
  708.    table->table_name);
  709. #endif
  710.     /* When lock on LOCK_open is freed other threads can continue */
  711.     pthread_cond_broadcast(&COND_refresh);
  712.     /* Close lock if this is not got with LOCK TABLES */
  713.     if (thd->lock)
  714.     {
  715.       mysql_unlock_tables(thd, thd->lock); thd->lock=0; // Start locked threads
  716.     }
  717.     /* Close all copies of 'table'.  This also frees all LOCK TABLES lock */
  718.     thd->open_tables=unlink_open_table(thd,thd->open_tables,table);
  719.   }
  720.   DBUG_RETURN(result);
  721. }
  722. static int send_check_errmsg(THD* thd, TABLE_LIST* table,
  723.      const char* operator_name, const char* errmsg)
  724. {
  725.   String* packet = &thd->packet;
  726.   packet->length(0);
  727.   net_store_data(packet, table->name);
  728.   net_store_data(packet, (char*)operator_name);
  729.   net_store_data(packet, "error");
  730.   net_store_data(packet, errmsg);
  731.   thd->net.last_error[0]=0;
  732.   if (my_net_write(&thd->net, (char*) thd->packet.ptr(),
  733.    packet->length()))
  734.     return -1;
  735.   return 1;
  736. }
  737. static int prepare_for_restore(THD* thd, TABLE_LIST* table)
  738. {
  739.   DBUG_ENTER("prepare_for_restore");
  740.   if (table->table) // do not overwrite existing tables on restore
  741.   {
  742.     DBUG_RETURN(send_check_errmsg(thd, table, "restore",
  743.   "table exists, will not overwrite on restore"
  744.   ));
  745.   }
  746.   else
  747.   {
  748.     char* backup_dir = thd->lex.backup_dir;
  749.     char src_path[FN_REFLEN], dst_path[FN_REFLEN];
  750.     char* table_name = table->name;
  751.     char* db = thd->db ? thd->db : table->db;
  752.     if (!fn_format(src_path, table_name, backup_dir, reg_ext, 4 + 64))
  753.       DBUG_RETURN(-1); // protect buffer overflow
  754.     sprintf(dst_path, "%s/%s/%s", mysql_real_data_home, db, table_name);
  755.     int lock_retcode;
  756.     pthread_mutex_lock(&LOCK_open);
  757.     if((lock_retcode = lock_table_name(thd, table)) < 0)
  758.     {
  759.       pthread_mutex_unlock(&LOCK_open);
  760.       DBUG_RETURN(-1);
  761.     }
  762.     if(lock_retcode && wait_for_locked_table_names(thd, table))
  763.     {
  764.       unlock_table_name(thd, table);
  765.       pthread_mutex_unlock(&LOCK_open);
  766.       DBUG_RETURN(-1);
  767.     }
  768.     pthread_mutex_unlock(&LOCK_open);
  769.     if(my_copy(src_path,
  770.        fn_format(dst_path, dst_path,"",
  771.  reg_ext, 4),
  772.        MYF(MY_WME)))
  773.     {
  774.       unlock_table_name(thd, table);
  775.       DBUG_RETURN(send_check_errmsg(thd, table, "restore",
  776.     "Failed copying .frm file"));
  777.     }
  778.     bool save_no_send_ok = thd->net.no_send_ok;
  779.     thd->net.no_send_ok = 1;
  780.     // generate table will try to send OK which messes up the output
  781.     // for the client
  782.     if(generate_table(thd, table, 0))
  783.     {
  784.       unlock_table_name(thd, table);
  785.       thd->net.no_send_ok = save_no_send_ok;
  786.       DBUG_RETURN(send_check_errmsg(thd, table, "restore",
  787.     "Failed generating table from .frm file"));
  788.     }
  789.     thd->net.no_send_ok = save_no_send_ok;
  790.   }
  791.   DBUG_RETURN(0);
  792. }
  793. static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
  794.      HA_CHECK_OPT* check_opt,
  795.      const char *operator_name,
  796.      thr_lock_type lock_type,
  797.      bool open_for_modify, bool restore,
  798.      uint extra_open_options,
  799.      int (handler::*operator_func)
  800.      (THD *, HA_CHECK_OPT *))
  801. {
  802.   TABLE_LIST *table;
  803.   List<Item> field_list;
  804.   Item* item;
  805.   String* packet = &thd->packet;
  806.   DBUG_ENTER("mysql_admin_table");
  807.   field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
  808.   item->maybe_null = 1;
  809.   field_list.push_back(item = new Item_empty_string("Op", 10));
  810.   item->maybe_null = 1;
  811.   field_list.push_back(item = new Item_empty_string("Msg_type", 10));
  812.   item->maybe_null = 1;
  813.   field_list.push_back(item = new Item_empty_string("Msg_text", 255));
  814.   item->maybe_null = 1;
  815.   if (send_fields(thd, field_list, 1))
  816.     DBUG_RETURN(-1);
  817.   for (table = tables; table; table = table->next)
  818.   {
  819.     char table_name[NAME_LEN*2+2];
  820.     char* db = (table->db) ? table->db : thd->db;
  821.     bool fatal_error=0;
  822.     strxmov(table_name,db ? db : "",".",table->name,NullS);
  823.     thd->open_options|= extra_open_options;
  824.     table->table = open_ltable(thd, table, lock_type);
  825.     thd->open_options&= ~extra_open_options;
  826.     packet->length(0);
  827.     if (restore)
  828.     {
  829.       switch (prepare_for_restore(thd, table)) {
  830.       case 1: continue; // error, message written to net
  831.       case -1: goto err; // error, message could be written to net
  832.       default: ;// should be 0 otherwise
  833.       }
  834.       // now we should be able to open the partially restored table
  835.       // to finish the restore in the handler later on
  836.       if(!(table->table = reopen_name_locked_table(thd, table)))
  837.         unlock_table_name(thd, table);
  838.     }
  839.     if (!table->table)
  840.     {
  841.       const char *err_msg;
  842.       net_store_data(packet, table_name);
  843.       net_store_data(packet, operator_name);
  844.       net_store_data(packet, "error");
  845.       if (!(err_msg=thd->net.last_error))
  846. err_msg=ER(ER_CHECK_NO_SUCH_TABLE);
  847.       net_store_data(packet, err_msg);
  848.       thd->net.last_error[0]=0;
  849.       if (my_net_write(&thd->net, (char*) thd->packet.ptr(),
  850.        packet->length()))
  851. goto err;
  852.       continue;
  853.     }
  854.     if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
  855.     {
  856.       char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
  857.       net_store_data(packet, table_name);
  858.       net_store_data(packet, operator_name);
  859.       net_store_data(packet, "error");
  860.       sprintf(buff, ER(ER_OPEN_AS_READONLY), table_name);
  861.       net_store_data(packet, buff);
  862.       close_thread_tables(thd);
  863.       if (my_net_write(&thd->net, (char*) thd->packet.ptr(),
  864.        packet->length()))
  865. goto err;
  866.       continue;
  867.     }
  868.     /* Close all instances of the table to allow repair to rename files */
  869.     if (open_for_modify && table->table->version)
  870.     {
  871.       pthread_mutex_lock(&LOCK_open);
  872.       mysql_lock_abort(thd,table->table);
  873.       while (remove_table_from_cache(thd, table->table->table_cache_key,
  874.      table->table->real_name) &&
  875.      ! thd->killed)
  876.       {
  877. dropping_tables++;
  878. (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
  879. dropping_tables--;
  880.       }
  881.       pthread_mutex_unlock(&LOCK_open);
  882.       if (thd->killed)
  883. goto err;
  884.     }
  885.     int result_code = (table->table->file->*operator_func)(thd, check_opt);
  886.     packet->length(0);
  887.     net_store_data(packet, table_name);
  888.     net_store_data(packet, operator_name);
  889.     switch (result_code) {
  890.     case HA_ADMIN_NOT_IMPLEMENTED:
  891.       net_store_data(packet, "error");
  892.       net_store_data(packet, ER(ER_CHECK_NOT_IMPLEMENTED));
  893.       break;
  894.     case HA_ADMIN_OK:
  895.       net_store_data(packet, "status");
  896.       net_store_data(packet, "OK");
  897.       break;
  898.     case HA_ADMIN_FAILED:
  899.       net_store_data(packet, "status");
  900.       net_store_data(packet, "Operation failed");
  901.       break;
  902.     case HA_ADMIN_ALREADY_DONE:
  903.       net_store_data(packet, "status");
  904.       net_store_data(packet, "Table is already up to date");
  905.       break;
  906.     case HA_ADMIN_CORRUPT:
  907.       net_store_data(packet, "error");
  908.       net_store_data(packet, "Corrupt");
  909.       fatal_error=1;
  910.       break;
  911.     case HA_ADMIN_INVALID:
  912.       net_store_data(packet, "error");
  913.       net_store_data(packet, "Invalid argument");
  914.       break;
  915.     default: // Probably HA_ADMIN_INTERNAL_ERROR
  916.       net_store_data(packet, "error");
  917.       net_store_data(packet, "Unknown - internal error during operation");
  918.       fatal_error=1;
  919.       break;
  920.     }
  921.     if (fatal_error)
  922.       table->table->version=0; // Force close of table
  923.     close_thread_tables(thd);
  924.     if (my_net_write(&thd->net, (char*) packet->ptr(),
  925.      packet->length()))
  926.       goto err;
  927.   }
  928.   send_eof(&thd->net);
  929.   DBUG_RETURN(0);
  930.  err:
  931.   close_thread_tables(thd); // Shouldn't be needed
  932.   DBUG_RETURN(-1);
  933. }
  934. int mysql_backup_table(THD* thd, TABLE_LIST* table_list)
  935. {
  936.   DBUG_ENTER("mysql_backup_table");
  937.   DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
  938. "backup", TL_READ, 0, 0, 0,
  939. &handler::backup));
  940. }
  941. int mysql_restore_table(THD* thd, TABLE_LIST* table_list)
  942. {
  943.   DBUG_ENTER("mysql_restore_table");
  944.   DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
  945. "restore", TL_WRITE, 1, 1,0,
  946. &handler::restore));
  947. }
  948. int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
  949. {
  950.   DBUG_ENTER("mysql_repair_table");
  951.   DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
  952. "repair", TL_WRITE, 1, 0, HA_OPEN_FOR_REPAIR,
  953. &handler::repair));
  954. }
  955. int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
  956. {
  957.   DBUG_ENTER("mysql_optimize_table");
  958.   DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
  959. "optimize", TL_WRITE, 1,0,0,
  960. &handler::optimize));
  961. }
  962. int mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
  963. {
  964.   DBUG_ENTER("mysql_analyze_table");
  965.   DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
  966. "analyze",TL_READ_NO_INSERT, 1,0,0,
  967. &handler::analyze));
  968. }
  969. int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
  970. {
  971.   DBUG_ENTER("mysql_check_table");
  972.   DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
  973. "check",
  974. TL_READ_NO_INSERT, 0, 0, HA_OPEN_FOR_REPAIR,
  975. &handler::check));
  976. }
  977. int mysql_alter_table(THD *thd,char *new_db, char *new_name,
  978.       HA_CREATE_INFO *create_info,
  979.       TABLE_LIST *table_list,
  980.       List<create_field> &fields,
  981.       List<Key> &keys,List<Alter_drop> &drop_list,
  982.       List<Alter_column> &alter_list,
  983.                       ORDER *order,
  984.       bool drop_primary,
  985.       enum enum_duplicates handle_duplicates)
  986. {
  987.   TABLE *table,*new_table;
  988.   int error;
  989.   char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN],
  990.     *table_name,*db;
  991.   bool use_timestamp=0;
  992.   ha_rows copied,deleted;
  993.   ulonglong next_insert_id;
  994.   uint save_time_stamp,db_create_options;
  995.   enum db_type old_db_type,new_db_type;
  996.   DBUG_ENTER("mysql_alter_table");
  997.   thd->proc_info="init";
  998.   table_name=table_list->real_name;
  999.   db=table_list->db;
  1000.   if (!new_db)
  1001.     new_db=db;
  1002.   if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
  1003.     DBUG_RETURN(-1);
  1004.   /* Check that we are not trying to rename to an existing table */
  1005.   if (new_name)
  1006.   {
  1007.     strmov(new_name_buff,new_name);
  1008.     fn_same(new_name_buff,table_name,3);
  1009. #ifdef FN_LOWER_CASE
  1010.     if (!my_strcasecmp(new_name_buff,table_name))// Check if name changed
  1011. #else
  1012.     if (!strcmp(new_name_buff,table_name)) // Check if name changed
  1013. #endif
  1014.       new_name=table_name; // No. Make later check easier
  1015.     else
  1016.     {
  1017.       if (table->tmp_table)
  1018.       {
  1019. if (find_temporary_table(thd,new_db,new_name_buff))
  1020. {
  1021.   my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name);
  1022.   DBUG_RETURN(-1);
  1023. }
  1024.       }
  1025.       else
  1026.       {
  1027. if (!access(fn_format(new_name_buff,new_name_buff,new_db,reg_ext,0),
  1028.     F_OK))
  1029. {
  1030.   /* Table will be closed in do_command() */
  1031.   my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name);
  1032.   DBUG_RETURN(-1);
  1033. }
  1034.       }
  1035.     }
  1036.   }
  1037.   else
  1038.     new_name=table_name;
  1039.   old_db_type=table->db_type;
  1040.   if (create_info->db_type == DB_TYPE_DEFAULT)
  1041.     create_info->db_type=old_db_type;
  1042.   new_db_type=create_info->db_type= ha_checktype(create_info->db_type);
  1043.   if (create_info->row_type == ROW_TYPE_DEFAULT)
  1044.     create_info->row_type=table->row_type;
  1045.   /* Check if the user only wants to do a simple RENAME */
  1046.   thd->proc_info="setup";
  1047.   if (new_name != table_name &&
  1048.       !fields.elements && !keys.elements && ! drop_list.elements &&
  1049.       !alter_list.elements && !drop_primary &&
  1050.       new_db_type == old_db_type && create_info->max_rows == 0 &&
  1051.       create_info->auto_increment_value == 0 && !table->tmp_table)
  1052.   {
  1053.     thd->proc_info="rename";
  1054.     VOID(pthread_mutex_lock(&LOCK_open));
  1055.     /* Then do a 'simple' rename of the table */
  1056.     error=0;
  1057.     if (!access(new_name_buff,F_OK))
  1058.     {
  1059.       my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name);
  1060.       error= -1;
  1061.     }
  1062.     else
  1063.     {
  1064.       *fn_ext(new_name)=0;
  1065.       close_cached_table(thd,table);
  1066.       if (mysql_rename_table(old_db_type,db,table_name,new_db,new_name))
  1067. error= -1;
  1068.     }
  1069.     VOID(pthread_cond_broadcast(&COND_refresh));
  1070.     VOID(pthread_mutex_unlock(&LOCK_open));
  1071.     if (!error)
  1072.     {
  1073.       mysql_update_log.write(thd, thd->query, thd->query_length);
  1074.       if (mysql_bin_log.is_open())
  1075.       {
  1076. Query_log_event qinfo(thd, thd->query);
  1077. mysql_bin_log.write(&qinfo);
  1078.       }
  1079.       send_ok(&thd->net);
  1080.     }
  1081.     DBUG_RETURN(error);
  1082.   }
  1083.   /* Full alter table */
  1084.   restore_record(table,2); // Empty record for DEFAULT
  1085.   List_iterator<Alter_drop> drop_it(drop_list);
  1086.   List_iterator<create_field> def_it(fields);
  1087.   List_iterator<Alter_column> alter_it(alter_list);
  1088.   List<create_field> create_list; // Add new fields here
  1089.   List<Key> key_list; // Add new keys here
  1090.   /*
  1091.   ** First collect all fields from table which isn't in drop_list
  1092.   */
  1093.   create_field *def;
  1094.   Field **f_ptr,*field;
  1095.   for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
  1096.   {
  1097.     /* Check if field should be droped */
  1098.     Alter_drop *drop;
  1099.     drop_it.rewind();
  1100.     while ((drop=drop_it++))
  1101.     {
  1102.       if (drop->type == Alter_drop::COLUMN &&
  1103.   !my_strcasecmp(field->field_name, drop->name))
  1104. break;
  1105.     }
  1106.     if (drop)
  1107.     {
  1108.       drop_it.remove();
  1109.       continue;
  1110.     }
  1111.     /* Check if field is changed */
  1112.     def_it.rewind();
  1113.     while ((def=def_it++))
  1114.     {
  1115.       if (def->change && !my_strcasecmp(field->field_name, def->change))
  1116. break;
  1117.     }
  1118.     if (def)
  1119.     { // Field is changed
  1120.       def->field=field;
  1121.       if (def->sql_type == FIELD_TYPE_TIMESTAMP)
  1122. use_timestamp=1;
  1123.       create_list.push_back(def);
  1124.       def_it.remove();
  1125.     }
  1126.     else
  1127.     { // Use old field value
  1128.       create_list.push_back(def=new create_field(field,field));
  1129.       if (def->sql_type == FIELD_TYPE_TIMESTAMP)
  1130. use_timestamp=1;
  1131.       alter_it.rewind(); // Change default if ALTER
  1132.       Alter_column *alter;
  1133.       while ((alter=alter_it++))
  1134.       {
  1135. if (!my_strcasecmp(field->field_name, alter->name))
  1136.   break;
  1137.       }
  1138.       if (alter)
  1139.       {
  1140.         if (def->sql_type == FIELD_TYPE_BLOB)
  1141.         {
  1142.           my_error(ER_BLOB_CANT_HAVE_DEFAULT,MYF(0),def->change);
  1143.           DBUG_RETURN(-1);
  1144.         }
  1145. def->def=alter->def; // Use new default
  1146. alter_it.remove();
  1147.       }
  1148.     }
  1149.   }
  1150.   def_it.rewind();
  1151.   List_iterator<create_field> find_it(create_list);
  1152.   while ((def=def_it++)) // Add new columns
  1153.   {
  1154.     if (def->change)
  1155.     {
  1156.       my_error(ER_BAD_FIELD_ERROR,MYF(0),def->change,table_name);
  1157.       DBUG_RETURN(-1);
  1158.     }
  1159.     if (!def->after)
  1160.       create_list.push_back(def);
  1161.     else if (def->after == first_keyword)
  1162.       create_list.push_front(def);
  1163.     else
  1164.     {
  1165.       create_field *find;
  1166.       find_it.rewind();
  1167.       while ((find=find_it++)) // Add new columns
  1168.       {
  1169. if (!my_strcasecmp(def->after, find->field_name))
  1170.   break;
  1171.       }
  1172.       if (!find)
  1173.       {
  1174. my_error(ER_BAD_FIELD_ERROR,MYF(0),def->after,table_name);
  1175. DBUG_RETURN(-1);
  1176.       }
  1177.       find_it.after(def); // Put element after this
  1178.     }
  1179.   }
  1180.   if (alter_list.elements)
  1181.   {
  1182.     my_error(ER_BAD_FIELD_ERROR,MYF(0),alter_list.head()->name,table_name);
  1183.     DBUG_RETURN(-1);
  1184.   }
  1185.   if (!create_list.elements)
  1186.   {
  1187.     my_error(ER_CANT_REMOVE_ALL_FIELDS,MYF(0));
  1188.     DBUG_RETURN(-1);
  1189.   }
  1190.   /*
  1191.   ** Collect all keys which isn't in drop list. Add only those
  1192.   ** for which some fields exists.
  1193.   */
  1194.   List_iterator<Key> key_it(keys);
  1195.   List_iterator<create_field> field_it(create_list);
  1196.   List<key_part_spec> key_parts;
  1197.   KEY *key_info=table->key_info;
  1198.   for (uint i=0 ; i < table->keys ; i++,key_info++)
  1199.   {
  1200.     if (drop_primary && (key_info->flags & HA_NOSAME))
  1201.     {
  1202.       drop_primary=0;
  1203.       continue;
  1204.     }
  1205.     char *key_name=key_info->name;
  1206.     Alter_drop *drop;
  1207.     drop_it.rewind();
  1208.     while ((drop=drop_it++))
  1209.     {
  1210.       if (drop->type == Alter_drop::KEY &&
  1211.   !my_strcasecmp(key_name, drop->name))
  1212. break;
  1213.     }
  1214.     if (drop)
  1215.     {
  1216.       drop_it.remove();
  1217.       continue;
  1218.     }
  1219.     KEY_PART_INFO *key_part= key_info->key_part;
  1220.     key_parts.empty();
  1221.     for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
  1222.     {
  1223.       if (!key_part->field)
  1224. continue; // Wrong field (from UNIREG)
  1225.       const char *key_part_name=key_part->field->field_name;
  1226.       create_field *cfield;
  1227.       field_it.rewind();
  1228.       while ((cfield=field_it++))
  1229.       {
  1230. if (cfield->change)
  1231. {
  1232.   if (!my_strcasecmp(key_part_name, cfield->change))
  1233.     break;
  1234. }
  1235. else if (!my_strcasecmp(key_part_name, cfield->field_name))
  1236.     break;
  1237.       }
  1238.       if (!cfield)
  1239. continue; // Field is removed
  1240.       uint key_part_length=key_part->length;
  1241.       if (cfield->field) // Not new field
  1242.       { // Check if sub key
  1243. if (cfield->field->type() != FIELD_TYPE_BLOB &&
  1244.     (cfield->field->pack_length() == key_part_length ||
  1245.      cfield->length != cfield->pack_length ||
  1246.      cfield->pack_length <= key_part_length))
  1247.   key_part_length=0; // Use whole field
  1248.       }
  1249.       key_parts.push_back(new key_part_spec(cfield->field_name,
  1250.     key_part_length));
  1251.     }
  1252.     if (key_parts.elements)
  1253.       key_list.push_back(new Key(key_info->flags & HA_NOSAME ?
  1254.  (!my_strcasecmp(key_name, "PRIMARY") ?
  1255.   Key::PRIMARY  : Key::UNIQUE) :
  1256.                                  (key_info->flags & HA_FULLTEXT ?
  1257.                                  Key::FULLTEXT : Key::MULTIPLE),
  1258.  key_name,key_parts));
  1259.   }
  1260.   key_it.rewind();
  1261.   {
  1262.     Key *key;
  1263.     while ((key=key_it++)) // Add new keys
  1264.       key_list.push_back(key);
  1265.   }
  1266.   if (drop_list.elements)
  1267.   {
  1268.     my_error(ER_CANT_DROP_FIELD_OR_KEY,MYF(0),drop_list.head()->name);
  1269.     goto err;
  1270.   }
  1271.   if (alter_list.elements)
  1272.   {
  1273.     my_error(ER_CANT_DROP_FIELD_OR_KEY,MYF(0),alter_list.head()->name);
  1274.     goto err;
  1275.   }
  1276.   (void) sprintf(tmp_name,"%s-%lx_%lx", tmp_file_prefix, current_pid,
  1277.  thd->thread_id);
  1278.   create_info->db_type=new_db_type;
  1279.   if (!create_info->max_rows)
  1280.     create_info->max_rows=table->max_rows;
  1281.   if (!create_info->avg_row_length)
  1282.     create_info->avg_row_length=table->avg_row_length;
  1283.   table->file->update_create_info(create_info);
  1284.   if (!create_info->comment)
  1285.     create_info->comment=table->comment;
  1286.   /* let new create options override the old ones */
  1287.   db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD);
  1288.   if (create_info->table_options &
  1289.       (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS))
  1290.     db_create_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS);
  1291.   if (create_info->table_options &
  1292.       (HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM))
  1293.     db_create_options&= ~(HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM);
  1294.   if (create_info->table_options &
  1295.       (HA_OPTION_DELAY_KEY_WRITE | HA_OPTION_NO_DELAY_KEY_WRITE))
  1296.     db_create_options&= ~(HA_OPTION_DELAY_KEY_WRITE |
  1297.   HA_OPTION_NO_DELAY_KEY_WRITE);
  1298.   create_info->table_options|= db_create_options;
  1299.   if (table->tmp_table)
  1300.     create_info->options|=HA_LEX_CREATE_TMP_TABLE;
  1301.   if ((error=mysql_create_table(thd, new_db, tmp_name,
  1302. create_info,
  1303. create_list,key_list,1,1))) // no logging
  1304.     DBUG_RETURN(error);
  1305.   {
  1306.     if (table->tmp_table)
  1307.       new_table=open_table(thd,new_db,tmp_name,tmp_name,0);
  1308.     else
  1309.     {
  1310.       char path[FN_REFLEN];
  1311.       (void) sprintf(path,"%s/%s/%s",mysql_data_home,new_db,tmp_name);
  1312.       fn_format(path,path,"","",4);
  1313.       new_table=open_temporary_table(thd, path, new_db, tmp_name,0);
  1314.     }
  1315.     if (!new_table)
  1316.     {
  1317.       VOID(quick_rm_table(new_db_type,new_db,tmp_name));
  1318.       goto err;
  1319.     }
  1320.   }
  1321.   save_time_stamp=new_table->time_stamp;
  1322.   if (use_timestamp)
  1323.     new_table->time_stamp=0;
  1324.   new_table->next_number_field=new_table->found_next_number_field;
  1325.   thd->count_cuted_fields=1; // calc cuted fields
  1326.   thd->cuted_fields=0L;
  1327.   thd->proc_info="copy to tmp table";
  1328.   next_insert_id=thd->next_insert_id; // Remember for loggin
  1329.   copied=deleted=0;
  1330.   if (!new_table->is_view)
  1331.     error=copy_data_between_tables(table,new_table,create_list,
  1332.    handle_duplicates,
  1333.    order, &copied, &deleted);
  1334.   thd->last_insert_id=next_insert_id; // Needed for correct log
  1335.   thd->count_cuted_fields=0; // Don`t calc cuted fields
  1336.   new_table->time_stamp=save_time_stamp;
  1337.   if (table->tmp_table)
  1338.   {
  1339.     /* We changed a temporary table */
  1340.     if (error)
  1341.     {
  1342.       close_temporary_table(thd,new_db,tmp_name);
  1343.       my_free((gptr) new_table,MYF(0));
  1344.       goto err;
  1345.     }
  1346.     /* Remove link to old table and rename the new one */
  1347.     close_temporary_table(thd,table->table_cache_key,table_name);
  1348.     if (rename_temporary_table(thd, new_table, new_db, new_name))
  1349.     { // Fatal error
  1350.       close_temporary_table(thd,new_db,tmp_name);
  1351.       my_free((gptr) new_table,MYF(0));
  1352.       goto err;
  1353.     }
  1354.     mysql_update_log.write(thd, thd->query,thd->query_length);
  1355.     if (mysql_bin_log.is_open())
  1356.     {
  1357.       Query_log_event qinfo(thd, thd->query);
  1358.       mysql_bin_log.write(&qinfo);
  1359.     }
  1360.     goto end_temporary;
  1361.   }
  1362.   intern_close_table(new_table); /* close temporary table */
  1363.   my_free((gptr) new_table,MYF(0));
  1364.   VOID(pthread_mutex_lock(&LOCK_open));
  1365.   if (error)
  1366.   {
  1367.     VOID(quick_rm_table(new_db_type,new_db,tmp_name));
  1368.     VOID(pthread_mutex_unlock(&LOCK_open));
  1369.     goto err;
  1370.   }
  1371.   /*
  1372.   ** Data is copied.  Now we rename the old table to a temp name,
  1373.   ** rename the new one to the old name, remove all entries from the old table
  1374.   ** from the cash, free all locks, close the old table and remove it.
  1375.   */
  1376.   thd->proc_info="rename result table";
  1377.   sprintf(old_name,"%s2-%lx-%lx", tmp_file_prefix, current_pid,
  1378.   thd->thread_id);
  1379.   if (new_name != table_name)
  1380.   {
  1381.     if (!access(new_name_buff,F_OK))
  1382.     {
  1383.       error=1;
  1384.       my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff);
  1385.       VOID(quick_rm_table(new_db_type,new_db,tmp_name));
  1386.       VOID(pthread_mutex_unlock(&LOCK_open));
  1387.       goto err;
  1388.     }
  1389.   }
  1390. #if defined( __WIN__) || defined( __EMX__)
  1391.   // Win32 can't rename an open table, so we must close the org table!
  1392.   table_name=thd->strdup(table_name); // must be saved
  1393.   if (close_cached_table(thd,table))
  1394.   { // Aborted
  1395.     VOID(quick_rm_table(new_db_type,new_db,tmp_name));
  1396.     VOID(pthread_mutex_unlock(&LOCK_open));
  1397.     goto err;
  1398.   }
  1399.   table=0; // Marker for win32 version
  1400. #else
  1401.   table->file->extra(HA_EXTRA_FORCE_REOPEN); // Don't use this file anymore
  1402. #endif
  1403.   error=0;
  1404.   if (mysql_rename_table(old_db_type,db,table_name,db,old_name))
  1405.   {
  1406.     error=1;
  1407.     VOID(quick_rm_table(new_db_type,new_db,tmp_name));
  1408.   }
  1409.   else if (mysql_rename_table(new_db_type,new_db,tmp_name,new_db,
  1410.       new_name))
  1411.   { // Try to get everything back
  1412.     error=1;
  1413.     VOID(quick_rm_table(new_db_type,new_db,new_name));
  1414.     VOID(quick_rm_table(new_db_type,new_db,tmp_name));
  1415.     VOID(mysql_rename_table(old_db_type,db,old_name,db,table_name));
  1416.   }
  1417.   if (error)
  1418.   {
  1419.     // This shouldn't happen.  We solve this the safe way by
  1420.     // closing the locked table.
  1421.     close_cached_table(thd,table);
  1422.     VOID(pthread_mutex_unlock(&LOCK_open));
  1423.     goto err;
  1424.   }
  1425.   if (thd->lock || new_name != table_name) // True if WIN32
  1426.   {
  1427.     // Not table locking or alter table with rename
  1428.     // free locks and remove old table
  1429.     close_cached_table(thd,table);
  1430.     VOID(quick_rm_table(old_db_type,db,old_name));
  1431.   }
  1432.   else
  1433.   {
  1434.     // Using LOCK TABLES without rename.
  1435.     // This code is never executed on WIN32!
  1436.     // Remove old renamed table, reopen table and get new locks
  1437.     if (table)
  1438.     {
  1439.       VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Use new file
  1440.       remove_table_from_cache(thd,db,table_name); // Mark all in-use copies old
  1441.       mysql_lock_abort(thd,table);  // end threads waiting on lock
  1442.     }
  1443.     VOID(quick_rm_table(old_db_type,db,old_name));
  1444.     if (close_data_tables(thd,db,table_name) ||
  1445. reopen_tables(thd,1,0))
  1446.     { // This shouldn't happen
  1447.       close_cached_table(thd,table); // Remove lock for table
  1448.       VOID(pthread_mutex_unlock(&LOCK_open));
  1449.       goto err;
  1450.     }
  1451.   }
  1452.   /* The ALTER TABLE is always in it's own transaction */
  1453.   error = ha_commit_stmt(thd);
  1454.   if (ha_commit(thd))
  1455.     error=1;
  1456.   if (error)
  1457.   {
  1458.     VOID(pthread_cond_broadcast(&COND_refresh));
  1459.     VOID(pthread_mutex_unlock(&LOCK_open));
  1460.     goto err;
  1461.   }
  1462.   thd->proc_info="end";
  1463.   mysql_update_log.write(thd, thd->query,thd->query_length);
  1464.   if (mysql_bin_log.is_open())
  1465.   {
  1466.     Query_log_event qinfo(thd, thd->query);
  1467.     mysql_bin_log.write(&qinfo);
  1468.   }
  1469.   VOID(pthread_cond_broadcast(&COND_refresh));
  1470.   VOID(pthread_mutex_unlock(&LOCK_open));
  1471. end_temporary:
  1472.   sprintf(tmp_name,ER(ER_INSERT_INFO),(ulong) (copied+deleted),
  1473.   (ulong) deleted, thd->cuted_fields);
  1474.   send_ok(&thd->net,copied+deleted,0L,tmp_name);
  1475.   thd->some_tables_deleted=0;
  1476.   DBUG_RETURN(0);
  1477.  err:
  1478.   DBUG_RETURN(-1);
  1479. }
  1480. static int
  1481. copy_data_between_tables(TABLE *from,TABLE *to,
  1482.                          List<create_field> &create,
  1483.  enum enum_duplicates handle_duplicates,
  1484.                          ORDER *order,
  1485.  ha_rows *copied,
  1486.                          ha_rows *deleted)
  1487. {
  1488.   int error;
  1489.   Copy_field *copy,*copy_end;
  1490.   ulong found_count,delete_count;
  1491.   THD *thd= current_thd;
  1492.   uint length;
  1493.   SORT_FIELD *sortorder;
  1494.   READ_RECORD info;
  1495.   Field *next_field;
  1496.   TABLE_LIST   tables;
  1497.   List<Item>   fields;
  1498.   List<Item>   all_fields;
  1499.   DBUG_ENTER("copy_data_between_tables");
  1500.   if (!(copy= new Copy_field[to->fields]))
  1501.     DBUG_RETURN(-1); /* purecov: inspected */
  1502.   to->file->external_lock(thd,F_WRLCK);
  1503.   to->file->extra(HA_EXTRA_WRITE_CACHE);
  1504.   from->file->info(HA_STATUS_VARIABLE);
  1505.   to->file->deactivate_non_unique_index(from->file->records);
  1506.   List_iterator<create_field> it(create);
  1507.   create_field *def;
  1508.   copy_end=copy;
  1509.   for (Field **ptr=to->field ; *ptr ; ptr++)
  1510.   {
  1511.     def=it++;
  1512.     if (def->field)
  1513.       (copy_end++)->set(*ptr,def->field,0);
  1514.   }
  1515.   found_count=delete_count=0;
  1516.   if (order)
  1517.   {
  1518.     from->io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
  1519.                                          MYF(MY_FAE | MY_ZEROFILL));
  1520.     bzero((char*) &tables,sizeof(tables));
  1521.     tables.table = from;
  1522.     tables.name  = tables.real_name= from->real_name;
  1523.     tables.db  = from->table_cache_key;
  1524.     error=1;
  1525.     if (setup_order(thd, &tables, fields, all_fields, order) ||
  1526.         !(sortorder=make_unireg_sortorder(order, &length)) ||
  1527.         (from->found_records = filesort(&from, sortorder, length, 
  1528.                                          (SQL_SELECT *) 0, 0L, HA_POS_ERROR))
  1529.         == HA_POS_ERROR)
  1530.       goto err;
  1531.   };
  1532.   init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
  1533.   if (handle_duplicates == DUP_IGNORE ||
  1534.       handle_duplicates == DUP_REPLACE)
  1535.     to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
  1536.   next_field=to->next_number_field;
  1537.   while (!(error=info.read_record(&info)))
  1538.   {
  1539.     if (thd->killed)
  1540.     {
  1541.       my_error(ER_SERVER_SHUTDOWN,MYF(0));
  1542.       error= 1;
  1543.       break;
  1544.     }
  1545.     if (next_field)
  1546.       next_field->reset();
  1547.     for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
  1548.       copy_ptr->do_copy(copy_ptr);
  1549.     if ((error=to->file->write_row((byte*) to->record[0])))
  1550.     {
  1551.       if ((handle_duplicates != DUP_IGNORE &&
  1552.    handle_duplicates != DUP_REPLACE) ||
  1553.   (error != HA_ERR_FOUND_DUPP_KEY &&
  1554.    error != HA_ERR_FOUND_DUPP_UNIQUE))
  1555.       {
  1556. to->file->print_error(error,MYF(0));
  1557. break;
  1558.       }
  1559.       delete_count++;
  1560.     }
  1561.     else
  1562.       found_count++;
  1563.   }
  1564.   end_read_record(&info);
  1565.   free_io_cache(from);
  1566.   delete [] copy;
  1567.   uint tmp_error;
  1568.   if ((tmp_error=to->file->extra(HA_EXTRA_NO_CACHE)))
  1569.   {
  1570.     to->file->print_error(tmp_error,MYF(0));
  1571.     error=1;
  1572.   }
  1573.   to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
  1574.   if (to->file->activate_all_index(thd))
  1575.     error=1;
  1576.   /*
  1577.     Ensure that the new table is saved properly to disk so that we
  1578.     can do a rename
  1579.   */
  1580.   if (ha_commit_stmt(thd))
  1581.     error=1;
  1582.   if (ha_commit(thd))
  1583.     error=1;
  1584.   if (to->file->external_lock(thd,F_UNLCK))
  1585.     error=1;
  1586.  err:
  1587.   free_io_cache(from);
  1588.   *copied= found_count;
  1589.   *deleted=delete_count;
  1590.   DBUG_RETURN(error > 0 ? -1 : 0);
  1591. }