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

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /* Basic functions neaded by many modules */
  14. #include "mysql_priv.h"
  15. #include "sql_acl.h"
  16. #include <thr_alarm.h>
  17. #include <m_ctype.h>
  18. #include <my_dir.h>
  19. #include <hash.h>
  20. #include <nisam.h>
  21. #include <assert.h>
  22. #ifdef __WIN__
  23. #include <io.h>
  24. #endif
  25. TABLE *unused_tables; /* Used by mysql_test */
  26. HASH open_cache; /* Used by mysql_test */
  27. static int open_unireg_entry(THD *thd,TABLE *entry,const char *db,
  28.      const char *name, const char *alias, bool locked);
  29. static bool insert_fields(THD *thd,TABLE_LIST *tables, const char *table_name,
  30.   List_iterator<Item> *it);
  31. static void free_cache_entry(TABLE *entry);
  32. static void mysql_rm_tmp_tables(void);
  33. static key_map get_key_map_from_key_list(THD *thd, TABLE *table,
  34.  List<String> *index_list);
  35. static byte *cache_key(const byte *record,uint *length,
  36.        my_bool not_used __attribute__((unused)))
  37. {
  38.   TABLE *entry=(TABLE*) record;
  39.   *length=entry->key_length;
  40.   return (byte*) entry->table_cache_key;
  41. }
  42. void table_cache_init(void)
  43. {
  44.   VOID(hash_init(&open_cache,table_cache_size+16,0,0,cache_key,
  45.  (void (*)(void*)) free_cache_entry,0));
  46.   mysql_rm_tmp_tables();
  47. }
  48. void table_cache_free(void)
  49. {
  50.   DBUG_ENTER("table_cache_free");
  51.   close_cached_tables((THD*) 0,0,(TABLE_LIST*) 0);
  52.   if (!open_cache.records) // Safety first
  53.     hash_free(&open_cache);
  54.   DBUG_VOID_RETURN;
  55. }
  56. uint cached_tables(void)
  57. {
  58.   return open_cache.records;
  59. }
  60. #ifdef EXTRA_DEBUG
  61. static void check_unused(void)
  62. {
  63.   uint count=0,idx=0;
  64.   TABLE *cur_link,*start_link;
  65.   if ((start_link=cur_link=unused_tables))
  66.   {
  67.     do
  68.     {
  69.       if (cur_link != cur_link->next->prev || cur_link != cur_link->prev->next)
  70.       {
  71. DBUG_PRINT("error",("Unused_links aren't linked properly")); /* purecov: inspected */
  72. return; /* purecov: inspected */
  73.       }
  74.     } while (count++ < open_cache.records &&
  75.      (cur_link=cur_link->next) != start_link);
  76.     if (cur_link != start_link)
  77.     {
  78.       DBUG_PRINT("error",("Unused_links aren't connected")); /* purecov: inspected */
  79.     }
  80.   }
  81.   for (idx=0 ; idx < open_cache.records ; idx++)
  82.   {
  83.     TABLE *entry=(TABLE*) hash_element(&open_cache,idx);
  84.     if (!entry->in_use)
  85.       count--;
  86.   }
  87.   if (count != 0)
  88.   {
  89.     DBUG_PRINT("error",("Unused_links doesn't match open_cache: diff: %d", /* purecov: inspected */
  90. count)); /* purecov: inspected */
  91.   }
  92. }
  93. #else
  94. #define check_unused()
  95. #endif
  96. int list_open_tables(THD *thd,List<char> *tables, const char *db,const char *wild)
  97. {
  98.   int result = 0;
  99.   uint col_access=thd->col_access;
  100.   TABLE_LIST table_list;
  101.   DBUG_ENTER("list_open_tables");
  102.   VOID(pthread_mutex_lock(&LOCK_open));
  103.   bzero((char*) &table_list,sizeof(table_list));
  104.   for (uint idx=0 ; result == 0 && idx < open_cache.records; idx++)
  105.   {
  106.     TABLE *entry=(TABLE*) hash_element(&open_cache,idx);
  107.     if ((!entry->real_name) || strcmp(entry->table_cache_key,db))
  108.       continue;
  109.     if (wild && wild[0] && wild_compare(entry->real_name,wild))
  110.       continue;
  111.     if (db && !(col_access & TABLE_ACLS))
  112.     {
  113.       table_list.db= (char*) db;
  114.       table_list.real_name= entry->real_name;/*real name*/
  115.       table_list.grant.privilege=col_access;
  116.       if (check_grant(thd,TABLE_ACLS,&table_list,1))
  117.         continue;
  118.     }
  119.     /* need to check if he have't already listed it */
  120.     List_iterator<char> it(*tables);
  121.     char *table_name; 
  122.     int check = 0;
  123.     while (check == 0 && (table_name=it++))
  124.     {
  125.       if (!strcmp(table_name,entry->real_name))
  126.         check++;
  127.     }
  128.     if (check)
  129.       continue;
  130.     
  131.     if (tables->push_back(thd->strdup(entry->real_name)))
  132.     {
  133.       result = -1;
  134.     }
  135.   }
  136.   
  137.   VOID(pthread_mutex_unlock(&LOCK_open));
  138.   DBUG_RETURN(result);  
  139. }
  140. char*
  141. query_table_status(THD *thd,const char *db,const char *table_name)
  142. {
  143.   int cached = 0, in_use = 0;
  144.   char info[256];
  145.   for (uint idx=0 ; idx < open_cache.records; idx++)
  146.   {
  147.     TABLE *entry=(TABLE*) hash_element(&open_cache,idx);
  148.     if (strcmp(entry->table_cache_key,db) ||
  149.         strcmp(entry->real_name,table_name))
  150.       continue;
  151.     cached++;
  152.     if (entry->in_use)
  153.       in_use++;
  154.   }
  155.   sprintf(info, "cached=%d, in_use=%d", cached, in_use);
  156.   return thd->strdup(info);
  157. }
  158. /******************************************************************************
  159. ** Send name and type of result to client.
  160. ** Sum fields has table name empty and field_name.
  161. ** flag is a bit mask with the following functions:
  162. **   1 send number of rows
  163. **   2 send default values
  164. **   4 Don't convert field names
  165. ******************************************************************************/
  166. bool
  167. send_fields(THD *thd,List<Item> &list,uint flag)
  168. {
  169.   List_iterator<Item> it(list);
  170.   Item *item;
  171.   char buff[80];
  172.   CONVERT *convert= (flag & 4) ? (CONVERT*) 0 : thd->convert_set;
  173.   String tmp((char*) buff,sizeof(buff)),*res,*packet= &thd->packet;
  174.   if (thd->fatal_error) // We have got an error
  175.     goto err;
  176.   if (flag & 1)
  177.   { // Packet with number of elements
  178.     char *pos=net_store_length(buff,(uint) list.elements);
  179.     (void) my_net_write(&thd->net, buff,(uint) (pos-buff));
  180.   }
  181.   while ((item=it++))
  182.   {
  183.     char *pos;
  184.     Send_field field;
  185.     item->make_field(&field);
  186.     packet->length(0);
  187.     if (convert)
  188.     {
  189.       if (convert->store(packet,field.table_name,
  190.  (uint) strlen(field.table_name)) ||
  191.   convert->store(packet,field.col_name,
  192.  (uint) strlen(field.col_name)) ||
  193.   packet->realloc(packet->length()+10))
  194. goto err;
  195.     }
  196.     else if (net_store_data(packet,field.table_name) ||
  197.      net_store_data(packet,field.col_name) ||
  198.      packet->realloc(packet->length()+10))
  199.       goto err; /* purecov: inspected */
  200.     pos= (char*) packet->ptr()+packet->length();
  201.     if (!(thd->client_capabilities & CLIENT_LONG_FLAG))
  202.     {
  203.       packet->length(packet->length()+9);
  204.       pos[0]=3; int3store(pos+1,field.length);
  205.       pos[4]=1; pos[5]=field.type;
  206.       pos[6]=2; pos[7]=(char) field.flags; pos[8]= (char) field.decimals;
  207.     }
  208.     else
  209.     {
  210.       packet->length(packet->length()+10);
  211.       pos[0]=3; int3store(pos+1,field.length);
  212.       pos[4]=1; pos[5]=field.type;
  213.       pos[6]=3; int2store(pos+7,field.flags); pos[9]= (char) field.decimals;
  214.     }
  215.     if (flag & 2)
  216.     { // Send default value
  217.       if (!(res=item->val_str(&tmp)))
  218.       {
  219. if (net_store_null(packet))
  220.   goto err;
  221.       }
  222.       else if (net_store_data(packet,res->ptr(),res->length()))
  223. goto err;
  224.     }
  225.     if (my_net_write(&thd->net, (char*) packet->ptr(),packet->length()))
  226.       break; /* purecov: inspected */
  227.   }
  228.   send_eof(&thd->net,(test_flags & TEST_MIT_THREAD) ? 0: 1);
  229.   return 0;
  230.  err:
  231.   send_error(&thd->net,ER_OUT_OF_RESOURCES); /* purecov: inspected */
  232.   return 1; /* purecov: inspected */
  233. }
  234. /*****************************************************************************
  235.  *  Functions to free open table cache
  236.  ****************************************************************************/
  237. void intern_close_table(TABLE *table)
  238. { // Free all structures
  239.   free_io_cache(table);
  240.   if (table->file)
  241.     VOID(closefrm(table)); // close file
  242. }
  243. static void free_cache_entry(TABLE *table)
  244. {
  245.   DBUG_ENTER("free_cache_entry");
  246.   intern_close_table(table);
  247.   if (!table->in_use)
  248.   {
  249.     table->next->prev=table->prev; /* remove from used chain */
  250.     table->prev->next=table->next;
  251.     if (table == unused_tables)
  252.     {
  253.       unused_tables=unused_tables->next;
  254.       if (table == unused_tables)
  255. unused_tables=0;
  256.     }
  257.     check_unused(); // consisty check
  258.   }
  259.   my_free((gptr) table,MYF(0));
  260.   DBUG_VOID_RETURN;
  261. }
  262. void free_io_cache(TABLE *table)
  263. {
  264.   if (table->io_cache)
  265.   {
  266.     close_cached_file(table->io_cache);
  267.     my_free((gptr) table->io_cache,MYF(0));
  268.     table->io_cache=0;
  269.   }
  270.   if (table->record_pointers)
  271.   {
  272.     my_free((gptr) table->record_pointers,MYF(0));
  273.     table->record_pointers=0;
  274.   }
  275. }
  276. /* Close all tables which aren't in use by any thread */
  277. bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
  278.  TABLE_LIST *tables)
  279. {
  280.   bool result=0;
  281.   DBUG_ENTER("close_cached_tables");
  282.   VOID(pthread_mutex_lock(&LOCK_open));
  283.   if (!tables)
  284.   {
  285.     while (unused_tables)
  286.     {
  287. #ifdef EXTRA_DEBUG
  288.       if (hash_delete(&open_cache,(byte*) unused_tables))
  289. printf("Warning: Couldn't delete open table from hashn");
  290. #else
  291.       VOID(hash_delete(&open_cache,(byte*) unused_tables));
  292. #endif
  293.     }
  294.     if (!open_cache.records && ! locked_in_memory)
  295.     {
  296.       end_key_cache(); /* No tables in memory */
  297.     }
  298.     refresh_version++; // Force close of open tables
  299.   }
  300.   else
  301.   {
  302.     bool found=0;
  303.     for (TABLE_LIST *table=tables ; table ; table=table->next)
  304.     {
  305.       if (remove_table_from_cache(thd, table->db, table->name, 1))
  306. found=1;
  307.     }
  308.     if (!found)
  309.       if_wait_for_refresh=0; // Nothing to wait for
  310.   }
  311.   if (if_wait_for_refresh)
  312.   {
  313.     /*
  314.       If there is any table that has a lower refresh_version, wait until
  315.       this is closed (or this thread is killed) before returning
  316.     */
  317.     if (!tables)
  318.       kill_delayed_threads();
  319.     pthread_mutex_lock(&thd->mysys_var->mutex);
  320.     thd->mysys_var->current_mutex= &LOCK_open;
  321.     thd->mysys_var->current_cond= &COND_refresh;
  322.     thd->proc_info="Flushing tables";
  323.     pthread_mutex_unlock(&thd->mysys_var->mutex);
  324.     close_old_data_files(thd,thd->open_tables,1,1);
  325.     bool found=1;
  326.     /* Wait until all threads has closed all the tables we had locked */
  327.     DBUG_PRINT("info", ("Waiting for others threads to close their open tables"));
  328.     while (found && ! thd->killed)
  329.     {
  330.       found=0;
  331.       for (uint idx=0 ; idx < open_cache.records ; idx++)
  332.       {
  333. TABLE *table=(TABLE*) hash_element(&open_cache,idx);
  334. if ((table->version) < refresh_version && table->db_stat)
  335. {
  336.   found=1;
  337.   pthread_cond_wait(&COND_refresh,&LOCK_open);
  338.   break;
  339. }
  340.       }
  341.     }
  342.     /*
  343.       No other thread has the locked tables open; reopen them and get the
  344.       old locks. This should always succeed (unless some external process
  345.       has removed the tables)
  346.     */
  347.     thd->in_lock_tables=1;
  348.     result=reopen_tables(thd,1,1);
  349.     thd->in_lock_tables=0;
  350.   }
  351.   VOID(pthread_mutex_unlock(&LOCK_open));
  352.   if (if_wait_for_refresh)
  353.   {
  354.     THD *thd=current_thd;
  355.     pthread_mutex_lock(&thd->mysys_var->mutex);
  356.     thd->mysys_var->current_mutex= 0;
  357.     thd->mysys_var->current_cond= 0;
  358.     thd->proc_info=0;
  359.     pthread_mutex_unlock(&thd->mysys_var->mutex);
  360.   }
  361.   DBUG_RETURN(result);
  362. }
  363. /* Put all tables used by thread in free list */
  364. void close_thread_tables(THD *thd, bool locked)
  365. {
  366.   DBUG_ENTER("close_thread_tables");
  367.   if (thd->locked_tables)
  368.     DBUG_VOID_RETURN; // LOCK TABLES in use
  369.   TABLE *table,*next;
  370.   bool found_old_table=0;
  371.   if (thd->lock)
  372.   {
  373.     mysql_unlock_tables(thd, thd->lock); thd->lock=0;
  374.   }
  375.   /* VOID(pthread_sigmask(SIG_SETMASK,&thd->block_signals,NULL)); */
  376.   if (!locked)
  377.     VOID(pthread_mutex_lock(&LOCK_open));
  378.   DBUG_PRINT("info", ("thd->open_tables=%p", thd->open_tables));
  379.   for (table=thd->open_tables ; table ; table=next)
  380.   {
  381.     next=table->next;
  382.     if (table->version != refresh_version ||
  383. thd->version != refresh_version || !table->db_stat)
  384.     {
  385.       VOID(hash_delete(&open_cache,(byte*) table));
  386.       found_old_table=1;
  387.     }
  388.     else
  389.     {
  390.       if (table->flush_version != flush_version)
  391.       {
  392. table->flush_version=flush_version;
  393. table->file->extra(HA_EXTRA_FLUSH);
  394.       }
  395.       else
  396.       {
  397. // Free memory and reset for next loop
  398. table->file->extra(HA_EXTRA_RESET);
  399.       }
  400.       table->in_use=0;
  401.       if (unused_tables)
  402.       {
  403. table->next=unused_tables; /* Link in last */
  404. table->prev=unused_tables->prev;
  405. unused_tables->prev=table;
  406. table->prev->next=table;
  407.       }
  408.       else
  409. unused_tables=table->next=table->prev=table;
  410.     }
  411.   }
  412.   thd->open_tables=0;
  413.   /* Free tables to hold down open files */
  414.   while (open_cache.records > table_cache_size && unused_tables)
  415.     VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */
  416.   check_unused();
  417.   if (found_old_table)
  418.   {
  419.     /* Tell threads waiting for refresh that something has happened */
  420.     VOID(pthread_cond_broadcast(&COND_refresh));
  421.   }
  422.   if (!locked)
  423.     VOID(pthread_mutex_unlock(&LOCK_open));
  424.   /*  VOID(pthread_sigmask(SIG_SETMASK,&thd->signals,NULL)); */
  425.   DBUG_VOID_RETURN;
  426. }
  427. /* Close and delete temporary tables */
  428. void close_temporary(TABLE *table,bool delete_table)
  429. {
  430.   DBUG_ENTER("close_temporary");
  431.   char path[FN_REFLEN];
  432.   db_type table_type=table->db_type;
  433.   strmov(path,table->path);
  434.   free_io_cache(table);
  435.   closefrm(table);
  436.   my_free((char*) table,MYF(0));
  437.   if (delete_table)
  438.     rm_temporary_table(table_type, path);
  439.   DBUG_VOID_RETURN;
  440. }
  441. void close_temporary_tables(THD *thd)
  442. {
  443.   TABLE *table,*next;
  444.   uint init_query_buf_size = 11, query_buf_size; // "drop table "
  445.   char* query, *p;
  446.   LINT_INIT(p);
  447.   query_buf_size = init_query_buf_size;
  448.   for (table=thd->temporary_tables ; table ; table=table->next)
  449.   {
  450.     query_buf_size += table->key_length;
  451.   }
  452.   if(query_buf_size == init_query_buf_size)
  453.     return; // no tables to close
  454.   if((query = alloc_root(&thd->mem_root, query_buf_size)))
  455.     {
  456.       memcpy(query, "drop table ", init_query_buf_size);
  457.       p = query + init_query_buf_size;
  458.     }
  459.   for (table=thd->temporary_tables ; table ; table=next)
  460.   {
  461.     if(query) // we might be out of memory, but this is not fatal
  462.       {
  463. p = strxmov(p,table->table_cache_key,".",
  464.     table->table_name,",", NullS);
  465. // here we assume table_cache_key always starts
  466. // with  terminated db name
  467.       }
  468.     next=table->next;
  469.     close_temporary(table);
  470.   }
  471.   if (query && mysql_bin_log.is_open())
  472.   {
  473.     uint save_query_len = thd->query_length;
  474.     *--p = 0;
  475.     thd->query_length = (uint)(p-query);
  476.     Query_log_event qinfo(thd, query);
  477.     mysql_bin_log.write(&qinfo);
  478.     thd->query_length = save_query_len;
  479.   }
  480.   thd->temporary_tables=0;
  481. }
  482. TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name)
  483. {
  484.   char key[MAX_DBKEY_LENGTH];
  485.   uint key_length= (uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
  486.   TABLE *table,**prev;
  487.   int4store(key+key_length,thd->slave_proxy_id);
  488.   key_length += 4;
  489.   prev= &thd->temporary_tables;
  490.   for (table=thd->temporary_tables ; table ; table=table->next)
  491.   {
  492.     if (table->key_length == key_length &&
  493. !memcmp(table->table_cache_key,key,key_length))
  494.       return prev;
  495.     prev= &table->next;
  496.   }
  497.   return 0; // Not a temporary table
  498. }
  499. bool close_temporary_table(THD *thd, const char *db, const char *table_name)
  500. {
  501.   TABLE *table,**prev;
  502.   if (!(prev=find_temporary_table(thd,db,table_name)))
  503.     return 1;
  504.   table= *prev;
  505.   *prev= table->next;
  506.   close_temporary(table);
  507.   if(thd->slave_thread)
  508.     --slave_open_temp_tables;
  509.   return 0;
  510. }
  511. bool rename_temporary_table(THD* thd, TABLE *table, const char *db,
  512.     const char *table_name)
  513. {
  514.   char *key;
  515.   if (!(key=(char*) alloc_root(&table->mem_root,
  516.        (uint) strlen(db)+
  517.        (uint) strlen(table_name)+6)))
  518.     return 1; /* purecov: inspected */
  519.   table->key_length=(uint)
  520.     (strmov((table->real_name=strmov(table->table_cache_key=key,
  521.      db)+1),
  522.     table_name) - table->table_cache_key)+1;
  523.   int4store(key+table->key_length,thd->slave_proxy_id);
  524.   table->key_length += 4;
  525.   return 0;
  526. }
  527. /* move table first in unused links */
  528. static void relink_unused(TABLE *table)
  529. {
  530.   if (table != unused_tables)
  531.   {
  532.     table->prev->next=table->next; /* Remove from unused list */
  533.     table->next->prev=table->prev;
  534.     table->next=unused_tables; /* Link in unused tables */
  535.     table->prev=unused_tables->prev;
  536.     unused_tables->prev->next=table;
  537.     unused_tables->prev=table;
  538.     unused_tables=table;
  539.     check_unused();
  540.   }
  541. }
  542. /*
  543.   Remove all instances of table from the current open list
  544.   Free all locks on tables that are done with LOCK TABLES
  545.  */
  546. TABLE *unlink_open_table(THD *thd, TABLE *list, TABLE *find)
  547. {
  548.   char key[MAX_DBKEY_LENGTH];
  549.   uint key_length=find->key_length;
  550.   TABLE *start=list,**prev,*next;
  551.   prev= &start;
  552.   memcpy(key,find->table_cache_key,key_length);
  553.   for (; list ; list=next)
  554.   {
  555.     next=list->next;
  556.     if (list->key_length == key_length &&
  557. !memcmp(list->table_cache_key,key,key_length))
  558.     {
  559.       if (thd->locked_tables)
  560. mysql_lock_remove(thd, thd->locked_tables,list);
  561.       VOID(hash_delete(&open_cache,(byte*) list)); // Close table
  562.     }
  563.     else
  564.     {
  565.       *prev=list; // put in use list
  566.       prev= &list->next;
  567.     }
  568.   }
  569.   *prev=0;
  570.   // Notify any 'refresh' threads
  571.   pthread_cond_broadcast(&COND_refresh);
  572.   return start;
  573. }
  574. /*
  575.    When we call the following function we must have a lock on
  576.    LOCK_OPEN ; This lock will be unlocked on return.
  577. */
  578. void wait_for_refresh(THD *thd)
  579. {
  580.   /* Wait until the current table is up to date */
  581.   const char *proc_info;
  582.   pthread_mutex_lock(&thd->mysys_var->mutex);
  583.   thd->mysys_var->current_mutex= &LOCK_open;
  584.   thd->mysys_var->current_cond= &COND_refresh;
  585.   proc_info=thd->proc_info;
  586.   thd->proc_info="Waiting for table";
  587.   pthread_mutex_unlock(&thd->mysys_var->mutex);
  588.   (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
  589.   pthread_mutex_unlock(&LOCK_open); // Must be unlocked first
  590.   pthread_mutex_lock(&thd->mysys_var->mutex);
  591.   thd->mysys_var->current_mutex= 0;
  592.   thd->mysys_var->current_cond= 0;
  593.   thd->proc_info= proc_info;
  594.   pthread_mutex_unlock(&thd->mysys_var->mutex);
  595. }
  596. TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
  597. {
  598.   DBUG_ENTER("reopen_name_locked_table");
  599.   if (thd->killed)
  600.     DBUG_RETURN(0);
  601.   TABLE* table;
  602.   if(!(table = table_list->table))
  603.     DBUG_RETURN(0);
  604.   char* db = thd->db ? thd->db : table_list->db;
  605.   char* table_name = table_list->name;
  606.   char key[MAX_DBKEY_LENGTH];
  607.   uint key_length;
  608.   key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
  609.   pthread_mutex_lock(&LOCK_open);
  610.   if (open_unireg_entry(thd, table, db, table_name, table_name, 1) ||
  611.       !(table->table_cache_key =memdup_root(&table->mem_root,(char*) key,
  612.     key_length)))
  613.     {
  614.       closefrm(table);
  615.       pthread_mutex_unlock(&LOCK_open);
  616.       DBUG_RETURN(0);
  617.     }
  618.   table->key_length=key_length;
  619.   table->version=0;
  620.   table->flush_version=0;
  621.   if (!key_cache_inited)
  622.     ha_key_cache();
  623.   table->in_use = thd;
  624.   check_unused();
  625.   pthread_mutex_unlock(&LOCK_open);
  626.   table->next = thd->open_tables;
  627.   thd->open_tables = table;
  628.   table->tablenr=thd->current_tablenr++;
  629.   table->used_fields=0;
  630.   table->const_table=0;
  631.   table->outer_join=table->null_row=table->maybe_null=0;
  632.   table->status=STATUS_NO_RECORD;
  633.   table->keys_in_use_for_query=table->used_keys= table->keys_in_use;
  634.   DBUG_RETURN(table);
  635. }
  636. /******************************************************************************
  637. ** open a table
  638. ** Uses a cache of open tables to find a table not in use.
  639. ** If refresh is a NULL pointer, then the is no version number checking and
  640. ** the table is not put in the thread-open-list
  641. ** If the return value is NULL and refresh is set then one must close
  642. ** all tables and retry the open
  643. ******************************************************************************/
  644. TABLE *open_table(THD *thd,const char *db,const char *table_name,
  645.   const char *alias,bool *refresh)
  646. {
  647.   reg1 TABLE *table;
  648.   char key[MAX_DBKEY_LENGTH];
  649.   uint key_length;
  650.   DBUG_ENTER("open_table");
  651.   /* find a unused table in the open table cache */
  652.   if (refresh)
  653.     *refresh=0;
  654.   if (thd->killed)
  655.     DBUG_RETURN(0);
  656.   key_length= (uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
  657.   int4store(key + key_length, thd->slave_proxy_id);
  658.   for (table=thd->temporary_tables; table ; table=table->next)
  659.   {
  660.     if (table->key_length == key_length+4 &&
  661. !memcmp(table->table_cache_key,key,key_length+4))
  662.     {
  663.       if (table->query_id == thd->query_id)
  664.       {
  665. my_printf_error(ER_CANT_REOPEN_TABLE,
  666. ER(ER_CANT_REOPEN_TABLE),MYF(0),table->table_name);
  667. DBUG_RETURN(0);
  668.       }
  669.       table->query_id=thd->query_id;
  670.       goto reset;
  671.     }
  672.   }
  673.   if (thd->locked_tables)
  674.   { // Using table locks
  675.     for (table=thd->open_tables; table ; table=table->next)
  676.     {
  677.       if (table->key_length == key_length &&
  678.   !memcmp(table->table_cache_key,key,key_length) &&
  679.   !my_strcasecmp(table->table_name,alias))
  680. goto reset;
  681.     }
  682.     my_printf_error(ER_TABLE_NOT_LOCKED,ER(ER_TABLE_NOT_LOCKED),MYF(0),alias);
  683.     DBUG_RETURN(0);
  684.   }
  685.   VOID(pthread_mutex_lock(&LOCK_open));
  686.   if (!thd->open_tables)
  687.     thd->version=refresh_version;
  688.   else if (thd->version != refresh_version && refresh)
  689.   {
  690.     /* Someone did a refresh while thread was opening tables */
  691.     *refresh=1;
  692.     VOID(pthread_mutex_unlock(&LOCK_open));
  693.     DBUG_RETURN(0);
  694.   }
  695.   for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ;
  696.        table && table->in_use ;
  697.        table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length))
  698.   {
  699.     if (table->version != refresh_version)
  700.     {
  701.       /*
  702.       ** There is a refresh in progress for this table
  703.       ** Wait until the table is freed or the thread is killed.
  704.       */
  705.       close_old_data_files(thd,thd->open_tables,0,0);
  706.       if (table->in_use != thd)
  707. wait_for_refresh(thd);
  708.       else
  709. VOID(pthread_mutex_unlock(&LOCK_open));
  710.       if (refresh)
  711. *refresh=1;
  712.       DBUG_RETURN(0);
  713.     }
  714.   }
  715.   if (table)
  716.   {
  717.     if (table == unused_tables)
  718.     { // First unused
  719.       unused_tables=unused_tables->next; // Remove from link
  720.       if (table == unused_tables)
  721. unused_tables=0;
  722.     }
  723.     table->prev->next=table->next; /* Remove from unused list */
  724.     table->next->prev=table->prev;
  725.   }
  726.   else
  727.   {
  728.     /* Free cache if too big */
  729.     while (open_cache.records > table_cache_size && unused_tables)
  730.       VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */
  731.     /* make a new table */
  732.     if (!(table=(TABLE*) my_malloc(sizeof(*table),MYF(MY_WME))))
  733.       DBUG_RETURN(NULL);
  734.     if (open_unireg_entry(thd, table,db,table_name,alias,1) ||
  735. !(table->table_cache_key=memdup_root(&table->mem_root,(char*) key,
  736.      key_length)))
  737.     {
  738.       MEM_ROOT* glob_alloc;
  739.       LINT_INIT(glob_alloc);
  740.       if (errno == ENOENT &&
  741.  (glob_alloc = my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC)))
  742. // Sasha: needed for replication
  743. // remember the name of the non-existent table
  744. // so we can try to download it from the master
  745.       {
  746. int table_name_len = (uint) strlen(table_name);
  747. int db_len = (uint) strlen(db);
  748. thd->last_nx_db = alloc_root(glob_alloc,db_len + table_name_len + 2);
  749. if(thd->last_nx_db)
  750. {
  751.   thd->last_nx_table = thd->last_nx_db + db_len + 1;
  752.   memcpy(thd->last_nx_table, table_name, table_name_len + 1);
  753.   memcpy(thd->last_nx_db, db, db_len + 1);
  754. }
  755.       }
  756.       table->next=table->prev=table;
  757.       free_cache_entry(table);
  758.       VOID(pthread_mutex_unlock(&LOCK_open));
  759.       DBUG_RETURN(NULL);
  760.     }
  761.     table->key_length=key_length;
  762.     table->version=refresh_version;
  763.     table->flush_version=flush_version;
  764.     if (!key_cache_inited)
  765.       ha_key_cache();
  766.     DBUG_PRINT("info", ("inserting table %p into the cache", table));
  767.     VOID(hash_insert(&open_cache,(byte*) table));
  768.   }
  769.   table->in_use=thd;
  770.   check_unused();
  771.   VOID(pthread_mutex_unlock(&LOCK_open));
  772.   if (refresh)
  773.   {
  774.     table->next=thd->open_tables; /* Link into simple list */
  775.     thd->open_tables=table;
  776.   }
  777.   table->reginfo.lock_type=TL_READ; /* Assume read */
  778.  reset:
  779.   /* Fix alias if table name changes */
  780.   if (strcmp(table->table_name,alias))
  781.   {
  782.     uint length=(uint) strlen(alias)+1;
  783.     table->table_name= (char*) my_realloc(table->table_name,length,
  784.   MYF(MY_WME));
  785.     memcpy(table->table_name,alias,length);
  786.     for (uint i=0 ; i < table->fields ; i++)
  787.       table->field[i]->table_name=table->table_name;
  788.   }
  789.   /* These variables are also set in reopen_table() */
  790.   table->tablenr=thd->current_tablenr++;
  791.   table->used_fields=0;
  792.   table->const_table=0;
  793.   table->outer_join=table->null_row=table->maybe_null=0;
  794.   table->status=STATUS_NO_RECORD;
  795.   table->keys_in_use_for_query=table->used_keys= table->keys_in_use;
  796.   dbug_assert(table->key_read == 0);
  797.   DBUG_RETURN(table);
  798. }
  799. TABLE *find_locked_table(THD *thd, const char *db,const char *table_name)
  800. {
  801.   char key[MAX_DBKEY_LENGTH];
  802.   uint key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
  803.   for (TABLE *table=thd->open_tables; table ; table=table->next)
  804.   {
  805.     if (table->key_length == key_length &&
  806. !memcmp(table->table_cache_key,key,key_length))
  807.       return table;
  808.   }
  809.   return(0);
  810. }
  811. /****************************************************************************
  812. ** Reopen an table because the definition has changed. The date file for the
  813. ** table is already closed.
  814. ** Returns 0 if ok.
  815. ** If table can't be reopened, the entry is unchanged.
  816. ****************************************************************************/
  817. bool reopen_table(TABLE *table,bool locked)
  818. {
  819.   TABLE tmp;
  820.   char *db=table->table_cache_key;
  821.   char *table_name=table->real_name;
  822.   bool error=1;
  823.   Field **field;
  824.   uint key,part;
  825.   DBUG_ENTER("reopen_table");
  826. #ifdef EXTRA_DEBUG
  827.   if (table->db_stat)
  828.     sql_print_error("Table %s had a open data handler in reopen_table",
  829.     table->table_name);
  830. #endif
  831.   if (!locked)
  832.     VOID(pthread_mutex_lock(&LOCK_open));
  833.   if (open_unireg_entry(current_thd,&tmp,db,table_name,table->table_name,
  834. locked))
  835.     goto end;
  836.   free_io_cache(table);
  837.   if (!(tmp.table_cache_key= memdup_root(&tmp.mem_root,db,
  838.  table->key_length)))
  839.   {
  840.     closefrm(&tmp); // End of memory
  841.     goto end;
  842.   }
  843.   tmp.key_length=table->key_length;
  844.   tmp.in_use=table->in_use;
  845.   tmp.used_keys=tmp.keys_in_use;
  846.   tmp.reginfo.lock_type=table->reginfo.lock_type;
  847.   tmp.version=refresh_version;
  848.   tmp.next=table->next;
  849.   tmp.prev=table->prev;
  850.   /* This list copies varibles set by open_table */
  851.   tmp.tablenr= table->tablenr;
  852.   tmp.tmp_table= table->tmp_table;
  853.   tmp.used_fields= table->used_fields;
  854.   tmp.const_table= table->const_table;
  855.   tmp.outer_join= table->outer_join;
  856.   tmp.null_row= table->null_row;
  857.   tmp.status= table->status;
  858.   tmp.grant= table->grant;
  859.   if (table->file)
  860.     VOID(closefrm(table)); // close file, free everything
  861.   *table=tmp;
  862.   table->file->change_table_ptr(table);
  863.   for (field=table->field ; *field ; field++)
  864.   {
  865.     (*field)->table=table;
  866.     (*field)->table_name=table->table_name;
  867.   }
  868.   for (key=0 ; key < table->keys ; key++)
  869.     for (part=0 ; part < table->key_info[key].usable_key_parts ; part++)
  870.       table->key_info[key].key_part[part].field->table=table;
  871.   VOID(pthread_cond_broadcast(&COND_refresh));
  872.   error=0;
  873.  end:
  874.   if (!locked)
  875.     VOID(pthread_mutex_unlock(&LOCK_open));
  876.   DBUG_RETURN(error);
  877. }
  878. /*
  879.   Used with ALTER TABLE:
  880.   Close all instanses of table when LOCK TABLES is in used;
  881.   Close first all instances of table and then reopen them
  882.  */
  883. bool close_data_tables(THD *thd,const char *db, const char *table_name)
  884. {
  885.   TABLE *table;
  886.   for (table=thd->open_tables; table ; table=table->next)
  887.   {
  888.     if (!strcmp(table->real_name,table_name) &&
  889. !strcmp(table->table_cache_key,db))
  890.     {
  891.       mysql_lock_remove(thd, thd->locked_tables,table);
  892.       table->file->close();
  893.       table->db_stat=0;
  894.     }
  895.   }
  896.   return 0; // For the future
  897. }
  898. /*
  899.   Reopen all tables with closed data files
  900.   One should have lock on LOCK_open when calling this
  901. */
  902. bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
  903. {
  904.   DBUG_ENTER("reopen_tables");
  905.   if (!thd->open_tables)
  906.     DBUG_RETURN(0);
  907.   TABLE *table,*next,**prev;
  908.   TABLE **tables,**tables_ptr; // For locks
  909.   bool error=0;
  910.   if (get_locks)
  911.   {
  912.     /* The ptr is checked later */
  913.     uint opens=0;
  914.     for (table=thd->open_tables; table ; table=table->next) opens++;
  915.     tables= (TABLE**) my_alloca(sizeof(TABLE*)*opens);
  916.   }
  917.   else
  918.     tables= &thd->open_tables;
  919.   tables_ptr =tables;
  920.   prev= &thd->open_tables;
  921.   for (table=thd->open_tables; table ; table=next)
  922.   {
  923.     uint db_stat=table->db_stat;
  924.     next=table->next;
  925.     if (!tables || (!db_stat && reopen_table(table,1)))
  926.     {
  927.       my_error(ER_CANT_REOPEN_TABLE,MYF(0),table->table_name);
  928.       VOID(hash_delete(&open_cache,(byte*) table));
  929.       error=1;
  930.     }
  931.     else
  932.     {
  933.       *prev= table;
  934.       prev= &table->next;
  935.       if (get_locks && !db_stat)
  936. *tables_ptr++= table; // need new lock on this
  937.       if (in_refresh)
  938.       {
  939. table->version=0;
  940. table->locked_by_flush=0;
  941.       }
  942.     }
  943.   }
  944.   if (tables != tables_ptr) // Should we get back old locks
  945.   {
  946.     MYSQL_LOCK *lock;
  947.     /* We should always get these locks */
  948.     thd->some_tables_deleted=0;
  949.     if ((lock=mysql_lock_tables(thd,tables,(uint) (tables_ptr-tables))))
  950.     {
  951.       thd->locked_tables=mysql_lock_merge(thd->locked_tables,lock);
  952.     }
  953.     else
  954.       error=1;
  955.   }
  956.   if (get_locks && tables)
  957.   {
  958.     my_afree((gptr) tables);
  959.   }
  960.   VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
  961.   *prev=0;
  962.   DBUG_RETURN(error);
  963. }
  964. /*
  965.   Close handlers for tables in list, but leave the TABLE structure
  966.   intact so that we can re-open these quickly
  967.   abort_locks is set if called from flush_tables.
  968. */
  969. void close_old_data_files(THD *thd, TABLE *table, bool abort_locks,
  970.   bool send_refresh)
  971. {
  972.   DBUG_ENTER("close_old_data_files");
  973.   bool found=send_refresh;
  974.   for (; table ; table=table->next)
  975.   {
  976.     if (table->version != refresh_version)
  977.     {
  978.       found=1;
  979.       if (!abort_locks) // If not from flush tables
  980. table->version = refresh_version; // Let other threads use table
  981.       if (table->db_stat)
  982.       {
  983. if (abort_locks)
  984. {
  985.   mysql_lock_abort(thd,table); // Close waiting threads
  986.   mysql_lock_remove(thd, thd->locked_tables,table);
  987.   table->locked_by_flush=1; // Will be reopened with locks
  988. }
  989. table->file->close();
  990. table->db_stat=0;
  991.       }
  992.     }
  993.   }
  994.   if (found)
  995.     VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
  996.   DBUG_VOID_RETURN;
  997. }
  998. /*
  999.   Wait until all threads has closed the tables in the list
  1000.   We have also to wait if there is thread that has a lock on this table even
  1001.   if the table is closed
  1002. */
  1003. bool table_is_used(TABLE *table, bool wait_for_name_lock)
  1004. {
  1005.   do
  1006.   {
  1007.     char *key= table->table_cache_key;
  1008.     uint key_length=table->key_length;
  1009.     for (TABLE *search=(TABLE*) hash_search(&open_cache,
  1010.     (byte*) key,key_length) ;
  1011.  search ;
  1012.  search = (TABLE*) hash_next(&open_cache,(byte*) key,key_length))
  1013.     {
  1014.       if (search->locked_by_flush ||
  1015.   search->locked_by_name && wait_for_name_lock ||
  1016.   search->db_stat && search->version < refresh_version)
  1017. return 1; // Table is used
  1018.     }
  1019.   } while ((table=table->next));
  1020.   return 0;
  1021. }
  1022. /* Wait until all used tables are refreshed */
  1023. bool wait_for_tables(THD *thd)
  1024. {
  1025.   bool result;
  1026.   DBUG_ENTER("wait_for_tables");
  1027.   thd->proc_info="Waiting for tables";
  1028.   pthread_mutex_lock(&LOCK_open);
  1029.   while (!thd->killed)
  1030.   {
  1031.     thd->some_tables_deleted=0;
  1032.     close_old_data_files(thd,thd->open_tables,0,dropping_tables != 0);
  1033.     if (!table_is_used(thd->open_tables,1))
  1034.       break;
  1035.     (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
  1036.   }
  1037.   if (thd->killed)
  1038.     result= 1; // aborted
  1039.   else
  1040.   {
  1041.     /* Now we can open all tables without any interference */
  1042.     thd->proc_info="Reopen tables";
  1043.     result=reopen_tables(thd,0,0);
  1044.      
  1045.   }
  1046.   pthread_mutex_unlock(&LOCK_open);
  1047.   thd->proc_info=0;
  1048.   DBUG_RETURN(result);
  1049. }
  1050. /* drop tables from locked list */
  1051. bool drop_locked_tables(THD *thd,const char *db, const char *table_name)
  1052. {
  1053.   TABLE *table,*next,**prev;
  1054.   bool found=0;
  1055.   prev= &thd->open_tables;
  1056.   for (table=thd->open_tables; table ; table=next)
  1057.   {
  1058.     next=table->next;
  1059.     if (!strcmp(table->real_name,table_name) &&
  1060. !strcmp(table->table_cache_key,db))
  1061.     {
  1062.       mysql_lock_remove(thd, thd->locked_tables,table);
  1063.       VOID(hash_delete(&open_cache,(byte*) table));
  1064.       found=1;
  1065.     }
  1066.     else
  1067.     {
  1068.       *prev=table;
  1069.       prev= &table->next;
  1070.     }
  1071.   }
  1072.   *prev=0;
  1073.   if (found)
  1074.     VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
  1075.   if (thd->locked_tables && thd->locked_tables->table_count == 0)
  1076.   {
  1077.     my_free((gptr) thd->locked_tables,MYF(0));
  1078.     thd->locked_tables=0;
  1079.   }
  1080.   return found;
  1081. }
  1082. /* lock table to force abort of any threads trying to use table */
  1083. void abort_locked_tables(THD *thd,const char *db, const char *table_name)
  1084. {
  1085.   TABLE *table;
  1086.   for (table=thd->open_tables; table ; table=table->next)
  1087.   {
  1088.     if (!strcmp(table->real_name,table_name) &&
  1089. !strcmp(table->table_cache_key,db))
  1090.       mysql_lock_abort(thd,table);
  1091.   }
  1092. }
  1093. /****************************************************************************
  1094. ** open_unireg_entry
  1095. ** Purpose : Load a table definition from file and open unireg table
  1096. ** Args : entry with DB and table given
  1097. ** Returns : 0 if ok
  1098. ** Note that the extra argument for open is taken from thd->open_options
  1099. */
  1100. static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
  1101.      const char *name, const char *alias, bool locked)
  1102. {
  1103.   char path[FN_REFLEN];
  1104.   int error;
  1105.   DBUG_ENTER("open_unireg_entry");
  1106.   (void) sprintf(path,"%s/%s/%s",mysql_data_home,db,name);
  1107.   if (openfrm(path,alias,
  1108.        (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
  1109.        HA_TRY_READ_ONLY),
  1110.        READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
  1111.       thd->open_options, entry))
  1112.   {
  1113.     if (!entry->crashed)
  1114.       goto err; // Can't repair the table
  1115.     TABLE_LIST table_list;
  1116.     table_list.db=(char*) db;
  1117.     table_list.name=(char*) name;
  1118.     table_list.next=0;
  1119.     if (!locked)
  1120.       pthread_mutex_lock(&LOCK_open);
  1121.     if ((error=lock_table_name(thd,&table_list)))
  1122.     {
  1123.       if (error < 0)
  1124.       {
  1125. if (!locked)
  1126.   pthread_mutex_unlock(&LOCK_open);
  1127. goto err;
  1128.       }
  1129.       if (wait_for_locked_table_names(thd,&table_list))
  1130.       {
  1131. unlock_table_name(thd,&table_list);
  1132. if (!locked)
  1133.   pthread_mutex_unlock(&LOCK_open);
  1134. goto err;
  1135.       }
  1136.     }
  1137.     pthread_mutex_unlock(&LOCK_open);
  1138.     thd->net.last_error[0]=0; // Clear error message
  1139.     thd->net.last_errno=0;
  1140.     error=0;
  1141.     if (openfrm(path,alias,
  1142. (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
  1143.  HA_TRY_READ_ONLY),
  1144. READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
  1145. ha_open_options | HA_OPEN_FOR_REPAIR,
  1146. entry) || ! entry->file ||
  1147. (entry->file->is_crashed() && entry->file->check_and_repair(thd)))
  1148.     {
  1149.       /* Give right error message */
  1150.       thd->net.last_error[0]=0;
  1151.       thd->net.last_errno=0;
  1152.       my_error(ER_NOT_KEYFILE, MYF(0), name, my_errno);
  1153.       sql_print_error("Error: Couldn't repair table: %s.%s",db,name);
  1154.       if (entry->file)
  1155. closefrm(entry);
  1156.       error=1;
  1157.     }
  1158.     else
  1159.     {
  1160.       thd->net.last_error[0]=0; // Clear error message
  1161.       thd->net.last_errno=0;
  1162.     }
  1163.     if (locked)
  1164.       pthread_mutex_lock(&LOCK_open);      // Get back original lock
  1165.     unlock_table_name(thd,&table_list);
  1166.     if (error)
  1167.       goto err;
  1168.   }
  1169.   (void) entry->file->extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
  1170.   DBUG_RETURN(0);
  1171. err:
  1172.   DBUG_RETURN(1);
  1173. }
  1174. /*****************************************************************************
  1175. ** open all tables in list
  1176. *****************************************************************************/
  1177. int open_tables(THD *thd,TABLE_LIST *start)
  1178. {
  1179.   TABLE_LIST *tables;
  1180.   bool refresh;
  1181.   int result=0;
  1182.   DBUG_ENTER("open_tables");
  1183.  restart:
  1184.   thd->proc_info="Opening tables";
  1185.   for (tables=start ; tables ; tables=tables->next)
  1186.   {
  1187.     if (!tables->table &&
  1188. !(tables->table=open_table(thd,
  1189.    tables->db ? tables->db : thd->db,
  1190.    tables->real_name,
  1191.    tables->name, &refresh)))
  1192.     {
  1193.       if (refresh) // Refresh in progress
  1194.       {
  1195. /* close all 'old' tables used by this thread */
  1196. pthread_mutex_lock(&LOCK_open);
  1197. thd->version=refresh_version;
  1198. TABLE **prev_table= &thd->open_tables;
  1199. bool found=0;
  1200. for (TABLE_LIST *tmp=start ; tmp ; tmp=tmp->next)
  1201. {
  1202.   if (tmp->table)
  1203.   {
  1204.     if (tmp->table->version != refresh_version ||
  1205. ! tmp->table->db_stat)
  1206.     {
  1207.       VOID(hash_delete(&open_cache,(byte*) tmp->table));
  1208.       tmp->table=0;
  1209.       found=1;
  1210.     }
  1211.     else
  1212.     {
  1213.       *prev_table= tmp->table; // Relink open list
  1214.       prev_table= &tmp->table->next;
  1215.     }
  1216.   }
  1217. }
  1218. *prev_table=0;
  1219. if (found)
  1220.   VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
  1221. pthread_mutex_unlock(&LOCK_open);
  1222. goto restart;
  1223.       }
  1224.       result= -1; // Fatal error
  1225.       break;
  1226.     }
  1227.     if (tables->lock_type != TL_UNLOCK)
  1228.       tables->table->reginfo.lock_type=tables->lock_type;
  1229.     tables->table->grant= tables->grant;
  1230.   }
  1231.   thd->proc_info=0;
  1232.   DBUG_RETURN(result);
  1233. }
  1234. TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
  1235. {
  1236.   TABLE *table;
  1237.   bool refresh;
  1238.   DBUG_ENTER("open_ltable");
  1239. #ifdef __WIN__
  1240.   /* Win32 can't drop a file that is open */
  1241.   if (lock_type == TL_WRITE_ALLOW_READ)
  1242.     lock_type= TL_WRITE;
  1243. #endif
  1244.   thd->proc_info="Opening table";
  1245.   while (!(table=open_table(thd,table_list->db ? table_list->db : thd->db,
  1246.     table_list->real_name,table_list->name,
  1247.     &refresh)) && refresh) ;
  1248.   if (table)
  1249.   {
  1250.     table_list->table=table;
  1251.     table->grant= table_list->grant;
  1252.     if (thd->locked_tables)
  1253.     {
  1254.       thd->proc_info=0;
  1255.       if ((int) lock_type >= (int) TL_WRITE_ALLOW_READ &&
  1256.   (int) table->reginfo.lock_type < (int) TL_WRITE_ALLOW_READ)
  1257.       {
  1258. my_printf_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,
  1259. ER(ER_TABLE_NOT_LOCKED_FOR_WRITE),
  1260. MYF(0),table_list->name);
  1261. DBUG_RETURN(0);
  1262.       }
  1263.       thd->proc_info=0;
  1264.       DBUG_RETURN(table);
  1265.     }
  1266.     if ((table->reginfo.lock_type=lock_type) != TL_UNLOCK)
  1267.       if (!(thd->lock=mysql_lock_tables(thd,&table_list->table,1)))
  1268.   DBUG_RETURN(0);
  1269.   }
  1270.   thd->proc_info=0;
  1271.   DBUG_RETURN(table);
  1272. }
  1273. /*
  1274. ** Open all tables in list and locks them for read.
  1275. ** The lock will automaticly be freed by the close_thread_tables
  1276. */
  1277. int open_and_lock_tables(THD *thd,TABLE_LIST *tables)
  1278. {
  1279.   if (open_tables(thd,tables) || lock_tables(thd,tables))
  1280.     return -1; /* purecov: inspected */
  1281.   return 0;
  1282. }
  1283. int lock_tables(THD *thd,TABLE_LIST *tables)
  1284. {
  1285.   if (tables && !thd->locked_tables)
  1286.   {
  1287.     uint count=0;
  1288.     TABLE_LIST *table;
  1289.     for (table = tables ; table ; table=table->next)
  1290.       count++;
  1291.     TABLE **start,**ptr;
  1292.     if (!(ptr=start=(TABLE**) sql_alloc(sizeof(TABLE*)*count)))
  1293.       return -1;
  1294.     for (table = tables ; table ; table=table->next)
  1295.       *(ptr++)= table->table;
  1296.     if (!(thd->lock=mysql_lock_tables(thd,start,count)))
  1297.       return -1; /* purecov: inspected */
  1298.   }
  1299.   return 0;
  1300. }
  1301. /*
  1302. ** Open a single table without table caching and don't set it in open_list
  1303. ** Used by alter_table to open a temporary table and when creating
  1304. ** a temporary table with CREATE TEMPORARY ...
  1305. */
  1306. TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
  1307.     const char *table_name, bool link_in_list)
  1308. {
  1309.   TABLE *tmp_table;
  1310.   DBUG_ENTER("open_temporary_table");
  1311.   // the extra size in my_malloc() is for table_cache_key
  1312.   //  4 bytes for master thread id if we are in the slave
  1313.   //  1 byte to terminate db
  1314.   //  1 byte to terminate table_name
  1315.   // total of 6 extra bytes in my_malloc in addition to table/db stuff
  1316.   if (!(tmp_table=(TABLE*) my_malloc(sizeof(*tmp_table)+(uint) strlen(db)+
  1317.      (uint) strlen(table_name)+6,
  1318.      MYF(MY_WME))))
  1319.     DBUG_RETURN(0); /* purecov: inspected */
  1320.   if (openfrm(path, table_name,
  1321.       (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
  1322.       HA_TRY_READ_ONLY),
  1323.       READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
  1324.       ha_open_options,
  1325.       tmp_table))
  1326.   {
  1327.     DBUG_RETURN(0);
  1328.   }
  1329.   tmp_table->file->extra(HA_EXTRA_NO_READCHECK); // Not needed in SQL
  1330.   tmp_table->reginfo.lock_type=TL_WRITE; // Simulate locked
  1331.   tmp_table->tmp_table = 1;
  1332.   tmp_table->table_cache_key=(char*) (tmp_table+1);
  1333.   tmp_table->key_length= (uint) (strmov(strmov(tmp_table->table_cache_key,db)
  1334. +1, table_name)
  1335.  - tmp_table->table_cache_key)+1;
  1336.   int4store(tmp_table->table_cache_key + tmp_table->key_length,
  1337.     thd->slave_proxy_id);
  1338.   tmp_table->key_length += 4;
  1339.   if (link_in_list)
  1340.   {
  1341.     tmp_table->next=thd->temporary_tables;
  1342.     thd->temporary_tables=tmp_table;
  1343.     if(thd->slave_thread)
  1344.       ++slave_open_temp_tables;
  1345.   }
  1346.   DBUG_RETURN(tmp_table);
  1347. }
  1348. bool rm_temporary_table(enum db_type base, char *path)
  1349. {
  1350.   bool error=0;
  1351.   fn_format(path, path,"",reg_ext,4);
  1352.   unpack_filename(path,path);
  1353.   if (my_delete(path,MYF(0)))
  1354.     error=1; /* purecov: inspected */
  1355.   *fn_ext(path)=''; // remove extension
  1356.   handler *file=get_new_handler((TABLE*) 0, base);
  1357.   if (file && file->delete_table(path))
  1358.     error=1;
  1359.   delete file;
  1360.   return error;
  1361. }
  1362. /*****************************************************************************
  1363. ** find field in list or tables. if field is unqualifed and unique,
  1364. ** return unique field
  1365. ******************************************************************************/
  1366. #define WRONG_GRANT (Field*) -1
  1367. Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
  1368.    bool check_grants, bool allow_rowid)
  1369. {
  1370.   Field *field;
  1371.   if (table->name_hash.records)
  1372.   {
  1373.     if ((field=(Field*) hash_search(&table->name_hash,(byte*) name,
  1374.     length)))
  1375.       goto found;
  1376.   }
  1377.   else
  1378.   {
  1379.     Field **ptr=table->field;
  1380.     while ((field = *ptr++))
  1381.     {
  1382.       if (!my_strcasecmp(field->field_name, name))
  1383. goto found;
  1384.     }
  1385.   }
  1386.   if (allow_rowid && !my_strcasecmp(name,"_rowid") &&
  1387.       (field=table->rowid_field))
  1388.     goto found;
  1389.   return (Field*) 0;
  1390.  found:
  1391.   if (thd->set_query_id)
  1392.   {
  1393.     if (field->query_id != thd->query_id)
  1394.     {
  1395.       field->query_id=thd->query_id;
  1396.       table->used_fields++;
  1397.       if (field->part_of_key)
  1398.       {
  1399. if (!(field->part_of_key & table->ref_primary_key))
  1400.   table->used_keys&=field->part_of_key;
  1401.       }
  1402.       else
  1403. table->used_keys=0;
  1404.     }
  1405.     else
  1406.       thd->dupp_field=field;
  1407.   }
  1408.   if (check_grants && !thd->master_access && check_grant_column(thd,table,name,length))
  1409.     return WRONG_GRANT;
  1410.   return field;
  1411. }
  1412. Field *
  1413. find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables)
  1414. {
  1415.   Field *found=0;
  1416.   const char *db=item->db_name;
  1417.   const char *table_name=item->table_name;
  1418.   const char *name=item->field_name;
  1419.   uint length=(uint) strlen(name);
  1420.   if (table_name)
  1421.   { /* Qualified field */
  1422.     bool found_table=0;
  1423.     for (; tables ; tables=tables->next)
  1424.     {
  1425.       if (!strcmp(tables->name,table_name) &&
  1426.   (!db ||
  1427.    (tables->db && !strcmp(db,tables->db)) ||
  1428.    (!tables->db && !strcmp(db,thd->db))))
  1429.       {
  1430. found_table=1;
  1431. Field *find=find_field_in_table(thd,tables->table,name,length,
  1432. grant_option && !thd->master_access,1);
  1433. if (find)
  1434. {
  1435.   if (find == WRONG_GRANT)
  1436.     return (Field*) 0;
  1437.   if (db || !thd->where)
  1438.     return find;
  1439.   if (found)
  1440.   {
  1441.     my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
  1442.     item->full_name(),thd->where);
  1443.     return (Field*) 0;
  1444.   }
  1445.   found=find;
  1446. }
  1447.       }
  1448.     }
  1449.     if (found)
  1450.       return found;
  1451.     if (!found_table)
  1452.     {
  1453.       char buff[NAME_LEN*2+1];
  1454.       if (db)
  1455.       {
  1456. strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS);
  1457. table_name=buff;
  1458.       }
  1459.       my_printf_error(ER_UNKNOWN_TABLE,ER(ER_UNKNOWN_TABLE),MYF(0),table_name,
  1460.       thd->where);
  1461.     }
  1462.     else
  1463.       my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0),
  1464.       item->full_name(),thd->where);
  1465.     return (Field*) 0;
  1466.   }
  1467.   bool allow_rowid= tables && !tables->next; // Only one table
  1468.   for (; tables ; tables=tables->next)
  1469.   {
  1470.     Field *field=find_field_in_table(thd,tables->table,name,length,
  1471.      grant_option && !thd->master_access, allow_rowid);
  1472.     if (field)
  1473.     {
  1474.       if (field == WRONG_GRANT)
  1475. return (Field*) 0;
  1476.       if (found)
  1477.       {
  1478. if (!thd->where) // Returns first found
  1479.   break;
  1480. my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
  1481. name,thd->where);
  1482. return (Field*) 0;
  1483.       }
  1484.       found=field;
  1485.     }
  1486.   }
  1487.   if (found)
  1488.     return found;
  1489.   my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),
  1490.   MYF(0),item->full_name(),thd->where);
  1491.   return (Field*) 0;
  1492. }
  1493. Item **
  1494. find_item_in_list(Item *find,List<Item> &items)
  1495. {
  1496.   List_iterator<Item> li(items);
  1497.   Item **found=0,*item;
  1498.   const char *field_name=0;
  1499.   const char *table_name=0;
  1500.   if (find->type() == Item::FIELD_ITEM || find->type() == Item::REF_ITEM)
  1501.   {
  1502.     field_name= ((Item_ident*) find)->field_name;
  1503.     table_name= ((Item_ident*) find)->table_name;
  1504.   }
  1505.   while ((item=li++))
  1506.   {
  1507.     if (field_name && item->type() == Item::FIELD_ITEM)
  1508.     {
  1509.       if (!my_strcasecmp(((Item_field*) item)->name,field_name))
  1510.       {
  1511. if (!table_name)
  1512. {
  1513.   if (found)
  1514.   {
  1515.     if ((*found)->eq(item))
  1516.       continue; // Same field twice (Access?)
  1517.     if (current_thd->where)
  1518.       my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
  1519.       find->full_name(), current_thd->where);
  1520.     return (Item**) 0;
  1521.   }
  1522.   found=li.ref();
  1523. }
  1524. else if (!strcmp(((Item_field*) item)->table_name,table_name))
  1525. {
  1526.   found=li.ref();
  1527.   break;
  1528. }
  1529.       }
  1530.     }
  1531.     else if (!table_name && (item->eq(find) ||
  1532.      find->name &&
  1533.      !my_strcasecmp(item->name,find->name)))
  1534.     {
  1535.       found=li.ref();
  1536.       break;
  1537.     }
  1538.   }
  1539.   if (!found && current_thd->where)
  1540.     my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0),
  1541.     find->full_name(),current_thd->where);
  1542.   return found;
  1543. }
  1544. /****************************************************************************
  1545. ** Check that all given fields exists and fill struct with current data
  1546. ** Check also that the 'used keys' and 'ignored keys' exists and set up the
  1547. ** table structure accordingly
  1548. ****************************************************************************/
  1549. int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
  1550.  bool set_query_id, List<Item> *sum_func_list)
  1551. {
  1552.   reg2 Item *item;
  1553.   List_iterator<Item> it(fields);
  1554.   DBUG_ENTER("setup_fields");
  1555.   thd->set_query_id=set_query_id;
  1556.   thd->allow_sum_func= test(sum_func_list);
  1557.   thd->where="field list";
  1558.   /* Remap table numbers if INSERT ... SELECT */
  1559.   uint tablenr=0;
  1560.   for (TABLE_LIST *table=tables ; table ; table=table->next,tablenr++)
  1561.   {
  1562.     table->table->tablenr=tablenr;
  1563.     table->table->map= (table_map) 1 << tablenr;
  1564.     if ((table->table->outer_join=table->outer_join))
  1565.       table->table->maybe_null=1; // LEFT OUTER JOIN ...
  1566.     if (table->use_index)
  1567.     {
  1568.       key_map map= get_key_map_from_key_list(thd,table->table,
  1569.      table->use_index);
  1570.       if (map == ~(key_map) 0)
  1571. DBUG_RETURN(-1);
  1572.       table->table->keys_in_use_for_query=map;
  1573.     }
  1574.     if (table->ignore_index)
  1575.     {
  1576.       key_map map= get_key_map_from_key_list(thd,table->table,
  1577.      table->ignore_index);
  1578.       if (map == ~(key_map) 0)
  1579. DBUG_RETURN(-1);
  1580.       table->table->keys_in_use_for_query &= ~map;
  1581.     }
  1582.   }
  1583.   if (tablenr > MAX_TABLES)
  1584.   {
  1585.     my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES);
  1586.     DBUG_RETURN(-1);
  1587.   }
  1588.   while ((item=it++))
  1589.   {
  1590.     if (item->type() == Item::FIELD_ITEM &&
  1591. ((Item_field*) item)->field_name[0] == '*')
  1592.     {
  1593.       if (insert_fields(thd,tables,((Item_field*) item)->table_name,&it))
  1594. DBUG_RETURN(-1); /* purecov: inspected */
  1595.     }
  1596.     else
  1597.     {
  1598.       if (item->fix_fields(thd,tables))
  1599. DBUG_RETURN(-1); /* purecov: inspected */
  1600.       if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
  1601. item->split_sum_func(*sum_func_list);
  1602.       thd->used_tables|=item->used_tables();
  1603.     }
  1604.   }
  1605.   DBUG_RETURN(test(thd->fatal_error));
  1606. }
  1607. static key_map get_key_map_from_key_list(THD *thd, TABLE *table,
  1608.  List<String> *index_list)
  1609. {
  1610.   key_map map=0;
  1611.   List_iterator<String> it(*index_list);
  1612.   String *name;
  1613.   uint pos;
  1614.   while ((name=it++))
  1615.   {
  1616.     if ((pos=find_type(name->c_ptr(), &table->keynames, 1+2)) <= 0)
  1617.     {
  1618.       my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), name->c_ptr(),
  1619.        table->real_name);
  1620.       return (~ (key_map) 0);
  1621.     }
  1622.     map|= ((key_map) 1) << (pos-1);
  1623.   }
  1624.   return map;
  1625. }
  1626. /****************************************************************************
  1627. ** This just drops in all fields instead of current '*' field
  1628. ** Returns pointer to last inserted field if ok
  1629. ****************************************************************************/
  1630. static bool
  1631. insert_fields(THD *thd,TABLE_LIST *tables, const char *table_name,
  1632.       List_iterator<Item> *it)
  1633. {
  1634.   uint found;
  1635.   DBUG_ENTER("insert_fields");
  1636.   found=0;
  1637.   for (; tables ; tables=tables->next)
  1638.   {
  1639.     TABLE *table=tables->table;
  1640.     if (grant_option && !thd->master_access &&
  1641. check_grant_all_columns(thd,SELECT_ACL,table) )
  1642.       DBUG_RETURN(-1);
  1643.     if (!table_name || !strcmp(table_name,tables->name))
  1644.     {
  1645.       Field **ptr=table->field,*field;
  1646.       thd->used_tables|=table->map;
  1647.       while ((field = *ptr++))
  1648.       {
  1649. Item_field *item= new Item_field(field);
  1650. if (!found++)
  1651.   (void) it->replace(item);
  1652. else
  1653.   it->after(item);
  1654. if (field->query_id == thd->query_id)
  1655.   thd->dupp_field=field;
  1656. field->query_id=thd->query_id;
  1657. if (field->part_of_key)
  1658. {
  1659.   if (!(field->part_of_key & table->ref_primary_key))
  1660.     table->used_keys&=field->part_of_key;
  1661. }
  1662. else
  1663.   table->used_keys=0;
  1664.       }
  1665.       /* All fields are used */
  1666.       table->used_fields=table->fields;
  1667.     }
  1668.   }
  1669.   if (!found)
  1670.   {
  1671.     if (!table_name)
  1672.       my_error(ER_NO_TABLES_USED,MYF(0));
  1673.     else
  1674.       my_error(ER_BAD_TABLE_ERROR,MYF(0),table_name);
  1675.   }
  1676.   DBUG_RETURN(!found);
  1677. }
  1678. /*
  1679. ** Fix all conditions and outer join expressions
  1680. */
  1681. int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
  1682. {
  1683.   DBUG_ENTER("setup_conds");
  1684.   thd->set_query_id=1;
  1685.   thd->cond_count=0;
  1686.   thd->allow_sum_func=0;
  1687.   if (*conds)
  1688.   {
  1689.     thd->where="where clause";
  1690.     if ((*conds)->fix_fields(thd,tables))
  1691.       DBUG_RETURN(1);
  1692.   }
  1693.   /* Check if we are using outer joins */
  1694.   for (TABLE_LIST *table=tables ; table ; table=table->next)
  1695.   {
  1696.     if (table->on_expr)
  1697.     {
  1698.       /* Make a join an a expression */
  1699.       thd->where="on clause";
  1700.       if (table->on_expr->fix_fields(thd,tables))
  1701. DBUG_RETURN(1);
  1702.       thd->cond_count++;
  1703.       /* If it's a normal join, add the ON/USING expression to the WHERE */
  1704.       if (!table->outer_join)
  1705.       {
  1706. if (!(*conds=and_conds(*conds, table->on_expr)))
  1707.   DBUG_RETURN(1);
  1708. table->on_expr=0;
  1709.       }
  1710.     }
  1711.     if (table->natural_join)
  1712.     {
  1713.       /* Make a join of all fields with have the same name */
  1714.       TABLE *t1=table->table;
  1715.       TABLE *t2=table->natural_join->table;
  1716.       Item_cond_and *cond_and=new Item_cond_and();
  1717.       if (!cond_and) // If not out of memory
  1718. DBUG_RETURN(1);
  1719.       uint i,j;
  1720.       for (i=0 ; i < t1->fields ; i++)
  1721.       {
  1722. // TODO: This could be optimized to use hashed names if t2 had a hash
  1723. for (j=0 ; j < t2->fields ; j++)
  1724. {
  1725.   key_map tmp_map;
  1726.   if (!my_strcasecmp(t1->field[i]->field_name,
  1727.      t2->field[j]->field_name))
  1728.   {
  1729.     Item_func_eq *tmp=new Item_func_eq(new Item_field(t1->field[i]),
  1730.        new Item_field(t2->field[j]));
  1731.     if (!tmp)
  1732.       DBUG_RETURN(1);
  1733.     tmp->fix_length_and_dec(); // Update cmp_type
  1734.     tmp->const_item_cache=0;
  1735.     /* Mark field used for table cache */
  1736.     t1->field[i]->query_id=t2->field[j]->query_id=thd->query_id;
  1737.     cond_and->list.push_back(tmp);
  1738.     if ((tmp_map=t1->field[i]->part_of_key))
  1739.     {
  1740.       if (!(tmp_map & t1->ref_primary_key))
  1741. t1->used_keys&=tmp_map;
  1742.     }
  1743.     else
  1744.       t1->used_keys=0;
  1745.     if ((tmp_map=t2->field[j]->part_of_key))
  1746.     {
  1747.       if (!(tmp_map & t2->ref_primary_key))
  1748. t2->used_keys&=tmp_map;
  1749.     }
  1750.     else
  1751.       t2->used_keys=0;
  1752.     break;
  1753.   }
  1754. }
  1755.       }
  1756.       cond_and->used_tables_cache= t1->map | t2->map;
  1757.       thd->cond_count+=cond_and->list.elements;
  1758.       if (!table->outer_join) // Not left join
  1759.       {
  1760. if (!(*conds=and_conds(*conds, cond_and)))
  1761.   DBUG_RETURN(1);
  1762.       }
  1763.       else
  1764. table->on_expr=and_conds(table->on_expr,cond_and);
  1765.     }
  1766.   }
  1767.   DBUG_RETURN(test(thd->fatal_error));
  1768. }
  1769. /******************************************************************************
  1770. ** Fill a record with data (for INSERT or UPDATE)
  1771. ** Returns : 1 if some field has wrong type
  1772. ******************************************************************************/
  1773. int
  1774. fill_record(List<Item> &fields,List<Item> &values)
  1775. {
  1776.   List_iterator<Item> f(fields),v(values);
  1777.   Item *value;
  1778.   Item_field *field;
  1779.   DBUG_ENTER("fill_record");
  1780.   while ((field=(Item_field*) f++))
  1781.   {
  1782.     value=v++;
  1783.     if (value->save_in_field(field->field))
  1784.       DBUG_RETURN(1);
  1785.   }
  1786.   DBUG_RETURN(0);
  1787. }
  1788. int
  1789. fill_record(Field **ptr,List<Item> &values)
  1790. {
  1791.   List_iterator<Item> v(values);
  1792.   Item *value;
  1793.   DBUG_ENTER("fill_record");
  1794.   Field *field;
  1795.   while ((field = *ptr++))
  1796.   {
  1797.     value=v++;
  1798.     if (value->save_in_field(field))
  1799.       DBUG_RETURN(1);
  1800.   }
  1801.   DBUG_RETURN(0);
  1802. }
  1803. static void mysql_rm_tmp_tables(void)
  1804. {
  1805.   uint idx;
  1806.   char filePath[FN_REFLEN];
  1807.   MY_DIR *dirp;
  1808.   FILEINFO *file;
  1809.   DBUG_ENTER("mysql_rm_tmp_tables");
  1810.   /* See if the directory exists */
  1811.   if (!(dirp = my_dir(mysql_tmpdir,MYF(MY_WME | MY_DONT_SORT))))
  1812.     DBUG_VOID_RETURN; /* purecov: inspected */
  1813.   /*
  1814.   ** Remove all SQLxxx tables from directory
  1815.   */
  1816.   for (idx=2 ; idx < (uint) dirp->number_off_files ; idx++)
  1817.   {
  1818.     file=dirp->dir_entry+idx;
  1819.     if (!bcmp(file->name,tmp_file_prefix,tmp_file_prefix_length))
  1820.     {
  1821.       sprintf(filePath,"%s%s",mysql_tmpdir,file->name); /* purecov: inspected */
  1822.       VOID(my_delete(filePath,MYF(MY_WME))); /* purecov: inspected */
  1823.     }
  1824.   }
  1825.   my_dirend(dirp);
  1826.   DBUG_VOID_RETURN;
  1827. }
  1828. /*
  1829. ** CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with
  1830. ** the proper arguments.  This isn't very fast but it should work for most
  1831. ** cases.
  1832. ** One should normally create all indexes with CREATE TABLE or ALTER TABLE.
  1833. */
  1834. int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
  1835. {
  1836.   List<create_field> fields;
  1837.   List<Alter_drop> drop;
  1838.   List<Alter_column> alter;
  1839.   HA_CREATE_INFO create_info;
  1840.   DBUG_ENTER("mysql_create_index");
  1841.   bzero((char*) &create_info,sizeof(create_info));
  1842.   create_info.db_type=DB_TYPE_DEFAULT;
  1843.   DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
  1844. &create_info, table_list,
  1845. fields, keys, drop, alter, (ORDER*)0, FALSE, DUP_ERROR));
  1846. }
  1847. int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
  1848. {
  1849.   List<create_field> fields;
  1850.   List<Key> keys;
  1851.   List<Alter_column> alter;
  1852.   HA_CREATE_INFO create_info;
  1853.   DBUG_ENTER("mysql_drop_index");
  1854.   bzero((char*) &create_info,sizeof(create_info));
  1855.   create_info.db_type=DB_TYPE_DEFAULT;
  1856.   DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
  1857. &create_info, table_list,
  1858. fields, keys, drop, alter, (ORDER*)0, FALSE, DUP_ERROR));
  1859. }
  1860. /*****************************************************************************
  1861. unireg support functions
  1862. *****************************************************************************/
  1863. /*
  1864. ** Invalidate any cache entries that are for some DB
  1865. ** We can't use hash_delete when looping hash_elements. We mark them first
  1866. ** and afterwards delete those marked unused.
  1867. */
  1868. void remove_db_from_cache(const my_string db)
  1869. {
  1870.   for (uint idx=0 ; idx < open_cache.records ; idx++)
  1871.   {
  1872.     TABLE *table=(TABLE*) hash_element(&open_cache,idx);
  1873.     if (!strcmp(table->table_cache_key,db))
  1874.     {
  1875.       table->version=0L; /* Free when thread is ready */
  1876.       if (!table->in_use)
  1877. relink_unused(table);
  1878.     }
  1879.   }
  1880.   while (unused_tables && !unused_tables->version)
  1881.     VOID(hash_delete(&open_cache,(byte*) unused_tables));
  1882. }
  1883. /*
  1884. ** free all unused tables
  1885. */
  1886. void flush_tables()
  1887. {
  1888.   (void) pthread_mutex_lock(&LOCK_open);
  1889.   while (unused_tables)
  1890.     hash_delete(&open_cache,(byte*) unused_tables);
  1891.   (void) pthread_mutex_unlock(&LOCK_open);
  1892. }
  1893. /*
  1894. ** Mark all entries with the table as deleted to force an reopen of the table
  1895. ** Returns true if the table is in use by another thread
  1896. */
  1897. bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
  1898.      bool return_if_owned_by_thd)
  1899. {
  1900.   char key[MAX_DBKEY_LENGTH];
  1901.   uint key_length;
  1902.   TABLE *table;
  1903.   bool result=0;
  1904.   DBUG_ENTER("remove_table_from_cache");
  1905.   key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
  1906.   for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ;
  1907.        table;
  1908.        table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length))
  1909.   {
  1910.     THD *in_use;
  1911.     table->version=0L; /* Free when thread is ready */
  1912.     if (!(in_use=table->in_use))
  1913.       relink_unused(table);
  1914.     else if (in_use != thd)
  1915.     {
  1916.       in_use->some_tables_deleted=1;
  1917.       if (table->db_stat)
  1918. result=1;
  1919.       /* Kill delayed insert threads */
  1920.       if (in_use->system_thread && ! in_use->killed)
  1921.       {
  1922. in_use->killed=1;
  1923. pthread_mutex_lock(&in_use->mysys_var->mutex);
  1924. if (in_use->mysys_var->current_mutex)
  1925. {
  1926.   pthread_mutex_lock(in_use->mysys_var->current_mutex);
  1927.   pthread_cond_broadcast(in_use->mysys_var->current_cond);
  1928.   pthread_mutex_unlock(in_use->mysys_var->current_mutex);
  1929. }
  1930. pthread_mutex_unlock(&in_use->mysys_var->mutex);
  1931.       }
  1932.     }
  1933.     else
  1934.       result= result || return_if_owned_by_thd;
  1935.   }
  1936.   while (unused_tables && !unused_tables->version)
  1937.     VOID(hash_delete(&open_cache,(byte*) unused_tables));
  1938.   DBUG_RETURN(result);
  1939. }
  1940. int setup_ftfuncs(THD *thd,TABLE_LIST *tables, List<Item_func_match> &ftfuncs)
  1941. {
  1942.   List_iterator<Item_func_match> li(ftfuncs), li2(ftfuncs);
  1943.   Item_func_match *ftf, *ftf2;
  1944.   while ((ftf=li++))
  1945.   {
  1946.     if (ftf->fix_index())
  1947.       return 1;
  1948.     li2.rewind();
  1949.     while ((ftf2=li2++) != ftf)
  1950.     {
  1951.       if (ftf->eq(ftf2) && !ftf2->master)
  1952.         ftf2->master=ftf;
  1953.     }
  1954.   }
  1955.   return 0;
  1956. }