home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / sql / sql_table.cpp < prev    next >
C/C++ Source or Header  |  2000-11-22  |  48KB  |  1,677 lines

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