sql_table.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:109k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000-2004 MySQL 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. #ifdef HAVE_BERKELEY_DB
  16. #include "ha_berkeley.h"
  17. #endif
  18. #include <hash.h>
  19. #include <myisam.h>
  20. #include <my_dir.h>
  21. #ifdef __WIN__
  22. #include <io.h>
  23. #endif
  24. const char *primary_key_name="PRIMARY";
  25. static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
  26. static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
  27. static int copy_data_between_tables(TABLE *from,TABLE *to,
  28.     List<create_field> &create,
  29.     enum enum_duplicates handle_duplicates,
  30.                                     bool ignore,
  31.     uint order_num, ORDER *order,
  32.     ha_rows *copied,ha_rows *deleted);
  33. /*
  34.  Build the path to a file for a table (or the base path that can
  35.  then have various extensions stuck on to it).
  36.   SYNOPSIS
  37.    build_table_path()
  38.    buff                 Buffer to build the path into
  39.    bufflen              sizeof(buff)
  40.    db                   Name of database
  41.    table                Name of table
  42.    ext                  Filename extension
  43.   RETURN
  44.     0                   Error
  45.     #                   Size of path
  46.  */
  47. static uint build_table_path(char *buff, size_t bufflen, const char *db,
  48.                              const char *table, const char *ext)
  49. {
  50.   strxnmov(buff, bufflen-1, mysql_data_home, "/", db, "/", table, ext,
  51.            NullS);
  52.   return unpack_filename(buff,buff);
  53. }
  54. /*
  55.  delete (drop) tables.
  56.   SYNOPSIS
  57.    mysql_rm_table()
  58.    thd Thread handle
  59.    tables List of tables to delete
  60.    if_exists If 1, don't give error if one table doesn't exists
  61.   NOTES
  62.     Will delete all tables that can be deleted and give a compact error
  63.     messages for tables that could not be deleted.
  64.     If a table is in use, we will wait for all users to free the table
  65.     before dropping it
  66.     Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set.
  67.   RETURN
  68.     0 ok.  In this case ok packet is sent to user
  69.     -1 Error  (Error message given but not sent to user)
  70. */
  71. int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
  72.    my_bool drop_temporary)
  73. {
  74.   int error= 0;
  75.   DBUG_ENTER("mysql_rm_table");
  76.   /* mark for close and remove all cached entries */
  77.   thd->mysys_var->current_mutex= &LOCK_open;
  78.   thd->mysys_var->current_cond= &COND_refresh;
  79.   VOID(pthread_mutex_lock(&LOCK_open));
  80.   if (!drop_temporary && global_read_lock)
  81.   {
  82.     if (thd->global_read_lock)
  83.     {
  84.       my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0),
  85.        tables->real_name);
  86.       error= 1;
  87.       goto err;
  88.     }
  89.     while (global_read_lock && ! thd->killed)
  90.     {
  91.       (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
  92.     }
  93.   }
  94.   error=mysql_rm_table_part2(thd,tables, if_exists, drop_temporary, 0);
  95.  err:
  96.   pthread_mutex_unlock(&LOCK_open);
  97.   pthread_mutex_lock(&thd->mysys_var->mutex);
  98.   thd->mysys_var->current_mutex= 0;
  99.   thd->mysys_var->current_cond= 0;
  100.   pthread_mutex_unlock(&thd->mysys_var->mutex);
  101.   if (error)
  102.     DBUG_RETURN(-1);
  103.   send_ok(thd);
  104.   DBUG_RETURN(0);
  105. }
  106. /*
  107.  delete (drop) tables.
  108.   SYNOPSIS
  109.    mysql_rm_table_part2_with_lock()
  110.    thd Thread handle
  111.    tables List of tables to delete
  112.    if_exists If 1, don't give error if one table doesn't exists
  113.    dont_log_query Don't write query to log files
  114.  NOTES
  115.    Works like documented in mysql_rm_table(), but don't check
  116.    global_read_lock and don't send_ok packet to server.
  117.  RETURN
  118.   0 ok
  119.   1 error
  120. */
  121. int mysql_rm_table_part2_with_lock(THD *thd,
  122.    TABLE_LIST *tables, bool if_exists,
  123.    bool drop_temporary, bool dont_log_query)
  124. {
  125.   int error;
  126.   thd->mysys_var->current_mutex= &LOCK_open;
  127.   thd->mysys_var->current_cond= &COND_refresh;
  128.   VOID(pthread_mutex_lock(&LOCK_open));
  129.   error=mysql_rm_table_part2(thd,tables, if_exists, drop_temporary,
  130.      dont_log_query);
  131.   pthread_mutex_unlock(&LOCK_open);
  132.   pthread_mutex_lock(&thd->mysys_var->mutex);
  133.   thd->mysys_var->current_mutex= 0;
  134.   thd->mysys_var->current_cond= 0;
  135.   pthread_mutex_unlock(&thd->mysys_var->mutex);
  136.   return error;
  137. }
  138. /*
  139.   Execute the drop of a normal or temporary table
  140.   SYNOPSIS
  141.     mysql_rm_table_part2()
  142.     thd Thread handler
  143.     tables Tables to drop
  144.     if_exists If set, don't give an error if table doesn't exists.
  145. In this case we give an warning of level 'NOTE'
  146.     drop_temporary Only drop temporary tables
  147.     dont_log_query Don't log the query
  148.   TODO:
  149.     When logging to the binary log, we should log
  150.     tmp_tables and transactional tables as separate statements if we
  151.     are in a transaction;  This is needed to get these tables into the
  152.     cached binary log that is only written on COMMIT.
  153.    The current code only writes DROP statements that only uses temporary
  154.    tables to the cache binary log.  This should be ok on most cases, but
  155.    not all.
  156.  RETURN
  157.    0 ok
  158.    1 Error
  159.    -1 Thread was killed
  160. */
  161. int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
  162.  bool drop_temporary, bool dont_log_query)
  163. {
  164.   TABLE_LIST *table;
  165.   char path[FN_REFLEN], *alias;
  166.   String wrong_tables;
  167.   int error;
  168.   bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
  169.   DBUG_ENTER("mysql_rm_table_part2");
  170.   if (lock_table_names(thd, tables))
  171.     DBUG_RETURN(1);
  172.   for (table=tables ; table ; table=table->next)
  173.   {
  174.     char *db=table->db;
  175.     mysql_ha_flush(thd, table, MYSQL_HA_CLOSE_FINAL, TRUE);
  176.     if (!close_temporary_table(thd, db, table->real_name))
  177.     {
  178.       tmp_table_deleted=1;
  179.       continue; // removed temporary table
  180.     }
  181.     error=0;
  182.     if (!drop_temporary)
  183.     {
  184.       abort_locked_tables(thd,db,table->real_name);
  185.       remove_table_from_cache(thd,db,table->real_name,
  186.                               RTFC_WAIT_OTHER_THREAD_FLAG |
  187.                               RTFC_CHECK_KILLED_FLAG);
  188.       drop_locked_tables(thd,db,table->real_name);
  189.       if (thd->killed)
  190. DBUG_RETURN(-1);
  191.       alias= (lower_case_table_names == 2) ? table->alias : table->real_name;
  192.       /* remove form file and isam files */
  193.       build_table_path(path, sizeof(path), db, alias, reg_ext);
  194.     }
  195.     if (drop_temporary ||
  196. (access(path,F_OK) &&
  197.          ha_create_table_from_engine(thd, db, alias)))
  198.     {
  199.       // Table was not found on disk and table can't be created from engine
  200.       if (if_exists)
  201. push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
  202.     ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
  203.     table->real_name);
  204.       else
  205.         error= 1;
  206.     }
  207.     else
  208.     {
  209.       char *end;
  210.       db_type table_type= get_table_type(path);
  211.       *(end=fn_ext(path))=0; // Remove extension for delete
  212.       error=ha_delete_table(table_type, path);
  213.       if (error == ENOENT && if_exists)
  214. error = 0;
  215.       if (error == HA_ERR_ROW_IS_REFERENCED)
  216.       {
  217. /* the table is referenced by a foreign key constraint */
  218. foreign_key_error=1;
  219.       }
  220.       if (!error || error == ENOENT)
  221.       {
  222. /* Delete the table definition file */
  223. strmov(end,reg_ext);
  224. if (!(error=my_delete(path,MYF(MY_WME))))
  225.   some_tables_deleted=1;
  226.       }
  227.     }
  228.     if (error)
  229.     {
  230.       if (wrong_tables.length())
  231. wrong_tables.append(',');
  232.       wrong_tables.append(String(table->real_name,system_charset_info));
  233.     }
  234.   }
  235.   thd->tmp_table_used= tmp_table_deleted;
  236.   error= 0;
  237.   if (wrong_tables.length())
  238.   {
  239.     if (!foreign_key_error)
  240.       my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
  241.                      wrong_tables.c_ptr());
  242.     else
  243.       my_error(ER_ROW_IS_REFERENCED, MYF(0));
  244.     error= 1;
  245.   }
  246.   if (some_tables_deleted || tmp_table_deleted || !error)
  247.   {
  248.     query_cache_invalidate3(thd, tables, 0);
  249.     if (!dont_log_query)
  250.     {
  251.       mysql_update_log.write(thd, thd->query,thd->query_length);
  252.       if (mysql_bin_log.is_open())
  253.       {
  254.         if (!error)
  255.           thd->clear_error();
  256. Query_log_event qinfo(thd, thd->query, thd->query_length,
  257.       tmp_table_deleted && !some_tables_deleted, 
  258.       FALSE);
  259. mysql_bin_log.write(&qinfo);
  260.       }
  261.     }
  262.   }
  263.   unlock_table_names(thd, tables);
  264.   DBUG_RETURN(error);
  265. }
  266. int quick_rm_table(enum db_type base,const char *db,
  267.    const char *table_name)
  268. {
  269.   char path[FN_REFLEN];
  270.   int error=0;
  271.   build_table_path(path, sizeof(path), db, table_name, reg_ext);
  272.   if (my_delete(path,MYF(0)))
  273.     error=1; /* purecov: inspected */
  274.   *fn_ext(path)= 0;                             // Remove reg_ext
  275.   return ha_delete_table(base,path) || error;
  276. }
  277. /*
  278.   Sort keys in the following order:
  279.   - PRIMARY KEY
  280.   - UNIQUE keyws where all column are NOT NULL
  281.   - Other UNIQUE keys
  282.   - Normal keys
  283.   - Fulltext keys
  284.   This will make checking for duplicated keys faster and ensure that
  285.   PRIMARY keys are prioritized.
  286. */
  287. static int sort_keys(KEY *a, KEY *b)
  288. {
  289.   if (a->flags & HA_NOSAME)
  290.   {
  291.     if (!(b->flags & HA_NOSAME))
  292.       return -1;
  293.     if ((a->flags ^ b->flags) & (HA_NULL_PART_KEY | HA_END_SPACE_KEY))
  294.     {
  295.       /* Sort NOT NULL keys before other keys */
  296.       return (a->flags & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) ? 1 : -1;
  297.     }
  298.     if (a->name == primary_key_name)
  299.       return -1;
  300.     if (b->name == primary_key_name)
  301.       return 1;
  302.   }
  303.   else if (b->flags & HA_NOSAME)
  304.     return 1; // Prefer b
  305.   if ((a->flags ^ b->flags) & HA_FULLTEXT)
  306.   {
  307.     return (a->flags & HA_FULLTEXT) ? 1 : -1;
  308.   }
  309.   /*
  310.     Prefer original key order. usable_key_parts contains here
  311.     the original key position.
  312.   */
  313.   return ((a->usable_key_parts < b->usable_key_parts) ? -1 :
  314.   (a->usable_key_parts > b->usable_key_parts) ? 1 :
  315.   0);
  316. }
  317. /*
  318.   Check TYPELIB (set or enum) for duplicates
  319.   SYNOPSIS
  320.     check_duplicates_in_interval()
  321.     set_or_name   "SET" or "ENUM" string for warning message
  322.     name   name of the checked column
  323.     typelib   list of values for the column
  324.   DESCRIPTION
  325.     This function prints an warning for each value in list
  326.     which has some duplicates on its right
  327.   RETURN VALUES
  328.     void
  329. */
  330. void check_duplicates_in_interval(const char *set_or_name,
  331.                                   const char *name, TYPELIB *typelib,
  332.                                   CHARSET_INFO *cs)
  333. {
  334.   TYPELIB tmp= *typelib;
  335.   const char **cur_value= typelib->type_names;
  336.   unsigned int *cur_length= typelib->type_lengths;
  337.   
  338.   for ( ; tmp.count > 1; cur_value++, cur_length++)
  339.   {
  340.     tmp.type_names++;
  341.     tmp.type_lengths++;
  342.     tmp.count--;
  343.     if (find_type2(&tmp, (const char*)*cur_value, *cur_length, cs))
  344.     {
  345.       push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_NOTE,
  346.   ER_DUPLICATED_VALUE_IN_TYPE,
  347.   ER(ER_DUPLICATED_VALUE_IN_TYPE),
  348.   name,*cur_value,set_or_name);
  349.     }
  350.   }
  351. }
  352. /*
  353.   Check TYPELIB (set or enum) max and total lengths
  354.   SYNOPSIS
  355.     calculate_interval_lengths()
  356.     cs            charset+collation pair of the interval
  357.     typelib       list of values for the column
  358.     max_length    length of the longest item
  359.     tot_length    sum of the item lengths
  360.   DESCRIPTION
  361.     After this function call:
  362.     - ENUM uses max_length
  363.     - SET uses tot_length.
  364.   RETURN VALUES
  365.     void
  366. */
  367. void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
  368.                                 uint32 *max_length, uint32 *tot_length)
  369. {
  370.   const char **pos;
  371.   uint *len;
  372.   *max_length= *tot_length= 0;
  373.   for (pos= interval->type_names, len= interval->type_lengths;
  374.        *pos ; pos++, len++)
  375.   {
  376.     uint length= cs->cset->numchars(cs, *pos, *pos + *len);
  377.     *tot_length+= length;
  378.     set_if_bigger(*max_length, (uint32)length);
  379.   }
  380. }
  381. /*
  382.   Preparation for table creation
  383.   SYNOPSIS
  384.     mysql_prepare_table()
  385.     thd Thread object
  386.     create_info Create information (like MAX_ROWS)
  387.     fields List of fields to create
  388.     keys List of keys to create
  389.   DESCRIPTION
  390.     Prepares the table and key structures for table creation.
  391.   RETURN VALUES
  392.     0 ok
  393.     -1 error
  394. */
  395. int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
  396. List<create_field> &fields,
  397. List<Key> &keys, bool tmp_table, uint &db_options,
  398. handler *file, KEY *&key_info_buffer,
  399. uint *key_count, int select_field_count)
  400. {
  401.   const char *key_name;
  402.   create_field *sql_field,*dup_field;
  403.   uint field,null_fields,blob_columns;
  404.   ulong record_offset= 0;
  405.   KEY *key_info;
  406.   KEY_PART_INFO *key_part_info;
  407.   int timestamps= 0, timestamps_with_niladic= 0;
  408.   int field_no,dup_no;
  409.   int select_field_pos,auto_increment=0;
  410.   DBUG_ENTER("mysql_prepare_table");
  411.   List_iterator<create_field> it(fields),it2(fields);
  412.   select_field_pos=fields.elements - select_field_count;
  413.   null_fields=blob_columns=0;
  414.   for (field_no=0; (sql_field=it++) ; field_no++)
  415.   {
  416.     if (!sql_field->charset)
  417.       sql_field->charset= create_info->default_table_charset;
  418.     /*
  419.       table_charset is set in ALTER TABLE if we want change character set
  420.       for all varchar/char columns.
  421.       But the table charset must not affect the BLOB fields, so don't
  422.       allow to change my_charset_bin to somethig else.
  423.     */
  424.     if (create_info->table_charset && sql_field->charset != &my_charset_bin)
  425.       sql_field->charset= create_info->table_charset;
  426.     CHARSET_INFO *savecs= sql_field->charset;
  427.     if ((sql_field->flags & BINCMP_FLAG) &&
  428. !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname,
  429.     MY_CS_BINSORT,MYF(0))))
  430.     {
  431.       char tmp[64];
  432.       strmake(strmake(tmp, savecs->csname, sizeof(tmp)-4), "_bin", 4);
  433.       my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
  434.       DBUG_RETURN(-1);
  435.     }
  436.     if (sql_field->sql_type == FIELD_TYPE_SET ||
  437.         sql_field->sql_type == FIELD_TYPE_ENUM)
  438.     {
  439.       uint32 dummy;
  440.       CHARSET_INFO *cs= sql_field->charset;
  441.       TYPELIB *interval= sql_field->interval;
  442.       /*
  443.         Create typelib from interval_list, and if necessary
  444.         convert strings from client character set to the
  445.         column character set.
  446.       */
  447.       if (!interval)
  448.       {
  449.         /*
  450.           Create the typelib in prepared statement memory if we're
  451.           executing one.
  452.         */
  453.         MEM_ROOT *stmt_root= thd->current_arena->mem_root;
  454.         interval= sql_field->interval= typelib(stmt_root,
  455.                                                sql_field->interval_list);
  456.         List_iterator<String> it(sql_field->interval_list);
  457.         String conv, *tmp;
  458.         for (uint i= 0; (tmp= it++); i++)
  459.         {
  460.           if (String::needs_conversion(tmp->length(), tmp->charset(),
  461.                                        cs, &dummy))
  462.           {
  463.             uint cnv_errs;
  464.             conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
  465.             char *buf= (char*) alloc_root(stmt_root, conv.length()+1);
  466.             memcpy(buf, conv.ptr(), conv.length());
  467.             buf[conv.length()]= '';
  468.             interval->type_names[i]= buf;
  469.             interval->type_lengths[i]= conv.length();
  470.           }
  471.           // Strip trailing spaces.
  472.           uint lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
  473.                                             interval->type_lengths[i]);
  474.           interval->type_lengths[i]= lengthsp;
  475.           ((uchar *)interval->type_names[i])[lengthsp]= '';
  476.         }
  477.         sql_field->interval_list.empty(); // Don't need interval_list anymore
  478.       }
  479.       /*
  480.         Convert the default value from client character
  481.         set into the column character set if necessary.
  482.       */
  483.       if (sql_field->def && cs != sql_field->def->collation.collation)
  484.       {
  485.         Item_arena backup_arena;
  486.         bool need_to_change_arena=
  487.           !thd->current_arena->is_conventional_execution();
  488.         if (need_to_change_arena)
  489.         {
  490.           /* Asser that we don't do that at every PS execute */
  491.           DBUG_ASSERT(thd->current_arena->is_first_stmt_execute());
  492.           thd->set_n_backup_item_arena(thd->current_arena, &backup_arena);
  493.         }
  494.         sql_field->def= sql_field->def->safe_charset_converter(cs);
  495.         if (need_to_change_arena)
  496.           thd->restore_backup_item_arena(thd->current_arena, &backup_arena);
  497.         if (! sql_field->def)
  498.         {
  499.           /* Could not convert */
  500.           my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
  501.           DBUG_RETURN(-1);
  502.         }
  503.       }
  504.       if (sql_field->sql_type == FIELD_TYPE_SET)
  505.       {
  506.         if (sql_field->def)
  507.         {
  508.           char *not_used;
  509.           uint not_used2;
  510.           bool not_found= 0;
  511.           String str, *def= sql_field->def->val_str(&str);
  512.           def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
  513.           (void) find_set(interval, def->ptr(), def->length(),
  514.                           cs, &not_used, &not_used2, &not_found);
  515.           if (not_found)
  516.           {
  517.             my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
  518.             DBUG_RETURN(-1);
  519.           }
  520.         }
  521.         calculate_interval_lengths(cs, interval, &dummy, &sql_field->length);
  522.         sql_field->length+= (interval->count - 1);
  523.       }
  524.       else  /* FIELD_TYPE_ENUM */
  525.       {
  526.         if (sql_field->def)
  527.         {
  528.           String str, *def= sql_field->def->val_str(&str);
  529.           def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
  530.           if (!find_type2(interval, def->ptr(), def->length(), cs))
  531.           {
  532.             my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
  533.             DBUG_RETURN(-1);
  534.           }
  535.         }
  536.         calculate_interval_lengths(cs, interval, &sql_field->length, &dummy);
  537.       }
  538.       set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
  539.     }
  540.     sql_field->create_length_to_internal_length();
  541.     /* Don't pack keys in old tables if the user has requested this */
  542.     if ((sql_field->flags & BLOB_FLAG) ||
  543. sql_field->sql_type == FIELD_TYPE_VAR_STRING &&
  544. create_info->row_type != ROW_TYPE_FIXED)
  545.     {
  546.       db_options|=HA_OPTION_PACK_RECORD;
  547.     }
  548.     if (!(sql_field->flags & NOT_NULL_FLAG))
  549.       null_fields++;
  550.     if (check_column_name(sql_field->field_name))
  551.     {
  552.       my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name);
  553.       DBUG_RETURN(-1);
  554.     }
  555.     /* Check if we have used the same field name before */
  556.     for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
  557.     {
  558.       if (my_strcasecmp(system_charset_info,
  559. sql_field->field_name,
  560. dup_field->field_name) == 0)
  561.       {
  562. /*
  563.   If this was a CREATE ... SELECT statement, accept a field
  564.   redefinition if we are changing a field in the SELECT part
  565. */
  566. if (field_no < select_field_pos || dup_no >= select_field_pos)
  567. {
  568.   my_error(ER_DUP_FIELDNAME,MYF(0),sql_field->field_name);
  569.   DBUG_RETURN(-1);
  570. }
  571. else
  572. {
  573.   /* Field redefined */
  574.   sql_field->def= dup_field->def;
  575.   sql_field->sql_type= dup_field->sql_type;
  576.   sql_field->charset= (dup_field->charset ?
  577.  dup_field->charset :
  578.  create_info->default_table_charset);
  579.   sql_field->length= dup_field->chars_length;
  580.           sql_field->pack_length= dup_field->pack_length;
  581.   sql_field->create_length_to_internal_length();
  582.   sql_field->decimals= dup_field->decimals;
  583.   sql_field->unireg_check= dup_field->unireg_check;
  584.           /* 
  585.             We're making one field from two, the result field will have
  586.             dup_field->flags as flags. If we've incremented null_fields
  587.             because of sql_field->flags, decrement it back.
  588.           */
  589.           if (!(sql_field->flags & NOT_NULL_FLAG))
  590.             null_fields--;
  591.   sql_field->flags= dup_field->flags;
  592.   it2.remove(); // Remove first (create) definition
  593.   select_field_pos--;
  594.   break;
  595. }
  596.       }
  597.     }
  598.     it2.rewind();
  599.   }
  600.   /* record_offset will be increased with 'length-of-null-bits' later */
  601.   record_offset= 0;
  602.   it.rewind();
  603.   while ((sql_field=it++))
  604.   {
  605.     DBUG_ASSERT(sql_field->charset);
  606.     switch (sql_field->sql_type) {
  607.     case FIELD_TYPE_BLOB:
  608.     case FIELD_TYPE_MEDIUM_BLOB:
  609.     case FIELD_TYPE_TINY_BLOB:
  610.     case FIELD_TYPE_LONG_BLOB:
  611.       sql_field->pack_flag=FIELDFLAG_BLOB |
  612. pack_length_to_packflag(sql_field->pack_length -
  613. portable_sizeof_char_ptr);
  614.       if (sql_field->charset->state & MY_CS_BINSORT)
  615. sql_field->pack_flag|=FIELDFLAG_BINARY;
  616.       sql_field->length=8; // Unireg field length
  617.       sql_field->unireg_check=Field::BLOB_FIELD;
  618.       blob_columns++;
  619.       break;
  620.     case FIELD_TYPE_GEOMETRY:
  621. #ifdef HAVE_SPATIAL
  622.       if (!(file->table_flags() & HA_CAN_GEOMETRY))
  623.       {
  624. my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED),
  625. MYF(0), "GEOMETRY");
  626. DBUG_RETURN(-1);
  627.       }
  628.       sql_field->pack_flag=FIELDFLAG_GEOM |
  629. pack_length_to_packflag(sql_field->pack_length -
  630. portable_sizeof_char_ptr);
  631.       if (sql_field->charset->state & MY_CS_BINSORT)
  632. sql_field->pack_flag|=FIELDFLAG_BINARY;
  633.       sql_field->length=8; // Unireg field length
  634.       sql_field->unireg_check=Field::BLOB_FIELD;
  635.       blob_columns++;
  636.       break;
  637. #else
  638.       my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0),
  639.       sym_group_geom.name, sym_group_geom.needed_define);
  640.       DBUG_RETURN(-1);
  641. #endif /*HAVE_SPATIAL*/
  642.     case FIELD_TYPE_VAR_STRING:
  643.     case FIELD_TYPE_STRING:
  644.       sql_field->pack_flag=0;
  645.       if (sql_field->charset->state & MY_CS_BINSORT)
  646. sql_field->pack_flag|=FIELDFLAG_BINARY;
  647.       break;
  648.     case FIELD_TYPE_ENUM:
  649.       sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
  650. FIELDFLAG_INTERVAL;
  651.       if (sql_field->charset->state & MY_CS_BINSORT)
  652. sql_field->pack_flag|=FIELDFLAG_BINARY;
  653.       sql_field->unireg_check=Field::INTERVAL_FIELD;
  654.       check_duplicates_in_interval("ENUM",sql_field->field_name,
  655.                                    sql_field->interval,
  656.                                    sql_field->charset);
  657.       break;
  658.     case FIELD_TYPE_SET:
  659.       sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
  660. FIELDFLAG_BITFIELD;
  661.       if (sql_field->charset->state & MY_CS_BINSORT)
  662. sql_field->pack_flag|=FIELDFLAG_BINARY;
  663.       sql_field->unireg_check=Field::BIT_FIELD;
  664.       check_duplicates_in_interval("SET",sql_field->field_name,
  665.                                    sql_field->interval,
  666.                                    sql_field->charset);
  667.       break;
  668.     case FIELD_TYPE_DATE: // Rest of string types
  669.     case FIELD_TYPE_NEWDATE:
  670.     case FIELD_TYPE_TIME:
  671.     case FIELD_TYPE_DATETIME:
  672.     case FIELD_TYPE_NULL:
  673.       sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
  674.       break;
  675.     case FIELD_TYPE_TIMESTAMP:
  676.       /* We should replace old TIMESTAMP fields with their newer analogs */
  677.       if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
  678.       {
  679. if (!timestamps)
  680. {
  681.   sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
  682.   timestamps_with_niladic++;
  683. }
  684. else
  685.   sql_field->unireg_check= Field::NONE;
  686.       }
  687.       else if (sql_field->unireg_check != Field::NONE)
  688. timestamps_with_niladic++;
  689.       timestamps++;
  690.       /* fall-through */
  691.     default:
  692.       sql_field->pack_flag=(FIELDFLAG_NUMBER |
  693.     (sql_field->flags & UNSIGNED_FLAG ? 0 :
  694.      FIELDFLAG_DECIMAL) |
  695.     (sql_field->flags & ZEROFILL_FLAG ?
  696.      FIELDFLAG_ZEROFILL : 0) |
  697.     f_settype((uint) sql_field->sql_type) |
  698.     (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
  699.       break;
  700.     }
  701.     if (!(sql_field->flags & NOT_NULL_FLAG))
  702.       sql_field->pack_flag|=FIELDFLAG_MAYBE_NULL;
  703.     sql_field->offset= record_offset;
  704.     if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
  705.       auto_increment++;
  706.     record_offset+= sql_field->pack_length;
  707.   }
  708.   if (timestamps_with_niladic > 1)
  709.   {
  710.     my_error(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,MYF(0));
  711.     DBUG_RETURN(-1);
  712.   }
  713.   if (auto_increment > 1)
  714.   {
  715.     my_error(ER_WRONG_AUTO_KEY,MYF(0));
  716.     DBUG_RETURN(-1);
  717.   }
  718.   if (auto_increment &&
  719.       (file->table_flags() & HA_NO_AUTO_INCREMENT))
  720.   {
  721.     my_error(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,MYF(0));
  722.     DBUG_RETURN(-1);
  723.   }
  724.   if (blob_columns && (file->table_flags() & HA_NO_BLOBS))
  725.   {
  726.     my_error(ER_TABLE_CANT_HANDLE_BLOB,MYF(0));
  727.     DBUG_RETURN(-1);
  728.   }
  729.   /* Create keys */
  730.   List_iterator<Key> key_iterator(keys), key_iterator2(keys);
  731.   uint key_parts=0, fk_key_count=0;
  732.   bool primary_key=0,unique_key=0;
  733.   Key *key, *key2;
  734.   uint tmp, key_number;
  735.   /* special marker for keys to be ignored */
  736.   static char ignore_key[1];
  737.   /* Calculate number of key segements */
  738.   *key_count= 0;
  739.   while ((key=key_iterator++))
  740.   {
  741.     if (key->type == Key::FOREIGN_KEY)
  742.     {
  743.       fk_key_count++;
  744.       foreign_key *fk_key= (foreign_key*) key;
  745.       if (fk_key->ref_columns.elements &&
  746.   fk_key->ref_columns.elements != fk_key->columns.elements)
  747.       {
  748. my_error(ER_WRONG_FK_DEF, MYF(0), fk_key->name ? fk_key->name :
  749.  "foreign key without name",
  750.  ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
  751. DBUG_RETURN(-1);
  752.       }
  753.       continue;
  754.     }
  755.     (*key_count)++;
  756.     tmp=file->max_key_parts();
  757.     if (key->columns.elements > tmp)
  758.     {
  759.       my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
  760.       DBUG_RETURN(-1);
  761.     }
  762.     if (key->name && strlen(key->name) > NAME_LEN)
  763.     {
  764.       my_error(ER_TOO_LONG_IDENT, MYF(0), key->name);
  765.       DBUG_RETURN(-1);
  766.     }
  767.     key_iterator2.rewind ();
  768.     if (key->type != Key::FOREIGN_KEY)
  769.     {
  770.       while ((key2 = key_iterator2++) != key)
  771.       {
  772. /*
  773.           foreign_key_prefix(key, key2) returns 0 if key or key2, or both, is
  774.           'generated', and a generated key is a prefix of the other key.
  775.           Then we do not need the generated shorter key.
  776.         */
  777.         if ((key2->type != Key::FOREIGN_KEY &&
  778.              key2->name != ignore_key &&
  779.              !foreign_key_prefix(key, key2)))
  780.         {
  781.           /* TODO: issue warning message */
  782.           /* mark that the generated key should be ignored */
  783.           if (!key2->generated ||
  784.               (key->generated && key->columns.elements <
  785.                key2->columns.elements))
  786.             key->name= ignore_key;
  787.           else
  788.           {
  789.             key2->name= ignore_key;
  790.             key_parts-= key2->columns.elements;
  791.             (*key_count)--;
  792.           }
  793.           break;
  794.         }
  795.       }
  796.     }
  797.     if (key->name != ignore_key)
  798.       key_parts+=key->columns.elements;
  799.     else
  800.       (*key_count)--;
  801.     if (key->name && !tmp_table &&
  802. !my_strcasecmp(system_charset_info,key->name,primary_key_name))
  803.     {
  804.       my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name);
  805.       DBUG_RETURN(-1);
  806.     }
  807.   }
  808.   tmp=file->max_keys();
  809.   if (*key_count > tmp)
  810.   {
  811.     my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
  812.     DBUG_RETURN(-1);
  813.   }
  814.   key_info_buffer=key_info=(KEY*) sql_calloc(sizeof(KEY)* *key_count);
  815.   key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts);
  816.   if (!key_info_buffer || ! key_part_info)
  817.     DBUG_RETURN(-1); // Out of memory
  818.   key_iterator.rewind();
  819.   key_number=0;
  820.   for (; (key=key_iterator++) ; key_number++)
  821.   {
  822.     uint key_length=0;
  823.     key_part_spec *column;
  824.     if (key->name == ignore_key)
  825.     {
  826.       /* ignore redundant keys */
  827.       do
  828. key=key_iterator++;
  829.       while (key && key->name == ignore_key);
  830.       if (!key)
  831. break;
  832.     }
  833.     switch(key->type){
  834.     case Key::MULTIPLE:
  835. key_info->flags= 0;
  836. break;
  837.     case Key::FULLTEXT:
  838. key_info->flags= HA_FULLTEXT;
  839. break;
  840.     case Key::SPATIAL:
  841. #ifdef HAVE_SPATIAL
  842. key_info->flags= HA_SPATIAL;
  843. break;
  844. #else
  845. my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0),
  846. sym_group_geom.name, sym_group_geom.needed_define);
  847. DBUG_RETURN(-1);
  848. #endif
  849.     case Key::FOREIGN_KEY:
  850.       key_number--; // Skip this key
  851.       continue;
  852.     default:
  853.       key_info->flags = HA_NOSAME;
  854.       break;
  855.     }
  856.     if (key->generated)
  857.       key_info->flags|= HA_GENERATED_KEY;
  858.     key_info->key_parts=(uint8) key->columns.elements;
  859.     key_info->key_part=key_part_info;
  860.     key_info->usable_key_parts= key_number;
  861.     key_info->algorithm=key->algorithm;
  862.     if (key->type == Key::FULLTEXT)
  863.     {
  864.       if (!(file->table_flags() & HA_CAN_FULLTEXT))
  865.       {
  866. my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0));
  867. DBUG_RETURN(-1);
  868.       }
  869.     }
  870.     /*
  871.        Make SPATIAL to be RTREE by default
  872.        SPATIAL only on BLOB or at least BINARY, this
  873.        actually should be replaced by special GEOM type
  874.        in near future when new frm file is ready
  875.        checking for proper key parts number:
  876.     */
  877.     /* TODO: Add proper checks if handler supports key_type and algorithm */
  878.     if (key_info->flags & HA_SPATIAL)
  879.     {
  880.       if (key_info->key_parts != 1)
  881.       {
  882. my_printf_error(ER_WRONG_ARGUMENTS,
  883. ER(ER_WRONG_ARGUMENTS),MYF(0),"SPATIAL INDEX");
  884. DBUG_RETURN(-1);
  885.       }
  886.     }
  887.     else if (key_info->algorithm == HA_KEY_ALG_RTREE)
  888.     {
  889. #ifdef HAVE_RTREE_KEYS
  890.       if ((key_info->key_parts & 1) == 1)
  891.       {
  892. my_printf_error(ER_WRONG_ARGUMENTS,
  893. ER(ER_WRONG_ARGUMENTS),MYF(0),"RTREE INDEX");
  894. DBUG_RETURN(-1);
  895.       }
  896.       /* TODO: To be deleted */
  897.       my_printf_error(ER_NOT_SUPPORTED_YET, ER(ER_NOT_SUPPORTED_YET),
  898.       MYF(0), "RTREE INDEX");
  899.       DBUG_RETURN(-1);
  900. #else
  901.       my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0),
  902.       sym_group_rtree.name, sym_group_rtree.needed_define);
  903.       DBUG_RETURN(-1);
  904. #endif
  905.     }
  906.     List_iterator<key_part_spec> cols(key->columns), cols2(key->columns);
  907.     CHARSET_INFO *ft_key_charset=0;  // for FULLTEXT
  908.     for (uint column_nr=0 ; (column=cols++) ; column_nr++)
  909.     {
  910.       key_part_spec *dup_column;
  911.       it.rewind();
  912.       field=0;
  913.       while ((sql_field=it++) &&
  914.      my_strcasecmp(system_charset_info,
  915.    column->field_name,
  916.    sql_field->field_name))
  917. field++;
  918.       if (!sql_field)
  919.       {
  920. my_printf_error(ER_KEY_COLUMN_DOES_NOT_EXITS,
  921. ER(ER_KEY_COLUMN_DOES_NOT_EXITS),MYF(0),
  922. column->field_name);
  923. DBUG_RETURN(-1);
  924.       }
  925.       while ((dup_column= cols2++) != column)
  926.       {
  927.         if (!my_strcasecmp(system_charset_info,
  928.                  column->field_name, dup_column->field_name))
  929. {
  930.   my_printf_error(ER_DUP_FIELDNAME,
  931.   ER(ER_DUP_FIELDNAME),MYF(0),
  932.   column->field_name);
  933.   DBUG_RETURN(-1);
  934. }
  935.       }
  936.       cols2.rewind();
  937.       if (key->type == Key::FULLTEXT)
  938.       {
  939. if ((sql_field->sql_type != FIELD_TYPE_STRING &&
  940.      sql_field->sql_type != FIELD_TYPE_VAR_STRING &&
  941.      !f_is_blob(sql_field->pack_flag)) ||
  942.     sql_field->charset == &my_charset_bin ||
  943.     sql_field->charset->mbminlen > 1 || // ucs2 doesn't work yet
  944.     (ft_key_charset && sql_field->charset != ft_key_charset))
  945. {
  946.     my_printf_error(ER_BAD_FT_COLUMN,ER(ER_BAD_FT_COLUMN),MYF(0),
  947.     column->field_name);
  948.     DBUG_RETURN(-1);
  949. }
  950. ft_key_charset=sql_field->charset;
  951. /*
  952.   for fulltext keys keyseg length is 1 for blobs (it's ignored in ft
  953.   code anyway, and 0 (set to column width later) for char's. it has
  954.   to be correct col width for char's, as char data are not prefixed
  955.   with length (unlike blobs, where ft code takes data length from a
  956.   data prefix, ignoring column->length).
  957. */
  958. column->length=test(f_is_blob(sql_field->pack_flag));
  959.       }
  960.       else
  961.       {
  962. column->length*= sql_field->charset->mbmaxlen;
  963. if (f_is_blob(sql_field->pack_flag))
  964. {
  965.   if (!(file->table_flags() & HA_CAN_INDEX_BLOBS))
  966.   {
  967.     my_printf_error(ER_BLOB_USED_AS_KEY,ER(ER_BLOB_USED_AS_KEY),MYF(0),
  968.     column->field_name);
  969.     DBUG_RETURN(-1);
  970.   }
  971.   if (!column->length)
  972.   {
  973.     my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH,
  974.     ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0),
  975.     column->field_name);
  976.     DBUG_RETURN(-1);
  977.   }
  978. }
  979. #ifdef HAVE_SPATIAL
  980. if (key->type  == Key::SPATIAL)
  981. {
  982.   if (!column->length )
  983.   {
  984.     /*
  985.     BAR: 4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case
  986.  Lately we'll extend this code to support more dimensions
  987.     */
  988.     column->length=4*sizeof(double);
  989.   }
  990. }
  991. #endif
  992. if (!(sql_field->flags & NOT_NULL_FLAG))
  993. {
  994.   if (key->type == Key::PRIMARY)
  995.   {
  996.     /* Implicitly set primary key fields to NOT NULL for ISO conf. */
  997.     sql_field->flags|= NOT_NULL_FLAG;
  998.     sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL;
  999.             null_fields--;
  1000.   }
  1001.   else
  1002.      key_info->flags|= HA_NULL_PART_KEY;
  1003.   if (!(file->table_flags() & HA_NULL_IN_KEY))
  1004.   {
  1005.     my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX),
  1006.     MYF(0),column->field_name);
  1007.     DBUG_RETURN(-1);
  1008.   }
  1009.   if (key->type == Key::SPATIAL)
  1010.   {
  1011.     my_error(ER_SPATIAL_CANT_HAVE_NULL, MYF(0));
  1012.     DBUG_RETURN(-1);
  1013.   }
  1014. }
  1015. if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
  1016. {
  1017.   if (column_nr == 0 || (file->table_flags() & HA_AUTO_PART_KEY))
  1018.     auto_increment--; // Field is used
  1019. }
  1020.       }
  1021.       key_part_info->fieldnr= field;
  1022.       key_part_info->offset=  (uint16) sql_field->offset;
  1023.       key_part_info->key_type=sql_field->pack_flag;
  1024.       uint length=sql_field->pack_length;
  1025.       if (column->length)
  1026.       {
  1027. if (f_is_blob(sql_field->pack_flag))
  1028. {
  1029.   if ((length=column->length) > file->max_key_length() ||
  1030.       length > file->max_key_part_length())
  1031.   {
  1032.     length=min(file->max_key_length(), file->max_key_part_length());
  1033.     if (key->type == Key::MULTIPLE)
  1034.     {
  1035.       /* not a critical problem */
  1036.       char warn_buff[MYSQL_ERRMSG_SIZE];
  1037.       my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
  1038.   length);
  1039.       push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
  1040.    ER_TOO_LONG_KEY, warn_buff);
  1041.     }
  1042.     else
  1043.     {
  1044.       my_error(ER_TOO_LONG_KEY,MYF(0),length);
  1045.       DBUG_RETURN(-1);
  1046.     }
  1047.   }
  1048. }
  1049. else if (!f_is_geom(sql_field->pack_flag) &&
  1050.   (column->length > length ||
  1051.    ((f_is_packed(sql_field->pack_flag) ||
  1052.      ((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
  1053.       (key_info->flags & HA_NOSAME))) &&
  1054.     column->length != length)))
  1055. {
  1056.   my_error(ER_WRONG_SUB_KEY,MYF(0));
  1057.   DBUG_RETURN(-1);
  1058. }
  1059. else if (!(file->table_flags() & HA_NO_PREFIX_CHAR_KEYS))
  1060.   length=column->length;
  1061.       }
  1062.       else if (length == 0)
  1063.       {
  1064. my_printf_error(ER_WRONG_KEY_COLUMN, ER(ER_WRONG_KEY_COLUMN), MYF(0),
  1065. column->field_name);
  1066.   DBUG_RETURN(-1);
  1067.       }
  1068.       if (length > file->max_key_part_length())
  1069.       {
  1070. length=file->max_key_part_length();
  1071. if (key->type == Key::MULTIPLE)
  1072. {
  1073.   /* not a critical problem */
  1074.   char warn_buff[MYSQL_ERRMSG_SIZE];
  1075.   my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
  1076.       length);
  1077.   push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
  1078.        ER_TOO_LONG_KEY, warn_buff);
  1079. }
  1080. else
  1081. {
  1082.   my_error(ER_TOO_LONG_KEY,MYF(0),length);
  1083.   DBUG_RETURN(-1);
  1084. }
  1085.       }
  1086.       key_part_info->length=(uint16) length;
  1087.       /* Use packed keys for long strings on the first column */
  1088.       if (!(db_options & HA_OPTION_NO_PACK_KEYS) &&
  1089.   (length >= KEY_DEFAULT_PACK_LENGTH &&
  1090.    (sql_field->sql_type == FIELD_TYPE_STRING ||
  1091.     sql_field->sql_type == FIELD_TYPE_VAR_STRING ||
  1092.     sql_field->pack_flag & FIELDFLAG_BLOB)))
  1093.       {
  1094. if (column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB))
  1095.   key_info->flags|= HA_BINARY_PACK_KEY;
  1096. else
  1097.   key_info->flags|= HA_PACK_KEY;
  1098.       }
  1099.       key_length+=length;
  1100.       key_part_info++;
  1101.       /* Create the key name based on the first column (if not given) */
  1102.       if (column_nr == 0)
  1103.       {
  1104. if (key->type == Key::PRIMARY)
  1105. {
  1106.   if (primary_key)
  1107.   {
  1108.     my_error(ER_MULTIPLE_PRI_KEY,MYF(0));
  1109.     DBUG_RETURN(-1);
  1110.   }
  1111.   key_name=primary_key_name;
  1112.   primary_key=1;
  1113. }
  1114. else if (!(key_name = key->name))
  1115.   key_name=make_unique_key_name(sql_field->field_name,
  1116. key_info_buffer,key_info);
  1117. if (check_if_keyname_exists(key_name,key_info_buffer,key_info))
  1118. {
  1119.   my_error(ER_DUP_KEYNAME,MYF(0),key_name);
  1120.   DBUG_RETURN(-1);
  1121. }
  1122. key_info->name=(char*) key_name;
  1123.       }
  1124.     }
  1125.     if (!key_info->name || check_column_name(key_info->name))
  1126.     {
  1127.       my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
  1128.       DBUG_RETURN(-1);
  1129.     }
  1130.     if (!(key_info->flags & HA_NULL_PART_KEY))
  1131.       unique_key=1;
  1132.     key_info->key_length=(uint16) key_length;
  1133.     uint max_key_length= file->max_key_length();
  1134.     if (key_length > max_key_length && key->type != Key::FULLTEXT)
  1135.     {
  1136.       my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
  1137.       DBUG_RETURN(-1);
  1138.     }
  1139.     key_info++;
  1140.   }
  1141.   if (!unique_key && !primary_key &&
  1142.       (file->table_flags() & HA_REQUIRE_PRIMARY_KEY))
  1143.   {
  1144.     my_error(ER_REQUIRES_PRIMARY_KEY,MYF(0));
  1145.     DBUG_RETURN(-1);
  1146.   }
  1147.   if (auto_increment > 0)
  1148.   {
  1149.     my_error(ER_WRONG_AUTO_KEY,MYF(0));
  1150.     DBUG_RETURN(-1);
  1151.   }
  1152.   /* Sort keys in optimized order */
  1153.   qsort((gptr) key_info_buffer, *key_count, sizeof(KEY),
  1154. (qsort_cmp) sort_keys);
  1155.   create_info->null_bits= null_fields;
  1156.   DBUG_RETURN(0);
  1157. }
  1158. /*
  1159.   Create a table
  1160.   SYNOPSIS
  1161.     mysql_create_table()
  1162.     thd Thread object
  1163.     db Database
  1164.     table_name Table name
  1165.     create_info Create information (like MAX_ROWS)
  1166.     fields List of fields to create
  1167.     keys List of keys to create
  1168.     tmp_table Set to 1 if this is an internal temporary table
  1169. (From ALTER TABLE)
  1170.   DESCRIPTION
  1171.     If one creates a temporary table, this is automaticly opened
  1172.     no_log is needed for the case of CREATE ... SELECT,
  1173.     as the logging will be done later in sql_insert.cc
  1174.     select_field_count is also used for CREATE ... SELECT,
  1175.     and must be zero for standard create of table.
  1176.   RETURN VALUES
  1177.     0 ok
  1178.     -1 error
  1179. */
  1180. int mysql_create_table(THD *thd,const char *db, const char *table_name,
  1181.        HA_CREATE_INFO *create_info,
  1182.        List<create_field> &fields,
  1183.        List<Key> &keys,bool tmp_table,
  1184.        uint select_field_count)
  1185. {
  1186.   char path[FN_REFLEN];
  1187.   const char *alias;
  1188.   int error= -1;
  1189.   uint db_options, key_count;
  1190.   KEY *key_info_buffer;
  1191.   handler *file;
  1192.   enum db_type new_db_type;
  1193.   DBUG_ENTER("mysql_create_table");
  1194.   /* Check for duplicate fields and check type of table to create */
  1195.   if (!fields.elements)
  1196.   {
  1197.     my_error(ER_TABLE_MUST_HAVE_COLUMNS,MYF(0));
  1198.     DBUG_RETURN(-1);
  1199.   }
  1200.   if ((new_db_type= ha_checktype(create_info->db_type)) !=
  1201.       create_info->db_type)
  1202.   {
  1203.     create_info->db_type= new_db_type;
  1204.     push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
  1205. ER_WARN_USING_OTHER_HANDLER,
  1206. ER(ER_WARN_USING_OTHER_HANDLER),
  1207. ha_get_storage_engine(new_db_type),
  1208. table_name);
  1209.   }
  1210.   db_options=create_info->table_options;
  1211.   if (create_info->row_type == ROW_TYPE_DYNAMIC)
  1212.     db_options|=HA_OPTION_PACK_RECORD;
  1213.   alias= table_case_name(create_info, table_name);
  1214.   file=get_new_handler((TABLE*) 0, create_info->db_type);
  1215. #ifdef NOT_USED
  1216.   /*
  1217.     if there is a technical reason for a handler not to have support
  1218.     for temp. tables this code can be re-enabled.
  1219.     Otherwise, if a handler author has a wish to prohibit usage of
  1220.     temporary tables for his handler he should implement a check in
  1221.     ::create() method
  1222.   */
  1223.   if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
  1224.       (file->table_flags() & HA_NO_TEMP_TABLES))
  1225.   {
  1226.     my_error(ER_ILLEGAL_HA,MYF(0),table_name);
  1227.     DBUG_RETURN(-1);
  1228.   }
  1229. #endif
  1230.   /*
  1231.     If the table character set was not given explicitely,
  1232.     let's fetch the database default character set and
  1233.     apply it to the table.
  1234.   */
  1235.   if (!create_info->default_table_charset)
  1236.   {
  1237.     HA_CREATE_INFO db_info;
  1238.     char  path[FN_REFLEN];
  1239.     /* Abuse build_table_path() to build the path to the db.opt file */
  1240.     build_table_path(path, sizeof(path), db, MY_DB_OPT_FILE, "");
  1241.     load_db_opt(thd, path, &db_info);
  1242.     create_info->default_table_charset= db_info.default_table_charset;
  1243.   }
  1244.   if (mysql_prepare_table(thd, create_info, fields,
  1245.   keys, tmp_table, db_options, file,
  1246.   key_info_buffer, &key_count,
  1247.   select_field_count))
  1248.     DBUG_RETURN(-1);
  1249.       /* Check if table exists */
  1250.   if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
  1251.   {
  1252.     my_snprintf(path, sizeof(path), "%s%s%lx_%lx_%x%s",
  1253. mysql_tmpdir, tmp_file_prefix, current_pid, thd->thread_id,
  1254. thd->tmp_table++, reg_ext);
  1255.     if (lower_case_table_names)
  1256.       my_casedn_str(files_charset_info, path);
  1257.     create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
  1258.   }
  1259.   else
  1260.     build_table_path(path, sizeof(path), db, alias, reg_ext);
  1261.   /* Check if table already exists */
  1262.   if ((create_info->options & HA_LEX_CREATE_TMP_TABLE)
  1263.       && find_temporary_table(thd,db,table_name))
  1264.   {
  1265.     if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
  1266.     {
  1267.       create_info->table_existed= 1; // Mark that table existed
  1268.       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
  1269.                           ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
  1270.                           alias);
  1271.       DBUG_RETURN(0);
  1272.     }
  1273.     my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
  1274.     DBUG_RETURN(-1);
  1275.   }
  1276.   if (wait_if_global_read_lock(thd, 0, 1))
  1277.     DBUG_RETURN(error);
  1278.   VOID(pthread_mutex_lock(&LOCK_open));
  1279.   if (!tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
  1280.   {
  1281.     if (!access(path,F_OK))
  1282.     {
  1283.       if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
  1284.         goto warn;
  1285.       my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
  1286.       goto end;
  1287.     }
  1288.   }
  1289.   /*
  1290.     Check that table with given name does not already
  1291.     exist in any storage engine. In such a case it should
  1292.     be discovered and the error ER_TABLE_EXISTS_ERROR be returned
  1293.     unless user specified CREATE TABLE IF EXISTS
  1294.     The LOCK_open mutex has been locked to make sure no
  1295.     one else is attempting to discover the table. Since
  1296.     it's not on disk as a frm file, no one could be using it!
  1297.   */
  1298.   if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
  1299.   {
  1300.     bool create_if_not_exists =
  1301.       create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
  1302.     if (ha_table_exists_in_engine(thd, db, table_name))
  1303.     {
  1304.       DBUG_PRINT("info", ("Table with same name already existed in handler"));
  1305.       if (create_if_not_exists)
  1306.         goto warn;
  1307.       my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
  1308.       goto end;
  1309.     }
  1310.   }
  1311.   thd->proc_info="creating table";
  1312.   create_info->table_existed= 0; // Mark that table is created
  1313.   if (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE)
  1314.     create_info->data_file_name= create_info->index_file_name= 0;
  1315.   create_info->table_options=db_options;
  1316.   if (rea_create_table(thd, path, db, table_name,
  1317.                        create_info, fields, key_count,
  1318.        key_info_buffer))
  1319.     goto end;
  1320.   if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
  1321.   {
  1322.     /* Open table and put in temporary table list */
  1323.     if (!(open_temporary_table(thd, path, db, table_name, 1)))
  1324.     {
  1325.       (void) rm_temporary_table(create_info->db_type, path);
  1326.       goto end;
  1327.     }
  1328.     thd->tmp_table_used= 1;
  1329.   }
  1330.   if (!tmp_table)
  1331.   {
  1332.     // Must be written before unlock
  1333.     mysql_update_log.write(thd,thd->query, thd->query_length);
  1334.     if (mysql_bin_log.is_open())
  1335.     {
  1336.       thd->clear_error();
  1337.       Query_log_event qinfo(thd, thd->query, thd->query_length,
  1338.     test(create_info->options &
  1339.  HA_LEX_CREATE_TMP_TABLE),
  1340.     FALSE);
  1341.       mysql_bin_log.write(&qinfo);
  1342.     }
  1343.   }
  1344.   error=0;
  1345.   goto end;
  1346. warn:
  1347.   error= 0;
  1348.   push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
  1349.                       ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
  1350.                       alias);
  1351.   create_info->table_existed= 1; // Mark that table existed
  1352. end:
  1353.   VOID(pthread_mutex_unlock(&LOCK_open));
  1354.   start_waiting_global_read_lock(thd);
  1355.   thd->proc_info="After create";
  1356.   DBUG_RETURN(error);
  1357. }
  1358. /*
  1359. ** Give the key name after the first field with an optional '_#' after
  1360. **/
  1361. static bool
  1362. check_if_keyname_exists(const char *name, KEY *start, KEY *end)
  1363. {
  1364.   for (KEY *key=start ; key != end ; key++)
  1365.     if (!my_strcasecmp(system_charset_info,name,key->name))
  1366.       return 1;
  1367.   return 0;
  1368. }
  1369. static char *
  1370. make_unique_key_name(const char *field_name,KEY *start,KEY *end)
  1371. {
  1372.   char buff[MAX_FIELD_NAME],*buff_end;
  1373.   if (!check_if_keyname_exists(field_name,start,end) &&
  1374.       my_strcasecmp(system_charset_info,field_name,primary_key_name))
  1375.     return (char*) field_name; // Use fieldname
  1376.   buff_end=strmake(buff,field_name, sizeof(buff)-4);
  1377.   /*
  1378.     Only 3 chars + '' left, so need to limit to 2 digit
  1379.     This is ok as we can't have more than 100 keys anyway
  1380.   */
  1381.   for (uint i=2 ; i< 100; i++)
  1382.   {
  1383.     *buff_end= '_';
  1384.     int10_to_str(i, buff_end+1, 10);
  1385.     if (!check_if_keyname_exists(buff,start,end))
  1386.       return sql_strdup(buff);
  1387.   }
  1388.   return (char*) "not_specified"; // Should never happen
  1389. }
  1390. /****************************************************************************
  1391. ** Create table from a list of fields and items
  1392. ****************************************************************************/
  1393. TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
  1394.        const char *db, const char *name,
  1395.        List<create_field> *extra_fields,
  1396.        List<Key> *keys,
  1397.        List<Item> *items,
  1398.        MYSQL_LOCK **lock)
  1399. {
  1400.   TABLE tmp_table; // Used during 'create_field()'
  1401.   TABLE *table= 0;
  1402.   tmp_table.table_name=0;
  1403.   uint select_field_count= items->elements;
  1404.   DBUG_ENTER("create_table_from_items");
  1405.   /* Add selected items to field list */
  1406.   List_iterator_fast<Item> it(*items);
  1407.   Item *item;
  1408.   Field *tmp_field;
  1409.   tmp_table.db_create_options=0;
  1410.   tmp_table.null_row=tmp_table.maybe_null=0;
  1411.   tmp_table.blob_ptr_size=portable_sizeof_char_ptr;
  1412.   tmp_table.db_low_byte_first= test(create_info->db_type == DB_TYPE_MYISAM ||
  1413.     create_info->db_type == DB_TYPE_HEAP);
  1414.   while ((item=it++))
  1415.   {
  1416.     create_field *cr_field;
  1417.     Field *field;
  1418.     if (item->type() == Item::FUNC_ITEM)
  1419.       field=item->tmp_table_field(&tmp_table);
  1420.     else
  1421.       field=create_tmp_field(thd, &tmp_table, item, item->type(),
  1422.   (Item ***) 0, &tmp_field, 0, 0, 0);
  1423.     if (!field ||
  1424. !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
  1425.    ((Item_field *)item)->field :
  1426.    (Field*) 0))))
  1427.       DBUG_RETURN(0);
  1428.     extra_fields->push_back(cr_field);
  1429.   }
  1430.   /* create and lock table */
  1431.   /* QQ: create and open should be done atomic ! */
  1432.   /*
  1433.     We don't log the statement, it will be logged later.
  1434.     If this is a HEAP table, the automatic DELETE FROM which is written to the
  1435.     binlog when a HEAP table is opened for the first time since startup, must
  1436.     not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we
  1437.     don't want to delete from it) 2) it would be written before the CREATE
  1438.     TABLE, which is a wrong order. So we keep binary logging disabled when we
  1439.     open_table().
  1440.   */
  1441.   tmp_disable_binlog(thd);
  1442.   if (!mysql_create_table(thd,db,name,create_info,*extra_fields,
  1443.  *keys,0,select_field_count))
  1444.   {
  1445.     if (!(table=open_table(thd,db,name,name,(bool*) 0)))
  1446.       quick_rm_table(create_info->db_type,db,table_case_name(create_info,name));
  1447.   }
  1448.   reenable_binlog(thd);
  1449.   if (!table)
  1450.     DBUG_RETURN(0);
  1451.   table->reginfo.lock_type=TL_WRITE;
  1452.   if (! ((*lock)= mysql_lock_tables(thd, &table, 1, MYSQL_LOCK_IGNORE_FLUSH)))
  1453.   {
  1454.     VOID(pthread_mutex_lock(&LOCK_open));
  1455.     hash_delete(&open_cache,(byte*) table);
  1456.     VOID(pthread_mutex_unlock(&LOCK_open));
  1457.     quick_rm_table(create_info->db_type,db,table_case_name(create_info, name));
  1458.     DBUG_RETURN(0);
  1459.   }
  1460.   table->file->extra(HA_EXTRA_WRITE_CACHE);
  1461.   DBUG_RETURN(table);
  1462. }
  1463. /****************************************************************************
  1464. ** Alter a table definition
  1465. ****************************************************************************/
  1466. bool
  1467. mysql_rename_table(enum db_type base,
  1468.    const char *old_db,
  1469.    const char *old_name,
  1470.    const char *new_db,
  1471.    const char *new_name)
  1472. {
  1473.   char from[FN_REFLEN], to[FN_REFLEN], lc_from[FN_REFLEN], lc_to[FN_REFLEN];
  1474.   char *from_base= from, *to_base= to;
  1475.   char tmp_name[NAME_LEN+1];
  1476.   handler *file=get_new_handler((TABLE*) 0, base);
  1477.   int error=0;
  1478.   DBUG_ENTER("mysql_rename_table");
  1479.   build_table_path(from, sizeof(from), old_db, old_name, "");
  1480.   build_table_path(to, sizeof(to), new_db, new_name, "");
  1481.   /*
  1482.     If lower_case_table_names == 2 (case-preserving but case-insensitive
  1483.     file system) and the storage is not HA_FILE_BASED, we need to provide
  1484.     a lowercase file name, but we leave the .frm in mixed case.
  1485.    */
  1486.   if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED))
  1487.   {
  1488.     strmov(tmp_name, old_name);
  1489.     my_casedn_str(files_charset_info, tmp_name);
  1490.     build_table_path(lc_from, sizeof(lc_from), old_db, tmp_name, "");
  1491.     from_base= lc_from;
  1492.     strmov(tmp_name, new_name);
  1493.     my_casedn_str(files_charset_info, tmp_name);
  1494.     build_table_path(lc_to, sizeof(lc_to), new_db, tmp_name, "");
  1495.     to_base= lc_to;
  1496.   }
  1497.   if (!(error=file->rename_table(from_base, to_base)))
  1498.   {
  1499.     if (rename_file_ext(from,to,reg_ext))
  1500.     {
  1501.       error=my_errno;
  1502.       /* Restore old file name */
  1503.       file->rename_table(to_base, from_base);
  1504.     }
  1505.   }
  1506.   delete file;
  1507.   if (error)
  1508.     my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error);
  1509.   DBUG_RETURN(error != 0);
  1510. }
  1511. /*
  1512.   Force all other threads to stop using the table
  1513.   SYNOPSIS
  1514.     wait_while_table_is_used()
  1515.     thd Thread handler
  1516.     table Table to remove from cache
  1517.     function HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted
  1518. HA_EXTRA_FORCE_REOPEN if table is not be used
  1519.   NOTES
  1520.    When returning, the table will be unusable for other threads until
  1521.    the table is closed.
  1522.   PREREQUISITES
  1523.     Lock on LOCK_open
  1524.     Win32 clients must also have a WRITE LOCK on the table !
  1525. */
  1526. static void wait_while_table_is_used(THD *thd,TABLE *table,
  1527.      enum ha_extra_function function)
  1528. {
  1529.   DBUG_PRINT("enter",("table: %s", table->real_name));
  1530.   DBUG_ENTER("wait_while_table_is_used");
  1531.   safe_mutex_assert_owner(&LOCK_open);
  1532.   VOID(table->file->extra(function));
  1533.   /* Mark all tables that are in use as 'old' */
  1534.   mysql_lock_abort(thd, table); // end threads waiting on lock
  1535.   /* Wait until all there are no other threads that has this table open */
  1536.   remove_table_from_cache(thd,table->table_cache_key,
  1537.                           table->real_name, RTFC_WAIT_OTHER_THREAD_FLAG);
  1538.   DBUG_VOID_RETURN;
  1539. }
  1540. /*
  1541.   Close a cached table
  1542.   SYNOPSIS
  1543.     close_cached_table()
  1544.     thd Thread handler
  1545.     table Table to remove from cache
  1546.   NOTES
  1547.     Function ends by signaling threads waiting for the table to try to
  1548.     reopen the table.
  1549.   PREREQUISITES
  1550.     Lock on LOCK_open
  1551.     Win32 clients must also have a WRITE LOCK on the table !
  1552. */
  1553. static bool close_cached_table(THD *thd, TABLE *table)
  1554. {
  1555.   DBUG_ENTER("close_cached_table");
  1556.   wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DELETE);
  1557.   /* Close lock if this is not got with LOCK TABLES */
  1558.   if (thd->lock)
  1559.   {
  1560.     mysql_unlock_tables(thd, thd->lock);
  1561.     thd->lock=0; // Start locked threads
  1562.   }
  1563.   /* Close all copies of 'table'.  This also frees all LOCK TABLES lock */
  1564.   thd->open_tables=unlink_open_table(thd,thd->open_tables,table);
  1565.   /* When lock on LOCK_open is freed other threads can continue */
  1566.   pthread_cond_broadcast(&COND_refresh);
  1567.   DBUG_RETURN(0);
  1568. }
  1569. static int send_check_errmsg(THD *thd, TABLE_LIST* table,
  1570.      const char* operator_name, const char* errmsg)
  1571. {
  1572.   Protocol *protocol= thd->protocol;
  1573.   protocol->prepare_for_resend();
  1574.   protocol->store(table->alias, system_charset_info);
  1575.   protocol->store((char*) operator_name, system_charset_info);
  1576.   protocol->store("error", 5, system_charset_info);
  1577.   protocol->store(errmsg, system_charset_info);
  1578.   thd->net.last_error[0]=0;
  1579.   if (protocol->write())
  1580.     return -1;
  1581.   return 1;
  1582. }
  1583. static int prepare_for_restore(THD* thd, TABLE_LIST* table,
  1584.        HA_CHECK_OPT *check_opt)
  1585. {
  1586.   DBUG_ENTER("prepare_for_restore");
  1587.   if (table->table) // do not overwrite existing tables on restore
  1588.   {
  1589.     DBUG_RETURN(send_check_errmsg(thd, table, "restore",
  1590.   "table exists, will not overwrite on restore"
  1591.   ));
  1592.   }
  1593.   else
  1594.   {
  1595.     char* backup_dir= thd->lex->backup_dir;
  1596.     char src_path[FN_REFLEN], dst_path[FN_REFLEN];
  1597.     char* table_name = table->real_name;
  1598.     char* db = thd->db ? thd->db : table->db;
  1599.     if (fn_format_relative_to_data_home(src_path, table_name, backup_dir,
  1600. reg_ext))
  1601.       DBUG_RETURN(-1); // protect buffer overflow
  1602.     my_snprintf(dst_path, sizeof(dst_path), "%s%s/%s",
  1603. mysql_real_data_home, db, table_name);
  1604.     if (lock_and_wait_for_table_name(thd,table))
  1605.       DBUG_RETURN(-1);
  1606.     if (my_copy(src_path,
  1607. fn_format(dst_path, dst_path,"", reg_ext, 4),
  1608. MYF(MY_WME)))
  1609.     {
  1610.       pthread_mutex_lock(&LOCK_open);
  1611.       unlock_table_name(thd, table);
  1612.       pthread_mutex_unlock(&LOCK_open);
  1613.       DBUG_RETURN(send_check_errmsg(thd, table, "restore",
  1614.     "Failed copying .frm file"));
  1615.     }
  1616.     if (mysql_truncate(thd, table, 1))
  1617.     {
  1618.       pthread_mutex_lock(&LOCK_open);
  1619.       unlock_table_name(thd, table);
  1620.       pthread_mutex_unlock(&LOCK_open);
  1621.       DBUG_RETURN(send_check_errmsg(thd, table, "restore",
  1622.     "Failed generating table from .frm file"));
  1623.     }
  1624.   }
  1625.   /*
  1626.     Now we should be able to open the partially restored table
  1627.     to finish the restore in the handler later on
  1628.   */
  1629.   if (!(table->table = reopen_name_locked_table(thd, table)))
  1630.   {
  1631.     pthread_mutex_lock(&LOCK_open);
  1632.     unlock_table_name(thd, table);
  1633.     pthread_mutex_unlock(&LOCK_open);
  1634.   }
  1635.   DBUG_RETURN(0);
  1636. }
  1637. static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
  1638.       HA_CHECK_OPT *check_opt)
  1639. {
  1640.   int error= 0;
  1641.   TABLE tmp_table, *table;
  1642.   DBUG_ENTER("prepare_for_repair");
  1643.   if (!(check_opt->sql_flags & TT_USEFRM))
  1644.     DBUG_RETURN(0);
  1645.   if (!(table= table_list->table)) /* if open_ltable failed */
  1646.   {
  1647.     char name[FN_REFLEN];
  1648.     build_table_path(name, sizeof(name), table_list->db,
  1649.                      table_list->real_name, "");
  1650.     if (openfrm(name, "", 0, 0, 0, &tmp_table))
  1651.       DBUG_RETURN(0); // Can't open frm file
  1652.     table= &tmp_table;
  1653.   }
  1654.   /*
  1655.     User gave us USE_FRM which means that the header in the index file is
  1656.     trashed.
  1657.     In this case we will try to fix the table the following way:
  1658.     - Rename the data file to a temporary name
  1659.     - Truncate the table
  1660.     - Replace the new data file with the old one
  1661.     - Run a normal repair using the new index file and the old data file
  1662.   */
  1663.   char from[FN_REFLEN],tmp[FN_REFLEN+32];
  1664.   const char **ext= table->file->bas_ext();
  1665.   MY_STAT stat_info;
  1666.   /*
  1667.     Check if this is a table type that stores index and data separately,
  1668.     like ISAM or MyISAM
  1669.   */
  1670.   if (!ext[0] || !ext[1])
  1671.     goto end; // No data file
  1672.   strxmov(from, table->path, ext[1], NullS); // Name of data file
  1673.   if (!my_stat(from, &stat_info, MYF(0)))
  1674.     goto end; // Can't use USE_FRM flag
  1675.   my_snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
  1676.       from, current_pid, thd->thread_id);
  1677.   /* If we could open the table, close it */
  1678.   if (table_list->table)
  1679.   {
  1680.     pthread_mutex_lock(&LOCK_open);
  1681.     close_cached_table(thd, table);
  1682.     pthread_mutex_unlock(&LOCK_open);
  1683.   }
  1684.   if (lock_and_wait_for_table_name(thd,table_list))
  1685.   {
  1686.     error= -1;
  1687.     goto end;
  1688.   }
  1689.   if (my_rename(from, tmp, MYF(MY_WME)))
  1690.   {
  1691.     pthread_mutex_lock(&LOCK_open);
  1692.     unlock_table_name(thd, table_list);
  1693.     pthread_mutex_unlock(&LOCK_open);
  1694.     error= send_check_errmsg(thd, table_list, "repair",
  1695.      "Failed renaming data file");
  1696.     goto end;
  1697.   }
  1698.   if (mysql_truncate(thd, table_list, 1))
  1699.   {
  1700.     pthread_mutex_lock(&LOCK_open);
  1701.     unlock_table_name(thd, table_list);
  1702.     pthread_mutex_unlock(&LOCK_open);
  1703.     error= send_check_errmsg(thd, table_list, "repair",
  1704.      "Failed generating table from .frm file");
  1705.     goto end;
  1706.   }
  1707.   if (my_rename(tmp, from, MYF(MY_WME)))
  1708.   {
  1709.     pthread_mutex_lock(&LOCK_open);
  1710.     unlock_table_name(thd, table_list);
  1711.     pthread_mutex_unlock(&LOCK_open);
  1712.     error= send_check_errmsg(thd, table_list, "repair",
  1713.      "Failed restoring .MYD file");
  1714.     goto end;
  1715.   }
  1716.   /*
  1717.     Now we should be able to open the partially repaired table
  1718.     to finish the repair in the handler later on.
  1719.   */
  1720.   if (!(table_list->table = reopen_name_locked_table(thd, table_list)))
  1721.   {
  1722.     pthread_mutex_lock(&LOCK_open);
  1723.     unlock_table_name(thd, table_list);
  1724.     pthread_mutex_unlock(&LOCK_open);
  1725.   }
  1726. end:
  1727.   if (table == &tmp_table)
  1728.     closefrm(table); // Free allocated memory
  1729.   DBUG_RETURN(error);
  1730. }
  1731. /*
  1732.   RETURN VALUES
  1733.     0   Message sent to net (admin operation went ok)
  1734.    -1   Message should be sent by caller 
  1735.         (admin operation or network communication failed)
  1736. */
  1737. static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
  1738.      HA_CHECK_OPT* check_opt,
  1739.      const char *operator_name,
  1740.      thr_lock_type lock_type,
  1741.      bool open_for_modify,
  1742.      uint extra_open_options,
  1743.      int (*prepare_func)(THD *, TABLE_LIST *,
  1744.  HA_CHECK_OPT *),
  1745.      int (handler::*operator_func)
  1746.      (THD *, HA_CHECK_OPT *))
  1747. {
  1748.   TABLE_LIST *table;
  1749.   List<Item> field_list;
  1750.   Item *item;
  1751.   Protocol *protocol= thd->protocol;
  1752.   DBUG_ENTER("mysql_admin_table");
  1753.   field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
  1754.   item->maybe_null = 1;
  1755.   field_list.push_back(item = new Item_empty_string("Op", 10));
  1756.   item->maybe_null = 1;
  1757.   field_list.push_back(item = new Item_empty_string("Msg_type", 10));
  1758.   item->maybe_null = 1;
  1759.   field_list.push_back(item = new Item_empty_string("Msg_text", 255));
  1760.   item->maybe_null = 1;
  1761.   if (protocol->send_fields(&field_list, 1))
  1762.     DBUG_RETURN(-1);
  1763.   mysql_ha_flush(thd, tables, MYSQL_HA_CLOSE_FINAL, FALSE);
  1764.   for (table = tables; table; table = table->next)
  1765.   {
  1766.     char table_name[NAME_LEN*2+2];
  1767.     char* db = table->db;
  1768.     bool fatal_error=0;
  1769.     strxmov(table_name, db, ".", table->real_name, NullS);
  1770.     thd->open_options|= extra_open_options;
  1771.     table->table = open_ltable(thd, table, lock_type);
  1772. #ifdef EMBEDDED_LIBRARY
  1773.     thd->net.last_errno= 0;  // these errors shouldn't get client
  1774. #endif
  1775.     thd->open_options&= ~extra_open_options;
  1776.     if (prepare_func)
  1777.     {
  1778.       switch ((*prepare_func)(thd, table, check_opt)) {
  1779.       case  1:           // error, message written to net
  1780.         close_thread_tables(thd);
  1781.         continue;
  1782.       case -1:           // error, message could be written to net
  1783.         goto err;
  1784.       default:           // should be 0 otherwise
  1785.         ;
  1786.       }
  1787.     }
  1788.     if (!table->table)
  1789.     {
  1790.       const char *err_msg;
  1791.       protocol->prepare_for_resend();
  1792.       protocol->store(table_name, system_charset_info);
  1793.       protocol->store(operator_name, system_charset_info);
  1794.       protocol->store("error",5, system_charset_info);
  1795.       if (!(err_msg=thd->net.last_error))
  1796. err_msg=ER(ER_CHECK_NO_SUCH_TABLE);
  1797.       protocol->store(err_msg, system_charset_info);
  1798.       thd->net.last_error[0]=0;
  1799.       if (protocol->write())
  1800. goto err;
  1801.       continue;
  1802.     }
  1803.     table->table->pos_in_table_list= table;
  1804.     if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
  1805.     {
  1806.       char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
  1807.       protocol->prepare_for_resend();
  1808.       protocol->store(table_name, system_charset_info);
  1809.       protocol->store(operator_name, system_charset_info);
  1810.       protocol->store("error", 5, system_charset_info);
  1811.       my_snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY), table_name);
  1812.       protocol->store(buff, system_charset_info);
  1813.       close_thread_tables(thd);
  1814.       table->table=0; // For query cache
  1815.       if (protocol->write())
  1816. goto err;
  1817.       continue;
  1818.     }
  1819.     /* Close all instances of the table to allow repair to rename files */
  1820.     if (lock_type == TL_WRITE && table->table->version)
  1821.     {
  1822.       pthread_mutex_lock(&LOCK_open);
  1823.       const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
  1824.       "Waiting to get writelock");
  1825.       mysql_lock_abort(thd,table->table);
  1826.       remove_table_from_cache(thd, table->table->table_cache_key,
  1827.                               table->table->real_name,
  1828.                               RTFC_WAIT_OTHER_THREAD_FLAG |
  1829.                               RTFC_CHECK_KILLED_FLAG);
  1830.       thd->exit_cond(old_message);
  1831.       if (thd->killed)
  1832. goto err;
  1833.       /* Flush entries in the query cache involving this table. */
  1834.       query_cache_invalidate3(thd, table->table, 0);
  1835.       open_for_modify= 0;
  1836.     }
  1837.     int result_code = (table->table->file->*operator_func)(thd, check_opt);
  1838. #ifdef EMBEDDED_LIBRARY
  1839.     thd->net.last_errno= 0;  // these errors shouldn't get client
  1840. #endif
  1841.     protocol->prepare_for_resend();
  1842.     protocol->store(table_name, system_charset_info);
  1843.     protocol->store(operator_name, system_charset_info);
  1844. send_result_message:
  1845.     DBUG_PRINT("info", ("result_code: %d", result_code));
  1846.     switch (result_code) {
  1847.     case HA_ADMIN_NOT_IMPLEMENTED:
  1848.       {
  1849. char buf[ERRMSGSIZE+20];
  1850. uint length=my_snprintf(buf, ERRMSGSIZE,
  1851. ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
  1852. protocol->store("note", 4, system_charset_info);
  1853. protocol->store(buf, length, system_charset_info);
  1854.       }
  1855.       break;
  1856.     case HA_ADMIN_OK:
  1857.       protocol->store("status", 6, system_charset_info);
  1858.       protocol->store("OK",2, system_charset_info);
  1859.       break;
  1860.     case HA_ADMIN_FAILED:
  1861.       protocol->store("status", 6, system_charset_info);
  1862.       protocol->store("Operation failed",16, system_charset_info);
  1863.       break;
  1864.     case HA_ADMIN_REJECT:
  1865.       protocol->store("status", 6, system_charset_info);
  1866.       protocol->store("Operation need committed state",30, system_charset_info);
  1867.       open_for_modify= FALSE;
  1868.       break;
  1869.     case HA_ADMIN_ALREADY_DONE:
  1870.       protocol->store("status", 6, system_charset_info);
  1871.       protocol->store("Table is already up to date", 27, system_charset_info);
  1872.       break;
  1873.     case HA_ADMIN_CORRUPT:
  1874.       protocol->store("error", 5, system_charset_info);
  1875.       protocol->store("Corrupt", 7, system_charset_info);
  1876.       fatal_error=1;
  1877.       break;
  1878.     case HA_ADMIN_INVALID:
  1879.       protocol->store("error", 5, system_charset_info);
  1880.       protocol->store("Invalid argument",16, system_charset_info);
  1881.       break;
  1882.     case HA_ADMIN_TRY_ALTER:
  1883.     {
  1884.       /*
  1885.         This is currently used only by InnoDB. ha_innobase::optimize() answers
  1886.         "try with alter", so here we close the table, do an ALTER TABLE,
  1887.         reopen the table and do ha_innobase::analyze() on it.
  1888.       */
  1889.       close_thread_tables(thd);
  1890.       TABLE_LIST *save_next= table->next;
  1891.       table->next= 0;
  1892.       tmp_disable_binlog(thd); // binlogging is done by caller if wanted
  1893.       result_code= mysql_recreate_table(thd, table, 0);
  1894.       reenable_binlog(thd);
  1895.       close_thread_tables(thd);
  1896.       if (!result_code) // recreation went ok
  1897.       {
  1898.         if ((table->table= open_ltable(thd, table, lock_type)) &&
  1899.             ((result_code= table->table->file->analyze(thd, check_opt)) > 0))
  1900.           result_code= 0; // analyze went ok
  1901.       }
  1902.       if (result_code) // either mysql_recreate_table or analyze failed
  1903.       {
  1904.         const char *err_msg;
  1905.         if ((err_msg= thd->net.last_error))
  1906.         {
  1907.           if (!thd->vio_ok())
  1908.           {
  1909.             sql_print_error(err_msg);
  1910.           }
  1911.           else
  1912.           {
  1913.             /* Hijack the row already in-progress. */
  1914.             protocol->store("error", 5, system_charset_info);
  1915.             protocol->store(err_msg, system_charset_info);
  1916.             (void)protocol->write();
  1917.             /* Start off another row for HA_ADMIN_FAILED */
  1918.             protocol->prepare_for_resend();
  1919.             protocol->store(table_name, system_charset_info);
  1920.             protocol->store(operator_name, system_charset_info);
  1921.           }
  1922.         }
  1923.       }
  1924.       result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
  1925.       table->next= save_next;
  1926.       goto send_result_message;
  1927.     }
  1928.     default: // Probably HA_ADMIN_INTERNAL_ERROR
  1929.       protocol->store("error", 5, system_charset_info);
  1930.       protocol->store("Unknown - internal error during operation", 41
  1931.       , system_charset_info);
  1932.       fatal_error=1;
  1933.       break;
  1934.     }
  1935.     if (fatal_error)
  1936.       table->table->version=0; // Force close of table
  1937.     else if (open_for_modify)
  1938.     {
  1939.       pthread_mutex_lock(&LOCK_open);
  1940.       remove_table_from_cache(thd, table->table->table_cache_key,
  1941.       table->table->real_name, RTFC_NO_FLAG);
  1942.       pthread_mutex_unlock(&LOCK_open);
  1943.       /* May be something modified consequently we have to invalidate cache */
  1944.       query_cache_invalidate3(thd, table->table, 0);
  1945.     }
  1946.     close_thread_tables(thd);
  1947.     table->table=0; // For query cache
  1948.     if (protocol->write())
  1949.       goto err;
  1950.   }
  1951.   send_eof(thd);
  1952.   DBUG_RETURN(0);
  1953.  err:
  1954.   close_thread_tables(thd); // Shouldn't be needed
  1955.   if (table)
  1956.     table->table=0;
  1957.   DBUG_RETURN(-1);
  1958. }
  1959. int mysql_backup_table(THD* thd, TABLE_LIST* table_list)
  1960. {
  1961.   DBUG_ENTER("mysql_backup_table");
  1962.   DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
  1963. "backup", TL_READ, 0, 0, 0,
  1964. &handler::backup));
  1965. }
  1966. int mysql_restore_table(THD* thd, TABLE_LIST* table_list)
  1967. {
  1968.   DBUG_ENTER("mysql_restore_table");
  1969.   DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
  1970. "restore", TL_WRITE, 1, 0,
  1971. &prepare_for_restore,
  1972. &handler::restore));
  1973. }
  1974. int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
  1975. {
  1976.   DBUG_ENTER("mysql_repair_table");
  1977.   DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
  1978. "repair", TL_WRITE, 1, HA_OPEN_FOR_REPAIR,
  1979. &prepare_for_repair,
  1980. &handler::repair));
  1981. }
  1982. int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
  1983. {
  1984.   DBUG_ENTER("mysql_optimize_table");
  1985.   DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
  1986. "optimize", TL_WRITE, 1,0,0,
  1987. &handler::optimize));
  1988. }
  1989. /*
  1990.   Assigned specified indexes for a table into key cache
  1991.   SYNOPSIS
  1992.     mysql_assign_to_keycache()
  1993.     thd Thread object
  1994.     tables Table list (one table only)
  1995.   RETURN VALUES
  1996.     0   ok
  1997.    -1   error
  1998. */
  1999. int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
  2000.      LEX_STRING *key_cache_name)
  2001. {
  2002.   HA_CHECK_OPT check_opt;
  2003.   KEY_CACHE *key_cache;
  2004.   DBUG_ENTER("mysql_assign_to_keycache");
  2005.   check_opt.init();
  2006.   pthread_mutex_lock(&LOCK_global_system_variables);
  2007.   if (!(key_cache= get_key_cache(key_cache_name)))
  2008.   {
  2009.     pthread_mutex_unlock(&LOCK_global_system_variables);
  2010.     my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str);
  2011.     DBUG_RETURN(-1);
  2012.   }
  2013.   pthread_mutex_unlock(&LOCK_global_system_variables);
  2014.   check_opt.key_cache= key_cache;
  2015.   DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt,
  2016. "assign_to_keycache", TL_READ_NO_INSERT, 0,
  2017. 0, 0, &handler::assign_to_keycache));
  2018. }
  2019. /*
  2020.   Reassign all tables assigned to a key cache to another key cache
  2021.   SYNOPSIS
  2022.     reassign_keycache_tables()
  2023.     thd Thread object
  2024.     src_cache Reference to the key cache to clean up
  2025.     dest_cache New key cache
  2026.   NOTES
  2027.     This is called when one sets a key cache size to zero, in which
  2028.     case we have to move the tables associated to this key cache to
  2029.     the "default" one.
  2030.     One has to ensure that one never calls this function while
  2031.     some other thread is changing the key cache. This is assured by
  2032.     the caller setting src_cache->in_init before calling this function.
  2033.     We don't delete the old key cache as there may still be pointers pointing
  2034.     to it for a while after this function returns.
  2035.  RETURN VALUES
  2036.     0   ok
  2037. */
  2038. int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
  2039.      KEY_CACHE *dst_cache)
  2040. {
  2041.   DBUG_ENTER("reassign_keycache_tables");
  2042.   DBUG_ASSERT(src_cache != dst_cache);
  2043.   DBUG_ASSERT(src_cache->in_init);
  2044.   src_cache->param_buff_size= 0; // Free key cache
  2045.   ha_resize_key_cache(src_cache);
  2046.   ha_change_key_cache(src_cache, dst_cache);
  2047.   DBUG_RETURN(0);
  2048. }
  2049. /*
  2050.   Preload specified indexes for a table into key cache
  2051.   SYNOPSIS
  2052.     mysql_preload_keys()
  2053.     thd Thread object
  2054.     tables Table list (one table only)
  2055.   RETURN VALUES
  2056.     0   ok
  2057.    -1   error
  2058. */
  2059. int mysql_preload_keys(THD* thd, TABLE_LIST* tables)
  2060. {
  2061.   DBUG_ENTER("mysql_preload_keys");
  2062.   DBUG_RETURN(mysql_admin_table(thd, tables, 0,
  2063. "preload_keys", TL_READ, 0, 0, 0,
  2064. &handler::preload_keys));
  2065. }
  2066. /*
  2067.   Create a table identical to the specified table
  2068.   SYNOPSIS
  2069.     mysql_create_like_table()
  2070.     thd Thread object
  2071.     table Table list (one table only)
  2072.     create_info Create info
  2073.     table_ident Src table_ident
  2074.   RETURN VALUES
  2075.     0   ok
  2076.     -1 error
  2077. */
  2078. int mysql_create_like_table(THD* thd, TABLE_LIST* table,
  2079.     HA_CREATE_INFO *create_info,
  2080.     Table_ident *table_ident)
  2081. {
  2082.   TABLE **tmp_table;
  2083.   char src_path[FN_REFLEN], dst_path[FN_REFLEN];
  2084.   char *db= table->db;
  2085.   char *table_name= table->real_name;
  2086.   char *src_db;
  2087.   char *src_table= table_ident->table.str;
  2088.   int  err, res= -1;
  2089.   TABLE_LIST src_tables_list;
  2090.   DBUG_ENTER("mysql_create_like_table");
  2091.   src_db= table_ident->db.str ? table_ident->db.str : thd->db;
  2092.   /*
  2093.     Validate the source table
  2094.   */
  2095.   if (table_ident->table.length > NAME_LEN ||
  2096.       (table_ident->table.length &&
  2097.        check_table_name(src_table,table_ident->table.length)))
  2098.   {
  2099.     my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table);
  2100.     DBUG_RETURN(-1);
  2101.   }
  2102.   if (!src_db || check_db_name(src_db))
  2103.   {
  2104.     my_error(ER_WRONG_DB_NAME, MYF(0), src_db ? src_db : "NULL");
  2105.     DBUG_RETURN(-1);
  2106.   }
  2107.   src_tables_list.db= src_db;
  2108.   src_tables_list.real_name= src_table;
  2109.   src_tables_list.next= 0;
  2110.   if (lock_and_wait_for_table_name(thd, &src_tables_list))
  2111.     goto err;
  2112.   if ((tmp_table= find_temporary_table(thd, src_db, src_table)))
  2113.     strxmov(src_path, (*tmp_table)->path, reg_ext, NullS);
  2114.   else
  2115.   {
  2116.     strxmov(src_path, mysql_data_home, "/", src_db, "/", src_table,
  2117.     reg_ext, NullS);
  2118.     /* Resolve symlinks (for windows) */
  2119.     fn_format(src_path, src_path, "", "", MYF(MY_UNPACK_FILENAME));
  2120.     if (lower_case_table_names)
  2121.       my_casedn_str(files_charset_info, src_path);
  2122.     if (access(src_path, F_OK))
  2123.     {
  2124.       my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table);
  2125.       goto err;
  2126.     }
  2127.   }
  2128.   /*
  2129.     Validate the destination table
  2130.     skip the destination table name checking as this is already
  2131.     validated.
  2132.   */
  2133.   if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
  2134.   {
  2135.     if (find_temporary_table(thd, db, table_name))
  2136.       goto table_exists;
  2137.     my_snprintf(dst_path, sizeof(dst_path), "%s%s%lx_%lx_%x%s",
  2138. mysql_tmpdir, tmp_file_prefix, current_pid,
  2139. thd->thread_id, thd->tmp_table++, reg_ext);
  2140.     if (lower_case_table_names)
  2141.       my_casedn_str(files_charset_info, dst_path);
  2142.     create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
  2143.   }
  2144.   else
  2145.   {
  2146.     strxmov(dst_path, mysql_data_home, "/", db, "/", table_name,
  2147.     reg_ext, NullS);
  2148.     fn_format(dst_path, dst_path, "", "", MYF(MY_UNPACK_FILENAME));
  2149.     if (!access(dst_path, F_OK))
  2150.       goto table_exists;
  2151.   }
  2152.   /*
  2153.     Create a new table by copying from source table
  2154.   */
  2155.   if (my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE)))
  2156.   {
  2157.     if (my_errno == ENOENT)
  2158.       my_error(ER_BAD_DB_ERROR,MYF(0),db);
  2159.     else
  2160.       my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
  2161.     goto err;
  2162.   }
  2163.   /*
  2164.     As mysql_truncate don't work on a new table at this stage of
  2165.     creation, instead create the table directly (for both normal
  2166.     and temporary tables).
  2167.   */
  2168.   *fn_ext(dst_path)= 0;
  2169.   err= ha_create_table(dst_path, create_info, 1);
  2170.   if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
  2171.   {
  2172.     if (err || !open_temporary_table(thd, dst_path, db, table_name, 1))
  2173.     {
  2174.       (void) rm_temporary_table(create_info->db_type,
  2175. dst_path); /* purecov: inspected */
  2176.       goto err;     /* purecov: inspected */
  2177.     }
  2178.   }
  2179.   else if (err)
  2180.   {
  2181.     (void) quick_rm_table(create_info->db_type, db,
  2182.   table_name); /* purecov: inspected */
  2183.     goto err;     /* purecov: inspected */
  2184.   }
  2185.   // Must be written before unlock
  2186.   mysql_update_log.write(thd,thd->query, thd->query_length);
  2187.   if (mysql_bin_log.is_open())
  2188.   {
  2189.     thd->clear_error();
  2190.     Query_log_event qinfo(thd, thd->query, thd->query_length,
  2191.   test(create_info->options &
  2192.        HA_LEX_CREATE_TMP_TABLE), 
  2193.   FALSE);
  2194.     mysql_bin_log.write(&qinfo);
  2195.   }
  2196.   res= 0;
  2197.   goto err;
  2198. table_exists:
  2199.   if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
  2200.   {
  2201.     char warn_buff[MYSQL_ERRMSG_SIZE];
  2202.     my_snprintf(warn_buff, sizeof(warn_buff),
  2203. ER(ER_TABLE_EXISTS_ERROR), table_name);
  2204.     push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
  2205.  ER_TABLE_EXISTS_ERROR,warn_buff);
  2206.     res= 0;
  2207.   }
  2208.   else
  2209.     my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
  2210. err:
  2211.   pthread_mutex_lock(&LOCK_open);
  2212.   unlock_table_name(thd, &src_tables_list);
  2213.   pthread_mutex_unlock(&LOCK_open);
  2214.   DBUG_RETURN(res);
  2215. }
  2216. int mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
  2217. {
  2218. #ifdef OS2
  2219.   thr_lock_type lock_type = TL_WRITE;
  2220. #else
  2221.   thr_lock_type lock_type = TL_READ_NO_INSERT;
  2222. #endif
  2223.   DBUG_ENTER("mysql_analyze_table");
  2224.   DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
  2225. "analyze", lock_type, 1,0,0,
  2226. &handler::analyze));
  2227. }
  2228. int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
  2229. {
  2230. #ifdef OS2
  2231.   thr_lock_type lock_type = TL_WRITE;
  2232. #else
  2233.   thr_lock_type lock_type = TL_READ_NO_INSERT;
  2234. #endif
  2235.   DBUG_ENTER("mysql_check_table");
  2236.   DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
  2237. "check", lock_type,
  2238. 0, HA_OPEN_FOR_REPAIR, 0,
  2239. &handler::check));
  2240. }
  2241. /* table_list should contain just one table */
  2242. static int
  2243. mysql_discard_or_import_tablespace(THD *thd,
  2244.                                    TABLE_LIST *table_list,
  2245.                                    enum tablespace_op_type tablespace_op)
  2246. {
  2247.   TABLE *table;
  2248.   my_bool discard;
  2249.   int error;
  2250.   DBUG_ENTER("mysql_discard_or_import_tablespace");
  2251.   /*
  2252.     Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
  2253.     ALTER TABLE
  2254.   */
  2255.   thd->proc_info="discard_or_import_tablespace";
  2256.   discard= test(tablespace_op == DISCARD_TABLESPACE);
  2257.  /*
  2258.    We set this flag so that ha_innobase::open and ::external_lock() do
  2259.    not complain when we lock the table
  2260.  */
  2261.   thd->tablespace_op= TRUE;
  2262.   if (!(table=open_ltable(thd,table_list,TL_WRITE)))
  2263.   {
  2264.     thd->tablespace_op=FALSE;
  2265.     DBUG_RETURN(-1);
  2266.   }
  2267.   error=table->file->discard_or_import_tablespace(discard);
  2268.   thd->proc_info="end";
  2269.   if (error)
  2270.     goto err;
  2271.   /*
  2272.     The 0 in the call below means 'not in a transaction', which means
  2273.     immediate invalidation; that is probably what we wish here
  2274.   */
  2275.   query_cache_invalidate3(thd, table_list, 0);
  2276.   /* The ALTER TABLE is always in its own transaction */
  2277.   error = ha_commit_stmt(thd);
  2278.   if (ha_commit(thd))
  2279.     error=1;
  2280.   if (error)
  2281.     goto err;
  2282.   mysql_update_log.write(thd, thd->query,thd->query_length);
  2283.   if (mysql_bin_log.is_open())
  2284.   {
  2285.     Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
  2286.     mysql_bin_log.write(&qinfo);
  2287.   }
  2288. err:
  2289.   close_thread_tables(thd);
  2290.   thd->tablespace_op=FALSE;
  2291.   if (error == 0)
  2292.   {
  2293.     send_ok(thd);
  2294.     DBUG_RETURN(0);
  2295.   }
  2296.   if (error == HA_ERR_ROW_IS_REFERENCED)
  2297.     my_error(ER_ROW_IS_REFERENCED, MYF(0));
  2298.   
  2299.   DBUG_RETURN(-1);
  2300. }
  2301. #ifdef NOT_USED
  2302. /*
  2303.   CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with
  2304.   the proper arguments.  This isn't very fast but it should work for most
  2305.   cases.
  2306.   One should normally create all indexes with CREATE TABLE or ALTER TABLE.
  2307. */
  2308. int mysql_create_indexes(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
  2309. {
  2310.   List<create_field> fields;
  2311.   List<Alter_drop>   drop;
  2312.   List<Alter_column> alter;
  2313.   HA_CREATE_INFO     create_info;
  2314.   int      rc;
  2315.   uint      idx;
  2316.   uint      db_options;
  2317.   uint      key_count;
  2318.   TABLE      *table;
  2319.   Field      **f_ptr;
  2320.   KEY      *key_info_buffer;
  2321.   char      path[FN_REFLEN+1];
  2322.   DBUG_ENTER("mysql_create_index");
  2323.   /*
  2324.     Try to use online generation of index.
  2325.     This requires that all indexes can be created online.
  2326.     Otherwise, the old alter table procedure is executed.
  2327.     Open the table to have access to the correct table handler.
  2328.   */
  2329.   if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
  2330.     DBUG_RETURN(-1);
  2331.   /*
  2332.     The add_index method takes an array of KEY structs for the new indexes.
  2333.     Preparing a new table structure generates this array.
  2334.     It needs a list with all fields of the table, which does not need to
  2335.     be correct in every respect. The field names are important.
  2336.   */
  2337.   for (f_ptr= table->field; *f_ptr; f_ptr++)
  2338.   {
  2339.     create_field *c_fld= new create_field(*f_ptr, *f_ptr);
  2340.     c_fld->unireg_check= Field::NONE; /*avoid multiple auto_increments*/
  2341.     fields.push_back(c_fld);
  2342.   }
  2343.   bzero((char*) &create_info,sizeof(create_info));
  2344.   create_info.db_type=DB_TYPE_DEFAULT;
  2345.   create_info.default_table_charset= thd->variables.collation_database;
  2346.   db_options= 0;
  2347.   if (mysql_prepare_table(thd, &create_info, fields,
  2348.   keys, /*tmp_table*/ 0, db_options, table->file,
  2349.   key_info_buffer, key_count,
  2350.   /*select_field_count*/ 0))
  2351.     DBUG_RETURN(-1);
  2352.   /*
  2353.     Check if all keys can be generated with the add_index method.
  2354.     If anyone cannot, then take the old way.
  2355.   */
  2356.   for (idx=0; idx< key_count; idx++)
  2357.   {
  2358.     DBUG_PRINT("info", ("creating index %s", key_info_buffer[idx].name));
  2359.     if (!(table->file->index_ddl_flags(key_info_buffer+idx)&
  2360.   (HA_DDL_ONLINE| HA_DDL_WITH_LOCK)))
  2361.       break ;
  2362.   }
  2363.   if ((idx < key_count)|| !key_count)
  2364.   {
  2365.     /* Re-initialize the create_info, which was changed by prepare table. */
  2366.     bzero((char*) &create_info,sizeof(create_info));
  2367.     create_info.db_type=DB_TYPE_DEFAULT;
  2368.     create_info.default_table_charset= thd->variables.collation_database;
  2369.     /* Cleanup the fields list. We do not want to create existing fields. */
  2370.     fields.delete_elements();
  2371.     if (real_alter_table(thd, table_list->db, table_list->real_name,
  2372.  &create_info, table_list, table,
  2373.  fields, keys, drop, alter, 0, (ORDER*)0,
  2374.  ALTER_ADD_INDEX, DUP_ERROR))
  2375.       /* Don't need to free((gptr) key_info_buffer);*/
  2376.       DBUG_RETURN(-1);
  2377.   }
  2378.   else
  2379.   {
  2380.     if (table->file->add_index(table, key_info_buffer, key_count)||
  2381.         build_table_path(path, sizeof(path), table_list->db,
  2382.                          (lower_case_table_names == 2) ?
  2383.                          table_list->alias : table_list->real_name,
  2384.                          reg_ext) == 0 ||
  2385. mysql_create_frm(thd, path, &create_info,
  2386.  fields, key_count, key_info_buffer, table->file))
  2387.       /* don't need to free((gptr) key_info_buffer);*/
  2388.       DBUG_RETURN(-1);
  2389.   }
  2390.   /* don't need to free((gptr) key_info_buffer);*/
  2391.   DBUG_RETURN(0);
  2392. }
  2393. int mysql_drop_indexes(THD *thd, TABLE_LIST *table_list,
  2394.        List<Alter_drop> &drop)
  2395. {
  2396.   List<create_field> fields;
  2397.   List<Key>      keys;
  2398.   List<Alter_column> alter;
  2399.   HA_CREATE_INFO     create_info;
  2400.   uint      idx;
  2401.   uint      db_options;
  2402.   uint      key_count;
  2403.   uint      *key_numbers;
  2404.   TABLE      *table;
  2405.   Field      **f_ptr;
  2406.   KEY      *key_info;
  2407.   KEY      *key_info_buffer;
  2408.   char      path[FN_REFLEN];
  2409.   DBUG_ENTER("mysql_drop_index");
  2410.   /*
  2411.     Try to use online generation of index.
  2412.     This requires that all indexes can be created online.
  2413.     Otherwise, the old alter table procedure is executed.
  2414.     Open the table to have access to the correct table handler.
  2415.   */
  2416.   if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
  2417.     DBUG_RETURN(-1);
  2418.   /*
  2419.     The drop_index method takes an array of key numbers.
  2420.     It cannot get more entries than keys in the table.
  2421.   */
  2422.   key_numbers= (uint*) thd->alloc(sizeof(uint*)*table->keys);
  2423.   key_count= 0;
  2424.   /*
  2425.     Get the number of each key and check if it can be created online.
  2426.   */
  2427.   List_iterator<Alter_drop> drop_it(drop);
  2428.   Alter_drop *drop_key;
  2429.   while ((drop_key= drop_it++))
  2430.   {
  2431.     /* Find the key in the table. */
  2432.     key_info=table->key_info;
  2433.     for (idx=0; idx< table->keys; idx++, key_info++)
  2434.     {
  2435.       if (!my_strcasecmp(system_charset_info, key_info->name, drop_key->name))
  2436. break;
  2437.     }
  2438.     if (idx>= table->keys)
  2439.     {
  2440.       my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), drop_key->name);
  2441.       /*don't need to free((gptr) key_numbers);*/
  2442.       DBUG_RETURN(-1);
  2443.     }
  2444.     /*
  2445.       Check if the key can be generated with the add_index method.
  2446.       If anyone cannot, then take the old way.
  2447.     */
  2448.     DBUG_PRINT("info", ("dropping index %s", table->key_info[idx].name));
  2449.     if (!(table->file->index_ddl_flags(table->key_info+idx)&
  2450.   (HA_DDL_ONLINE| HA_DDL_WITH_LOCK)))
  2451.       break ;
  2452.     key_numbers[key_count++]= idx;
  2453.   }
  2454.   bzero((char*) &create_info,sizeof(create_info));
  2455.   create_info.db_type=DB_TYPE_DEFAULT;
  2456.   create_info.default_table_charset= thd->variables.collation_database;
  2457.   if ((drop_key)|| (drop.elements<= 0))
  2458.   {
  2459.     if (real_alter_table(thd, table_list->db, table_list->real_name,
  2460.  &create_info, table_list, table,
  2461.  fields, keys, drop, alter, 0, (ORDER*)0,
  2462.  ALTER_DROP_INDEX, DUP_ERROR))
  2463.       /*don't need to free((gptr) key_numbers);*/
  2464.       DBUG_RETURN(-1);
  2465.   }
  2466.   else
  2467.   {
  2468.     db_options= 0;
  2469.     if (table->file->drop_index(table, key_numbers, key_count)||
  2470. mysql_prepare_table(thd, &create_info, fields,
  2471.     keys, /*tmp_table*/ 0, db_options, table->file,
  2472.     key_info_buffer, key_count,
  2473.     /*select_field_count*/ 0)||
  2474.         build_table_path(path, sizeof(path), table_list->db,
  2475.                          (lower_case_table_names == 2) ?
  2476.                          table_list->alias : table_list->real_name,
  2477.                          reg_ext) == 0 ||
  2478. mysql_create_frm(thd, path, &create_info,
  2479.  fields, key_count, key_info_buffer, table->file))
  2480.       /*don't need to free((gptr) key_numbers);*/
  2481.       DBUG_RETURN(-1);
  2482.   }
  2483.   /*don't need to free((gptr) key_numbers);*/
  2484.   DBUG_RETURN(0);
  2485. }
  2486. #endif /* NOT_USED */
  2487. /*
  2488.   Alter table
  2489. */
  2490. int mysql_alter_table(THD *thd,char *new_db, char *new_name,
  2491.       HA_CREATE_INFO *create_info,
  2492.       TABLE_LIST *table_list,
  2493.       List<create_field> &fields, List<Key> &keys,
  2494.       uint order_num, ORDER *order,
  2495.       enum enum_duplicates handle_duplicates, bool ignore,
  2496.       ALTER_INFO *alter_info, bool do_send_ok)
  2497. {
  2498.   TABLE *table,*new_table;
  2499.   int error;
  2500.   char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
  2501.   char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
  2502.   char index_file[FN_REFLEN], data_file[FN_REFLEN];
  2503.   ha_rows copied,deleted;
  2504.   ulonglong next_insert_id;
  2505.   uint db_create_options, used_fields;
  2506.   enum db_type old_db_type,new_db_type;
  2507.   DBUG_ENTER("mysql_alter_table");
  2508.   thd->proc_info="init";
  2509.   table_name=table_list->real_name;
  2510.   alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
  2511.   db=table_list->db;
  2512.   if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
  2513.     new_db= db;
  2514.   used_fields=create_info->used_fields;
  2515.   
  2516.   mysql_ha_flush(thd, table_list, MYSQL_HA_CLOSE_FINAL, FALSE);
  2517.   /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
  2518.   if (alter_info->tablespace_op != NO_TABLESPACE_OP)
  2519.     DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
  2520.    alter_info->tablespace_op));
  2521.   if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
  2522.     DBUG_RETURN(-1);
  2523.   /* Check that we are not trying to rename to an existing table */
  2524.   if (new_name)
  2525.   {
  2526.     strmov(new_name_buff,new_name);
  2527.     strmov(new_alias= new_alias_buff, new_name);
  2528.     if (lower_case_table_names)
  2529.     {
  2530.       if (lower_case_table_names != 2)
  2531.       {
  2532. my_casedn_str(files_charset_info, new_name_buff);
  2533. new_alias= new_name; // Create lower case table name
  2534.       }
  2535.       my_casedn_str(files_charset_info, new_name);
  2536.     }
  2537.     if (new_db == db &&
  2538. !my_strcasecmp(table_alias_charset, new_name_buff, table_name))
  2539.     {
  2540.       /*
  2541. Source and destination table names are equal: make later check
  2542. easier.
  2543.       */
  2544.       new_alias= new_name= table_name;
  2545.     }
  2546.     else
  2547.     {
  2548.       if (table->tmp_table)
  2549.       {
  2550. if (find_temporary_table(thd,new_db,new_name_buff))
  2551. {
  2552.   my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff);
  2553.   DBUG_RETURN(-1);
  2554. }
  2555.       }
  2556.       else
  2557.       {
  2558. char dir_buff[FN_REFLEN];
  2559. strxnmov(dir_buff, FN_REFLEN, mysql_real_data_home, new_db, NullS);
  2560. if (!access(fn_format(new_name_buff,new_name_buff,dir_buff,reg_ext,0),
  2561.     F_OK))
  2562. {
  2563.   /* Table will be closed in do_command() */
  2564.   my_error(ER_TABLE_EXISTS_ERROR,MYF(0), new_alias);
  2565.   DBUG_RETURN(-1);
  2566. }
  2567.       }
  2568.     }
  2569.   }
  2570.   else
  2571.   {
  2572.     new_alias= (lower_case_table_names == 2) ? alias : table_name;
  2573.     new_name= table_name;
  2574.   }
  2575.   old_db_type=table->db_type;
  2576.   if (create_info->db_type == DB_TYPE_DEFAULT)
  2577.     create_info->db_type=old_db_type;
  2578.   if ((new_db_type= ha_checktype(create_info->db_type)) !=
  2579.       create_info->db_type)
  2580.   {
  2581.     create_info->db_type= new_db_type;
  2582.     push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
  2583. ER_WARN_USING_OTHER_HANDLER,
  2584. ER(ER_WARN_USING_OTHER_HANDLER),
  2585. ha_get_storage_engine(new_db_type),
  2586. new_name);
  2587.   }
  2588.   if (create_info->row_type == ROW_TYPE_NOT_USED)
  2589.     create_info->row_type=table->row_type;
  2590.   thd->proc_info="setup";
  2591.   if (alter_info->is_simple && !table->tmp_table)
  2592.   {
  2593.     error=0;
  2594.     if (new_name != table_name || new_db != db)
  2595.     {
  2596.       thd->proc_info="rename";
  2597.       VOID(pthread_mutex_lock(&LOCK_open));
  2598.       /* Then do a 'simple' rename of the table */
  2599.       error=0;
  2600.       if (!access(new_name_buff,F_OK))
  2601.       {
  2602. my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name);
  2603. error= -1;
  2604.       }
  2605.       else
  2606.       {
  2607. *fn_ext(new_name)=0;
  2608. close_cached_table(thd, table);
  2609. if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias))
  2610.   error= -1;
  2611.       }
  2612.       VOID(pthread_mutex_unlock(&LOCK_open));
  2613.     }
  2614.     if (!error)
  2615.     {
  2616.       switch (alter_info->keys_onoff) {
  2617.       case LEAVE_AS_IS:
  2618. break;
  2619.       case ENABLE:
  2620. VOID(pthread_mutex_lock(&LOCK_open));
  2621. wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
  2622. VOID(pthread_mutex_unlock(&LOCK_open));
  2623. error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
  2624. /* COND_refresh will be signaled in close_thread_tables() */
  2625. break;
  2626.       case DISABLE:
  2627. VOID(pthread_mutex_lock(&LOCK_open));
  2628. wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
  2629. VOID(pthread_mutex_unlock(&LOCK_open));
  2630. error=table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
  2631. /* COND_refresh will be signaled in close_thread_tables() */
  2632. break;
  2633.       }
  2634.     }
  2635.     if (error == HA_ERR_WRONG_COMMAND)
  2636.     {
  2637.       push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
  2638.   ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
  2639.   table->table_name);
  2640.       error=0;
  2641.     }
  2642.     if (!error)
  2643.     {
  2644.       mysql_update_log.write(thd, thd->query, thd->query_length);
  2645.       if (mysql_bin_log.is_open())
  2646.       {
  2647. thd->clear_error();
  2648. Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
  2649. mysql_bin_log.write(&qinfo);
  2650.       }
  2651.       if (do_send_ok)
  2652.         send_ok(thd);
  2653.     }
  2654.     else if (error > 0)
  2655.     {
  2656.       table->file->print_error(error, MYF(0));
  2657.       error= -1;
  2658.     }
  2659.     table_list->table=0; // For query cache
  2660.     query_cache_invalidate3(thd, table_list, 0);
  2661.     DBUG_RETURN(error);
  2662.   }
  2663.   /* Full alter table */
  2664.   /* let new create options override the old ones */
  2665.   if (!(used_fields & HA_CREATE_USED_MIN_ROWS))
  2666.     create_info->min_rows=table->min_rows;
  2667.   if (!(used_fields & HA_CREATE_USED_MAX_ROWS))
  2668.     create_info->max_rows=table->max_rows;
  2669.   if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
  2670.     create_info->avg_row_length=table->avg_row_length;
  2671.   if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
  2672.     create_info->default_table_charset= table->table_charset;
  2673.   restore_record(table,default_values); // Empty record for DEFAULT
  2674.   List_iterator<Alter_drop> drop_it(alter_info->drop_list);
  2675.   List_iterator<create_field> def_it(fields);
  2676.   List_iterator<Alter_column> alter_it(alter_info->alter_list);
  2677.   List<create_field> create_list; // Add new fields here
  2678.   List<Key> key_list; // Add new keys here
  2679.   create_field *def;
  2680.   /*
  2681.     First collect all fields from table which isn't in drop_list
  2682.   */
  2683.   Field **f_ptr,*field;
  2684.   for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
  2685.   {
  2686.     /* Check if field should be dropped */
  2687.     Alter_drop *drop;
  2688.     drop_it.rewind();
  2689.     while ((drop=drop_it++))
  2690.     {
  2691.       if (drop->type == Alter_drop::COLUMN &&
  2692.   !my_strcasecmp(system_charset_info,field->field_name, drop->name))
  2693.       {
  2694. /* Reset auto_increment value if it was dropped */
  2695. if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
  2696.     !(used_fields & HA_CREATE_USED_AUTO))
  2697. {
  2698.   create_info->auto_increment_value=0;
  2699.   create_info->used_fields|=HA_CREATE_USED_AUTO;
  2700. }
  2701. break;
  2702.       }
  2703.     }
  2704.     if (drop)
  2705.     {
  2706.       drop_it.remove();
  2707.       continue;
  2708.     }
  2709.     /* Check if field is changed */
  2710.     def_it.rewind();
  2711.     while ((def=def_it++))
  2712.     {
  2713.       if (def->change &&
  2714.   !my_strcasecmp(system_charset_info,field->field_name, def->change))
  2715. break;
  2716.     }
  2717.     if (def)
  2718.     { // Field is changed
  2719.       def->field=field;
  2720.       if (!def->after)
  2721.       {
  2722. create_list.push_back(def);
  2723. def_it.remove();
  2724.       }
  2725.     }
  2726.     else
  2727.     { // Use old field value
  2728.       create_list.push_back(def=new create_field(field,field));
  2729.       alter_it.rewind(); // Change default if ALTER
  2730.       Alter_column *alter;
  2731.       while ((alter=alter_it++))
  2732.       {
  2733. if (!my_strcasecmp(system_charset_info,field->field_name, alter->name))
  2734.   break;
  2735.       }
  2736.       if (alter)
  2737.       {
  2738. if (def->sql_type == FIELD_TYPE_BLOB)
  2739. {
  2740.   my_error(ER_BLOB_CANT_HAVE_DEFAULT,MYF(0),def->change);
  2741.   DBUG_RETURN(-1);
  2742. }
  2743. def->def=alter->def; // Use new default
  2744. alter_it.remove();
  2745.       }
  2746.     }
  2747.   }
  2748.   def_it.rewind();
  2749.   List_iterator<create_field> find_it(create_list);
  2750.   while ((def=def_it++)) // Add new columns
  2751.   {
  2752.     if (def->change && ! def->field)
  2753.     {
  2754.       my_error(ER_BAD_FIELD_ERROR,MYF(0),def->change,table_name);
  2755.       DBUG_RETURN(-1);
  2756.     }
  2757.     if (!def->after)
  2758.       create_list.push_back(def);
  2759.     else if (def->after == first_keyword)
  2760.       create_list.push_front(def);
  2761.     else
  2762.     {
  2763.       create_field *find;
  2764.       find_it.rewind();
  2765.       while ((find=find_it++)) // Add new columns
  2766.       {
  2767. if (!my_strcasecmp(system_charset_info,def->after, find->field_name))
  2768.   break;
  2769.       }
  2770.       if (!find)
  2771.       {
  2772. my_error(ER_BAD_FIELD_ERROR,MYF(0),def->after,table_name);
  2773. DBUG_RETURN(-1);
  2774.       }
  2775.       find_it.after(def); // Put element after this
  2776.     }
  2777.   }
  2778.   if (alter_info->alter_list.elements)
  2779.   {
  2780.     my_error(ER_BAD_FIELD_ERROR,MYF(0),alter_info->alter_list.head()->name,
  2781.      table_name);
  2782.     DBUG_RETURN(-1);
  2783.   }
  2784.   if (!create_list.elements)
  2785.   {
  2786.     my_error(ER_CANT_REMOVE_ALL_FIELDS,MYF(0));
  2787.     DBUG_RETURN(-1);
  2788.   }
  2789.   /*
  2790.     Collect all keys which isn't in drop list. Add only those
  2791.     for which some fields exists.
  2792.   */
  2793.   List_iterator<Key> key_it(keys);
  2794.   List_iterator<create_field> field_it(create_list);
  2795.   List<key_part_spec> key_parts;
  2796.   KEY *key_info=table->key_info;
  2797.   for (uint i=0 ; i < table->keys ; i++,key_info++)
  2798.   {
  2799.     char *key_name= key_info->name;
  2800.     Alter_drop *drop;
  2801.     drop_it.rewind();
  2802.     while ((drop=drop_it++))
  2803.     {
  2804.       if (drop->type == Alter_drop::KEY &&
  2805.   !my_strcasecmp(system_charset_info,key_name, drop->name))
  2806. break;
  2807.     }
  2808.     if (drop)
  2809.     {
  2810.       drop_it.remove();
  2811.       continue;
  2812.     }
  2813.     KEY_PART_INFO *key_part= key_info->key_part;
  2814.     key_parts.empty();
  2815.     for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
  2816.     {
  2817.       if (!key_part->field)
  2818. continue; // Wrong field (from UNIREG)
  2819.       const char *key_part_name=key_part->field->field_name;
  2820.       create_field *cfield;
  2821.       field_it.rewind();
  2822.       while ((cfield=field_it++))
  2823.       {
  2824. if (cfield->change)
  2825. {
  2826.   if (!my_strcasecmp(system_charset_info, key_part_name,
  2827.      cfield->change))
  2828.     break;
  2829. }
  2830. else if (!my_strcasecmp(system_charset_info,
  2831. key_part_name, cfield->field_name))
  2832.   break;
  2833.       }
  2834.       if (!cfield)
  2835. continue; // Field is removed
  2836.       uint key_part_length=key_part->length;
  2837.       if (cfield->field) // Not new field
  2838.       { // Check if sub key
  2839. if (cfield->field->type() != FIELD_TYPE_BLOB &&
  2840.     (cfield->field->pack_length() == key_part_length ||
  2841.      cfield->length <= key_part_length /
  2842.        key_part->field->charset()->mbmaxlen))
  2843.   key_part_length=0; // Use whole field
  2844.       }
  2845.       key_part_length /= key_part->field->charset()->mbmaxlen;
  2846.       key_parts.push_back(new key_part_spec(cfield->field_name,
  2847.     key_part_length));
  2848.     }
  2849.     if (key_parts.elements)
  2850.       key_list.push_back(new Key(key_info->flags & HA_SPATIAL ? Key::SPATIAL :
  2851.  (key_info->flags & HA_NOSAME ?
  2852.  (!my_strcasecmp(system_charset_info,
  2853.  key_name, primary_key_name) ?
  2854.   Key::PRIMARY : Key::UNIQUE) :
  2855.   (key_info->flags & HA_FULLTEXT ?
  2856.    Key::FULLTEXT : Key::MULTIPLE)),
  2857.  key_name,
  2858.  key_info->algorithm,
  2859.                                  test(key_info->flags & HA_GENERATED_KEY),
  2860.  key_parts));
  2861.   }
  2862.   {
  2863.     Key *key;
  2864.     while ((key=key_it++)) // Add new keys
  2865.     {
  2866.       if (key->type != Key::FOREIGN_KEY)
  2867. key_list.push_back(key);
  2868.       if (key->name &&
  2869.   !my_strcasecmp(system_charset_info,key->name,primary_key_name))
  2870.       {
  2871. my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name);
  2872. DBUG_RETURN(-1);
  2873.       }
  2874.     }
  2875.   }
  2876.   if (alter_info->drop_list.elements)
  2877.   {
  2878.     my_error(ER_CANT_DROP_FIELD_OR_KEY,MYF(0),
  2879.      alter_info->drop_list.head()->name);
  2880.     goto err;
  2881.   }
  2882.   if (alter_info->alter_list.elements)
  2883.   {
  2884.     my_error(ER_CANT_DROP_FIELD_OR_KEY,MYF(0),
  2885.      alter_info->alter_list.head()->name);
  2886.     goto err;
  2887.   }
  2888.   db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD);
  2889.   my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
  2890.       current_pid, thd->thread_id);
  2891.   /* Safety fix for innodb */
  2892.   if (lower_case_table_names)
  2893.     my_casedn_str(files_charset_info, tmp_name);
  2894.   if (new_db_type != old_db_type && !table->file->can_switch_engines()) {
  2895.     my_error(ER_ROW_IS_REFERENCED, MYF(0));
  2896.     goto err;
  2897.   }
  2898.   create_info->db_type=new_db_type;
  2899.   if (!create_info->comment)
  2900.     create_info->comment=table->comment;
  2901.   table->file->update_create_info(create_info);
  2902.   if ((create_info->table_options &
  2903.        (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS)) ||
  2904.       (used_fields & HA_CREATE_USED_PACK_KEYS))
  2905.     db_create_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS);
  2906.   if (create_info->table_options &
  2907.       (HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM))
  2908.     db_create_options&= ~(HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM);
  2909.   if (create_info->table_options &
  2910.       (HA_OPTION_DELAY_KEY_WRITE | HA_OPTION_NO_DELAY_KEY_WRITE))
  2911.     db_create_options&= ~(HA_OPTION_DELAY_KEY_WRITE |
  2912.   HA_OPTION_NO_DELAY_KEY_WRITE);
  2913.   create_info->table_options|= db_create_options;
  2914.   if (table->tmp_table)
  2915.     create_info->options|=HA_LEX_CREATE_TMP_TABLE;
  2916.   /*
  2917.     Handling of symlinked tables:
  2918.     If no rename:
  2919.       Create new data file and index file on the same disk as the
  2920.       old data and index files.
  2921.       Copy data.
  2922.       Rename new data file over old data file and new index file over
  2923.       old index file.
  2924.       Symlinks are not changed.
  2925.    If rename:
  2926.       Create new data file and index file on the same disk as the
  2927.       old data and index files.  Create also symlinks to point at
  2928.       the new tables.
  2929.       Copy data.
  2930.       At end, rename temporary tables and symlinks to temporary table
  2931.       to final table name.
  2932.       Remove old table and old symlinks
  2933.     If rename is made to another database:
  2934.       Create new tables in new database.
  2935.       Copy data.
  2936.       Remove old table and symlinks.
  2937.   */
  2938.   if (!strcmp(db, new_db)) // Ignore symlink if db changed
  2939.   {
  2940.     if (create_info->index_file_name)
  2941.     {
  2942.       /* Fix index_file_name to have 'tmp_name' as basename */
  2943.       strmov(index_file, tmp_name);
  2944.       create_info->index_file_name=fn_same(index_file,
  2945.    create_info->index_file_name,
  2946.    1);
  2947.     }
  2948.     if (create_info->data_file_name)
  2949.     {
  2950.       /* Fix data_file_name to have 'tmp_name' as basename */
  2951.       strmov(data_file, tmp_name);
  2952.       create_info->data_file_name=fn_same(data_file,
  2953.   create_info->data_file_name,
  2954.   1);
  2955.     }
  2956.   }
  2957.   else
  2958.     create_info->data_file_name=create_info->index_file_name=0;
  2959.   {
  2960.     /* We don't log the statement, it will be logged later. */
  2961.     tmp_disable_binlog(thd);
  2962.     error= mysql_create_table(thd, new_db, tmp_name,
  2963.                               create_info,create_list,key_list,1,0);
  2964.     reenable_binlog(thd);
  2965.     if (error)
  2966.       DBUG_RETURN(error);
  2967.   }
  2968.   if (table->tmp_table)
  2969.     new_table=open_table(thd,new_db,tmp_name,tmp_name,0);
  2970.   else
  2971.   {
  2972.     char path[FN_REFLEN];
  2973.     build_table_path(path, sizeof(path), new_db, tmp_name, "");
  2974.     new_table=open_temporary_table(thd, path, new_db, tmp_name,0);
  2975.   }
  2976.   if (!new_table)
  2977.   {
  2978.     VOID(quick_rm_table(new_db_type,new_db,tmp_name));
  2979.     goto err;
  2980.   }
  2981.   /* We don't want update TIMESTAMP fields during ALTER TABLE. */
  2982.   new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
  2983.   new_table->next_number_field=new_table->found_next_number_field;
  2984.   thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
  2985.   thd->cuted_fields=0L;
  2986.   thd->proc_info="copy to tmp table";
  2987.   next_insert_id=thd->next_insert_id; // Remember for loggin
  2988.   copied=deleted=0;
  2989.   if (!new_table->is_view)
  2990.     error=copy_data_between_tables(table,new_table,create_list,
  2991.    handle_duplicates, ignore,
  2992.    order_num, order, &copied, &deleted);
  2993.   thd->last_insert_id=next_insert_id; // Needed for correct log
  2994.   thd->count_cuted_fields= CHECK_FIELD_IGNORE;
  2995.   if (table->tmp_table)
  2996.   {
  2997.     /* We changed a temporary table */
  2998.     if (error)
  2999.     {
  3000.       /*
  3001. The following function call will free the new_table pointer,
  3002. in close_temporary_table(), so we can safely directly jump to err
  3003.       */
  3004.       close_temporary_table(thd,new_db,tmp_name);
  3005.       goto err;
  3006.     }
  3007.     /* Close lock if this is a transactional table */
  3008.     if (thd->lock)
  3009.     {
  3010.       mysql_unlock_tables(thd, thd->lock);
  3011.       thd->lock=0;
  3012.     }
  3013.     /* Remove link to old table and rename the new one */
  3014.     close_temporary_table(thd,table->table_cache_key,table_name);
  3015.     /* Should pass the 'new_name' as we store table name in the cache */
  3016.     if (rename_temporary_table(thd, new_table, new_db, new_name))
  3017.     { // Fatal error
  3018.       close_temporary_table(thd,new_db,tmp_name);
  3019.       my_free((gptr) new_table,MYF(0));
  3020.       goto err;
  3021.     }
  3022.     mysql_update_log.write(thd, thd->query,thd->query_length);
  3023.     if (mysql_bin_log.is_open())
  3024.     {
  3025.       thd->clear_error();
  3026.       Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
  3027.       mysql_bin_log.write(&qinfo);
  3028.     }
  3029.     goto end_temporary;
  3030.   }
  3031.   intern_close_table(new_table); /* close temporary table */
  3032.   my_free((gptr) new_table,MYF(0));
  3033.   VOID(pthread_mutex_lock(&LOCK_open));
  3034.   if (error)
  3035.   {
  3036.     VOID(quick_rm_table(new_db_type,new_db,tmp_name));
  3037.     VOID(pthread_mutex_unlock(&LOCK_open));
  3038.     goto err;
  3039.   }
  3040.   /*
  3041.     Data is copied.  Now we rename the old table to a temp name,
  3042.     rename the new one to the old name, remove all entries from the old table
  3043.     from the cash, free all locks, close the old table and remove it.
  3044.   */
  3045.   thd->proc_info="rename result table";
  3046.   my_snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
  3047.       current_pid, thd->thread_id);
  3048.   if (lower_case_table_names)
  3049.     my_casedn_str(files_charset_info, old_name);
  3050.   if (new_name != table_name || new_db != db)
  3051.   {
  3052.     if (!access(new_name_buff,F_OK))
  3053.     {
  3054.       error=1;
  3055.       my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff);
  3056.       VOID(quick_rm_table(new_db_type,new_db,tmp_name));
  3057.       VOID(pthread_mutex_unlock(&LOCK_open));
  3058.       goto err;
  3059.     }
  3060.   }
  3061. #if (!defined( __WIN__) && !defined( __EMX__) && !defined( OS2))
  3062.   if (table->file->has_transactions())
  3063. #endif
  3064.   {
  3065.     /*
  3066.       Win32 and InnoDB can't drop a table that is in use, so we must
  3067.       close the original table at before doing the rename
  3068.     */
  3069.     table_name=thd->strdup(table_name); // must be saved
  3070.     if (close_cached_table(thd, table))
  3071.     { // Aborted
  3072.       VOID(quick_rm_table(new_db_type,new_db,tmp_name));
  3073.       VOID(pthread_mutex_unlock(&LOCK_open));
  3074.       goto err;
  3075.     }
  3076.     table=0; // Marker that table is closed
  3077.   }
  3078. #if (!defined( __WIN__) && !defined( __EMX__) && !defined( OS2))
  3079.   else
  3080.     table->file->extra(HA_EXTRA_FORCE_REOPEN); // Don't use this file anymore
  3081. #endif
  3082.   error=0;
  3083.   if (mysql_rename_table(old_db_type,db,table_name,db,old_name))
  3084.   {
  3085.     error=1;
  3086.     VOID(quick_rm_table(new_db_type,new_db,tmp_name));
  3087.   }
  3088.   else if (mysql_rename_table(new_db_type,new_db,tmp_name,new_db,
  3089.       new_alias))
  3090.   { // Try to get everything back
  3091.     error=1;
  3092.     VOID(quick_rm_table(new_db_type,new_db,new_alias));
  3093.     VOID(quick_rm_table(new_db_type,new_db,tmp_name));
  3094.     VOID(mysql_rename_table(old_db_type,db,old_name,db,alias));
  3095.   }
  3096.   if (error)
  3097.   {
  3098.     /*
  3099.       This shouldn't happen.  We solve this the safe way by
  3100.       closing the locked table.
  3101.     */
  3102.     if (table)
  3103.       close_cached_table(thd,table);
  3104.     VOID(pthread_mutex_unlock(&LOCK_open));
  3105.     goto err;
  3106.   }
  3107.   if (thd->lock || new_name != table_name) // True if WIN32
  3108.   {
  3109.     /*
  3110.       Not table locking or alter table with rename
  3111.       free locks and remove old table
  3112.     */
  3113.     if (table)
  3114.       close_cached_table(thd,table);
  3115.     VOID(quick_rm_table(old_db_type,db,old_name));
  3116.   }
  3117.   else
  3118.   {
  3119.     /*
  3120.       Using LOCK TABLES without rename.
  3121.       This code is never executed on WIN32!
  3122.       Remove old renamed table, reopen table and get new locks
  3123.     */
  3124.     if (table)
  3125.     {
  3126.       VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Use new file
  3127.       /* Mark in-use copies old */
  3128.       remove_table_from_cache(thd,db,table_name,RTFC_NO_FLAG);
  3129.       /* end threads waiting on lock */
  3130.       mysql_lock_abort(thd,table);
  3131.     }
  3132.     VOID(quick_rm_table(old_db_type,db,old_name));
  3133.     if (close_data_tables(thd,db,table_name) ||
  3134. reopen_tables(thd,1,0))
  3135.     { // This shouldn't happen
  3136.       if (table)
  3137. close_cached_table(thd,table); // Remove lock for table
  3138.       VOID(pthread_mutex_unlock(&LOCK_open));
  3139.       goto err;
  3140.     }
  3141.   }
  3142.   /* The ALTER TABLE is always in its own transaction */
  3143.   error = ha_commit_stmt(thd);
  3144.   if (ha_commit(thd))
  3145.     error=1;
  3146.   if (error)
  3147.   {
  3148.     VOID(pthread_mutex_unlock(&LOCK_open));
  3149.     VOID(pthread_cond_broadcast(&COND_refresh));
  3150.     goto err;
  3151.   }
  3152.   thd->proc_info="end";
  3153.   mysql_update_log.write(thd, thd->query,thd->query_length);
  3154.   if (mysql_bin_log.is_open())
  3155.   {
  3156.     thd->clear_error();
  3157.     Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
  3158.     mysql_bin_log.write(&qinfo);
  3159.   }
  3160.   VOID(pthread_cond_broadcast(&COND_refresh));
  3161.   VOID(pthread_mutex_unlock(&LOCK_open));
  3162. #ifdef HAVE_BERKELEY_DB
  3163.   if (old_db_type == DB_TYPE_BERKELEY_DB)
  3164.   {
  3165.     /*
  3166.       For the alter table to be properly flushed to the logs, we
  3167.       have to open the new table.  If not, we get a problem on server
  3168.       shutdown.
  3169.     */
  3170.     char path[FN_REFLEN];
  3171.     build_table_path(path, sizeof(path), new_db, table_name, "");
  3172.     table=open_temporary_table(thd, path, new_db, tmp_name,0);
  3173.     if (table)
  3174.     {
  3175.       intern_close_table(table);
  3176.       my_free((char*) table, MYF(0));
  3177.     }
  3178.     else
  3179.       sql_print_warning("Could not open BDB table %s.%s after renamen",
  3180.                         new_db,table_name);
  3181.     (void) berkeley_flush_logs();
  3182.   }
  3183. #endif
  3184.   table_list->table=0; // For query cache
  3185.   query_cache_invalidate3(thd, table_list, 0);
  3186. end_temporary:
  3187.   my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
  3188.       (ulong) (copied + deleted), (ulong) deleted,
  3189.       (ulong) thd->cuted_fields);
  3190.   if (do_send_ok)
  3191.     send_ok(thd,copied+deleted,0L,tmp_name);
  3192.   thd->some_tables_deleted=0;
  3193.   DBUG_RETURN(0);
  3194.  err:
  3195.   DBUG_RETURN(-1);
  3196. }
  3197. static int
  3198. copy_data_between_tables(TABLE *from,TABLE *to,
  3199.  List<create_field> &create,
  3200.  enum enum_duplicates handle_duplicates,
  3201.                          bool ignore,
  3202.  uint order_num, ORDER *order,
  3203.  ha_rows *copied,
  3204.  ha_rows *deleted)
  3205. {
  3206.   int error;
  3207.   Copy_field *copy,*copy_end;
  3208.   ulong found_count,delete_count;
  3209.   THD *thd= current_thd;
  3210.   uint length;
  3211.   SORT_FIELD *sortorder;
  3212.   READ_RECORD info;
  3213.   TABLE_LIST   tables;
  3214.   List<Item>   fields;
  3215.   List<Item>   all_fields;
  3216.   ha_rows examined_rows;
  3217.   bool auto_increment_field_copied= 0;
  3218.   ulong save_sql_mode;
  3219.   DBUG_ENTER("copy_data_between_tables");
  3220.   /*
  3221.     Turn off recovery logging since rollback of an alter table is to
  3222.     delete the new table so there is no need to log the changes to it.
  3223.     
  3224.     This needs to be done before external_lock
  3225.   */
  3226.   error= ha_enable_transaction(thd, FALSE);
  3227.   if (error)
  3228.     DBUG_RETURN(-1);
  3229.   
  3230.   if (!(copy= new Copy_field[to->fields]))
  3231.     DBUG_RETURN(-1); /* purecov: inspected */
  3232.   if (to->file->external_lock(thd, F_WRLCK))
  3233.     DBUG_RETURN(-1);
  3234.   from->file->info(HA_STATUS_VARIABLE);
  3235.   to->file->start_bulk_insert(from->file->records);
  3236.   save_sql_mode= thd->variables.sql_mode;
  3237.   List_iterator<create_field> it(create);
  3238.   create_field *def;
  3239.   copy_end=copy;
  3240.   for (Field **ptr=to->field ; *ptr ; ptr++)
  3241.   {
  3242.     def=it++;
  3243.     if (def->field)
  3244.     {
  3245.       if (*ptr == to->next_number_field)
  3246.       {
  3247.         auto_increment_field_copied= TRUE;
  3248.         /*
  3249.           If we are going to copy contents of one auto_increment column to
  3250.           another auto_increment column it is sensible to preserve zeroes.
  3251.           This condition also covers case when we are don't actually alter
  3252.           auto_increment column.
  3253.         */
  3254.         if (def->field == from->found_next_number_field)
  3255.           thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
  3256.       }
  3257.       (copy_end++)->set(*ptr,def->field,0);
  3258.     }
  3259.   }
  3260.   found_count=delete_count=0;
  3261.   if (order)
  3262.   {
  3263.     from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
  3264.       MYF(MY_FAE | MY_ZEROFILL));
  3265.     bzero((char*) &tables,sizeof(tables));
  3266.     tables.table = from;
  3267.     tables.alias = tables.real_name= from->real_name;
  3268.     tables.db  = from->table_cache_key;
  3269.     error=1;
  3270.     if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
  3271. setup_order(thd, thd->lex->select_lex.ref_pointer_array,
  3272.     &tables, fields, all_fields, order) ||
  3273. !(sortorder=make_unireg_sortorder(order, &length)) ||
  3274. (from->sort.found_records = filesort(thd, from, sortorder, length,
  3275.      (SQL_SELECT *) 0, HA_POS_ERROR,
  3276.      &examined_rows))
  3277. == HA_POS_ERROR)
  3278.       goto err;
  3279.   };
  3280.   /* Handler must be told explicitly to retrieve all columns, because
  3281.      this function does not set field->query_id in the columns to the
  3282.      current query id */
  3283.   from->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
  3284.   init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
  3285.   if (ignore ||
  3286.       handle_duplicates == DUP_REPLACE)
  3287.     to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
  3288.   thd->row_count= 0;
  3289.   while (!(error=info.read_record(&info)))
  3290.   {
  3291.     if (thd->killed)
  3292.     {
  3293.       my_error(ER_SERVER_SHUTDOWN,MYF(0));
  3294.       error= 1;
  3295.       break;
  3296.     }
  3297.     thd->row_count++;
  3298.     if (to->next_number_field)
  3299.     {
  3300.       if (auto_increment_field_copied)
  3301.         to->auto_increment_field_not_null= TRUE;
  3302.       else
  3303.         to->next_number_field->reset();
  3304.     }
  3305.     for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
  3306.     {
  3307.       copy_ptr->do_copy(copy_ptr);
  3308.     }
  3309.     if ((error=to->file->write_row((byte*) to->record[0])))
  3310.     {
  3311.       if ((!ignore &&
  3312.    handle_duplicates != DUP_REPLACE) ||
  3313.   (error != HA_ERR_FOUND_DUPP_KEY &&
  3314.    error != HA_ERR_FOUND_DUPP_UNIQUE))
  3315.       {
  3316. to->file->print_error(error,MYF(0));
  3317. break;
  3318.       }
  3319.       delete_count++;
  3320.     }
  3321.     else
  3322.       found_count++;
  3323.   }
  3324.   end_read_record(&info);
  3325.   free_io_cache(from);
  3326.   delete [] copy; // This is never 0
  3327.   if (to->file->end_bulk_insert() && !error)
  3328.   {
  3329.     to->file->print_error(my_errno,MYF(0));
  3330.     error=1;
  3331.   }
  3332.   to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
  3333.   ha_enable_transaction(thd,TRUE);
  3334.   /*
  3335.     Ensure that the new table is saved properly to disk so that we
  3336.     can do a rename
  3337.   */
  3338.   if (ha_commit_stmt(thd))
  3339.     error=1;
  3340.   if (ha_commit(thd))
  3341.     error=1;
  3342.  err:
  3343.   thd->variables.sql_mode= save_sql_mode;
  3344.   free_io_cache(from);
  3345.   *copied= found_count;
  3346.   *deleted=delete_count;
  3347.   if (to->file->external_lock(thd,F_UNLCK))
  3348.     error=1;
  3349.   DBUG_RETURN(error > 0 ? -1 : 0);
  3350. }
  3351. /*
  3352.   Recreates tables by calling mysql_alter_table().
  3353.   SYNOPSIS
  3354.     mysql_recreate_table()
  3355.     thd Thread handler
  3356.     tables Tables to recreate
  3357.     do_send_ok          If we should send_ok() or leave it to caller
  3358.  RETURN
  3359.     Like mysql_alter_table().
  3360. */
  3361. int mysql_recreate_table(THD *thd, TABLE_LIST *table_list,
  3362.                          bool do_send_ok)
  3363. {
  3364.   DBUG_ENTER("mysql_recreate_table");
  3365.   LEX *lex= thd->lex;
  3366.   HA_CREATE_INFO create_info;
  3367.   lex->create_list.empty();
  3368.   lex->key_list.empty();
  3369.   lex->col_list.empty();
  3370.   lex->alter_info.reset();
  3371.   lex->alter_info.is_simple= 0;                 // Force full recreate
  3372.   bzero((char*) &create_info,sizeof(create_info));
  3373.   create_info.db_type=DB_TYPE_DEFAULT;
  3374.   create_info.row_type=ROW_TYPE_DEFAULT;
  3375.   create_info.default_table_charset=default_charset_info;
  3376.   DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
  3377.                                 table_list, lex->create_list,
  3378.                                 lex->key_list, 0, (ORDER *) 0,
  3379.                                 DUP_ERROR, 0, &lex->alter_info, do_send_ok));
  3380. }
  3381. int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
  3382. {
  3383.   TABLE_LIST *table;
  3384.   List<Item> field_list;
  3385.   Item *item;
  3386.   Protocol *protocol= thd->protocol;
  3387.   DBUG_ENTER("mysql_checksum_table");
  3388.   field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
  3389.   item->maybe_null= 1;
  3390.   field_list.push_back(item=new Item_int("Checksum",(longlong) 1,21));
  3391.   item->maybe_null= 1;
  3392.   if (protocol->send_fields(&field_list, 1))
  3393.     DBUG_RETURN(-1);
  3394.   for (table= tables; table; table= table->next)
  3395.   {
  3396.     char table_name[NAME_LEN*2+2];
  3397.     TABLE *t;
  3398.     strxmov(table_name, table->db ,".", table->real_name, NullS);
  3399.     t= table->table= open_ltable(thd, table, TL_READ_NO_INSERT);
  3400.     thd->clear_error(); // these errors shouldn't get client
  3401.     protocol->prepare_for_resend();
  3402.     protocol->store(table_name, system_charset_info);
  3403.     if (!t)
  3404.     {
  3405.       /* Table didn't exist */
  3406.       protocol->store_null();
  3407.       thd->net.last_error[0]=0;
  3408.     }
  3409.     else
  3410.     {
  3411.       t->pos_in_table_list= table;
  3412.       if (t->file->table_flags() & HA_HAS_CHECKSUM &&
  3413.   !(check_opt->flags & T_EXTEND))
  3414. protocol->store((ulonglong)t->file->checksum());
  3415.       else if (!(t->file->table_flags() & HA_HAS_CHECKSUM) &&
  3416.        (check_opt->flags & T_QUICK))
  3417. protocol->store_null();
  3418.       else
  3419.       {
  3420. /* calculating table's checksum */
  3421. ha_checksum crc= 0;
  3422. /* InnoDB must be told explicitly to retrieve all columns, because
  3423. this function does not set field->query_id in the columns to the
  3424. current query id */
  3425. t->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
  3426. if (t->file->ha_rnd_init(1))
  3427.   protocol->store_null();
  3428. else
  3429. {
  3430.   for (;;)
  3431.   {
  3432.     ha_checksum row_crc= 0;
  3433.             int error= t->file->rnd_next(t->record[0]);
  3434.             if (unlikely(error))
  3435.             {
  3436.               if (error == HA_ERR_RECORD_DELETED)
  3437.                 continue;
  3438.               break;
  3439.             }
  3440.     if (t->record[0] != (byte*) t->field[0]->ptr)
  3441.       row_crc= my_checksum(row_crc, t->record[0],
  3442.    ((byte*) t->field[0]->ptr) - t->record[0]);
  3443.     for (uint i= 0; i < t->fields; i++ )
  3444.     {
  3445.       Field *f= t->field[i];
  3446.       if (f->type() == FIELD_TYPE_BLOB)
  3447.       {
  3448. String tmp;
  3449. f->val_str(&tmp);
  3450. row_crc= my_checksum(row_crc, (byte*) tmp.ptr(), tmp.length());
  3451.       }
  3452.       else
  3453. row_crc= my_checksum(row_crc, (byte*) f->ptr,
  3454.      f->pack_length());
  3455.     }
  3456.     crc+= row_crc;
  3457.   }
  3458.   protocol->store((ulonglong)crc);
  3459.           t->file->ha_rnd_end();
  3460. }
  3461.       }
  3462.       thd->clear_error();
  3463.       close_thread_tables(thd);
  3464.       table->table=0; // For query cache
  3465.     }
  3466.     if (protocol->write())
  3467.       goto err;
  3468.   }
  3469.   send_eof(thd);
  3470.   DBUG_RETURN(0);
  3471.  err:
  3472.   close_thread_tables(thd); // Shouldn't be needed
  3473.   if (table)
  3474.     table->table=0;
  3475.   DBUG_RETURN(-1);
  3476. }