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

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. #include "mysql_priv.h"
  14. #include "sql_acl.h"
  15. #include "sql_repl.h"
  16. #include <m_ctype.h>
  17. #include <thr_alarm.h>
  18. #include <myisam.h>
  19. #include <my_dir.h>
  20. #include <assert.h>
  21. #define SCRAMBLE_LENGTH 8
  22. extern int yyparse(void);
  23. extern "C" pthread_mutex_t THR_LOCK_keycache;
  24. #ifdef SOLARIS
  25. extern "C" int gethostname(char *name, int namelen);
  26. #endif
  27. static int check_for_max_user_connections(const char *user, int u_length,
  28.   const char *host);
  29. static void decrease_user_connections(const char *user, const char *host);
  30. static bool check_table_access(THD *thd,uint want_access, TABLE_LIST *tables);
  31. static bool check_db_used(THD *thd,TABLE_LIST *tables);
  32. static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables);
  33. static bool check_dup(THD *thd,const char *db,const char *name,
  34.       TABLE_LIST *tables);
  35. static void mysql_init_query(THD *thd);
  36. static void remove_escape(char *name);
  37. static void refresh_status(void);
  38. const char *any_db="*any*"; // Special symbol for check_access
  39. const char *command_name[]={
  40.   "Sleep", "Quit", "Init DB", "Query", "Field List", "Create DB",
  41.   "Drop DB", "Refresh", "Shutdown", "Statistics", "Processlist",
  42.   "Connect","Kill","Debug","Ping","Time","Delayed_insert","Change user",
  43.   "Binlog Dump","Table Dump",  "Connect Out"
  44. };
  45. bool volatile abort_slave = 0;
  46. #ifdef HAVE_OPENSSL
  47. extern VioSSLAcceptorFd* ssl_acceptor_fd;
  48. #endif /* HAVE_OPENSSL */
  49. #ifdef __WIN__
  50. static void  test_signal(int sig_ptr)
  51. {
  52. #ifndef DBUG_OFF
  53.   MessageBox(NULL,"Test signal","DBUG",MB_OK);
  54. #endif
  55. }
  56. static void init_signals(void)
  57. {
  58.   int signals[7] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGBREAK,SIGABRT } ;
  59.   for(int i=0 ; i < 7 ; i++)
  60.     signal( signals[i], test_signal) ;
  61. }
  62. #endif
  63. inline bool end_active_trans(THD *thd)
  64. {
  65.   int error=0;
  66.   if (thd->options & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))
  67.   {
  68.     thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
  69.     thd->server_status&= ~SERVER_STATUS_IN_TRANS;
  70.     if (ha_commit(thd))
  71.       error=1;
  72.   }
  73.   return error;
  74. }
  75. /*
  76. ** Check if user is ok
  77. ** Updates:
  78. ** thd->user, thd->master_access, thd->priv_user, thd->db, thd->db_access
  79. */
  80. static bool check_user(THD *thd,enum_server_command command, const char *user,
  81.        const char *passwd, const char *db, bool check_count)
  82. {
  83.   NET *net= &thd->net;
  84.   thd->db=0;
  85.   if (!(thd->user = my_strdup(user, MYF(0))))
  86.   {
  87.     send_error(net,ER_OUT_OF_RESOURCES);
  88.     return 1;
  89.   }
  90.   thd->master_access=acl_getroot(thd->host, thd->ip, thd->user,
  91.  passwd, thd->scramble, &thd->priv_user,
  92.  protocol_version == 9 ||
  93.  !(thd->client_capabilities &
  94.    CLIENT_LONG_PASSWORD));
  95.   DBUG_PRINT("general",
  96.      ("Capabilities: %d  packet_length: %d  Host: '%s'  User: '%s'  Using password: %s  Access: %u  db: '%s'",
  97.       thd->client_capabilities, thd->max_packet_length,
  98.       thd->host ? thd->host : thd->ip, thd->priv_user,
  99.       passwd[0] ? "yes": "no",
  100.       thd->master_access, thd->db ? thd->db : "*none*"));
  101.   if (thd->master_access & NO_ACCESS)
  102.   {
  103.     net_printf(net, ER_ACCESS_DENIED_ERROR,
  104.        thd->user,
  105.        thd->host ? thd->host : thd->ip,
  106.        passwd[0] ? ER(ER_YES) : ER(ER_NO));
  107.     mysql_log.write(thd,COM_CONNECT,ER(ER_ACCESS_DENIED_ERROR),
  108.     thd->user,
  109.     thd->host ? thd->host : thd->ip ? thd->ip : "unknown ip",
  110.     passwd[0] ? ER(ER_YES) : ER(ER_NO));
  111.     return(1); // Error already given
  112.   }
  113.   if (check_count)
  114.   {
  115.     VOID(pthread_mutex_lock(&LOCK_thread_count));
  116.     bool tmp=(thread_count - delayed_insert_threads >= max_connections &&
  117.       !(thd->master_access & PROCESS_ACL));
  118.     VOID(pthread_mutex_unlock(&LOCK_thread_count));
  119.     if (tmp)
  120.     { // Too many connections
  121.       send_error(net, ER_CON_COUNT_ERROR);
  122.       return(1);
  123.     }
  124.   }
  125.   mysql_log.write(thd,command,
  126.   (thd->priv_user == thd->user ?
  127.    (char*) "%s@%s on %s" :
  128.    (char*) "%s@%s as anonymous on %s"),
  129.   user,
  130.   thd->host ? thd->host : thd->ip ? thd->ip : "unknown ip",
  131.   db ? db : (char*) "");
  132.   thd->db_access=0;
  133.   if (max_user_connections &&
  134.       check_for_max_user_connections(user, strlen(user), thd->host))
  135.     return -1;
  136.   if (db && db[0])
  137.   {
  138.     bool error=test(mysql_change_db(thd,db));
  139.     if (error)
  140.       decrease_user_connections(thd->user,thd->host);
  141.     return error;
  142.   }
  143.   else
  144.     send_ok(net); // Ready to handle questions
  145.   return 0; // ok
  146. }
  147. /*
  148. ** check for maximum allowable user connections
  149. ** if mysql server is started with corresponding
  150. ** variable that is greater then 0
  151. */
  152. static HASH hash_user_connections;
  153. static DYNAMIC_ARRAY  user_conn_array;
  154. extern  pthread_mutex_t LOCK_user_conn;
  155. struct  user_conn {
  156.   char *user;
  157.   uint len, connections;
  158. };
  159. static byte* get_key_conn(user_conn *buff, uint *length,
  160.   my_bool not_used __attribute__((unused)))
  161. {
  162.   *length=buff->len;
  163.   return (byte*) buff->user;
  164. }
  165. #define DEF_USER_COUNT 50
  166. static void free_user(struct user_conn *uc)
  167. {
  168.   my_free((char*) uc,MYF(0));
  169. }
  170. void init_max_user_conn(void) 
  171. {
  172.   (void) hash_init(&hash_user_connections,DEF_USER_COUNT,0,0,
  173.    (hash_get_key) get_key_conn, (void (*)(void*)) free_user,
  174.    0);
  175. }
  176. static int check_for_max_user_connections(const char *user, int u_length,
  177.   const char *host) 
  178. {
  179.   int error=1;
  180.   uint temp_len;
  181.   char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
  182.   struct  user_conn *uc;
  183.   if (!user)
  184.     user="";
  185.   if (!host)
  186.     host="";
  187.   DBUG_ENTER("check_for_max_user_connections");
  188.   DBUG_PRINT("enter",("user: '%s'  host: '%s'", user, host));
  189.   temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user), user, "@", host,
  190.      NullS) - temp_user);
  191.   (void) pthread_mutex_lock(&LOCK_user_conn);
  192.   uc = (struct  user_conn *) hash_search(&hash_user_connections,
  193.  (byte*) temp_user, temp_len);
  194.   if (uc) /* user found ; check for no. of connections */
  195.   {
  196.     if (max_user_connections ==  (uint) uc->connections) 
  197.     {
  198.       net_printf(&(current_thd->net),ER_TOO_MANY_USER_CONNECTIONS, temp_user);
  199.       goto end;
  200.     }
  201.     uc->connections++; 
  202.   }
  203.   else
  204.   {
  205.     /* the user is not found in the cache; Insert it */
  206.     struct user_conn *uc= ((struct user_conn*)
  207.    my_malloc(sizeof(struct user_conn) + temp_len+1,
  208.      MYF(MY_WME)));
  209.     if (!uc)
  210.     {
  211.       send_error(&current_thd->net, 0, NullS); // Out of memory
  212.       goto end;
  213.     }      
  214.     uc->user=(char*) (uc+1);
  215.     memcpy(uc->user,temp_user,temp_len+1);
  216.     uc->len = temp_len;
  217.     uc->connections = 1;
  218.     if (hash_insert(&hash_user_connections, (byte*) uc))
  219.     {
  220.       my_free((char*) uc,0);
  221.       send_error(&current_thd->net, 0, NullS); // Out of memory
  222.       goto end;
  223.     }
  224.   }
  225.   error=0;
  226. end:
  227.   (void) pthread_mutex_unlock(&LOCK_user_conn);
  228.   DBUG_RETURN(error);
  229. }
  230. static void decrease_user_connections(const char *user, const char *host)
  231. {
  232.   char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2];
  233.   int temp_len;
  234.   struct user_conn *uc;
  235.   if (!max_user_connections)
  236.     return;
  237.   if (!user)
  238.     user="";
  239.   if (!host)
  240.     host="";
  241.   DBUG_ENTER("decrease_user_connections");
  242.   DBUG_PRINT("enter",("user: '%s'  host: '%s'", user, host));
  243.   temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user), user, "@", host,
  244.      NullS) - temp_user);
  245.   (void) pthread_mutex_lock(&LOCK_user_conn);
  246.   uc = (struct  user_conn *) hash_search(&hash_user_connections,
  247.  (byte*) temp_user, temp_len);
  248.   dbug_assert(uc != 0); // We should always find the user
  249.   if (!uc)
  250.     goto end; // Safety; Something went wrong
  251.   if (! --uc->connections)
  252.   {
  253.     /* Last connection for user; Delete it */
  254.     (void) hash_delete(&hash_user_connections,(byte*) uc);
  255.   }
  256. end:
  257.   (void) pthread_mutex_unlock(&LOCK_user_conn);
  258.   DBUG_VOID_RETURN;
  259. }
  260. void free_max_user_conn(void)
  261. {
  262.   hash_free(&hash_user_connections);
  263. }
  264. /*
  265. ** check connnetion and get priviliges
  266. ** returns 0 on ok, -1 < if error is given > 0 on error.
  267. */
  268. static int
  269. check_connections(THD *thd)
  270. {
  271.   uint connect_errors=0;
  272.   NET *net= &thd->net;
  273.   /*
  274.   ** store the connection details
  275.   */
  276.   DBUG_PRINT("info", (("check_connections called by thread %d"),
  277.      thd->thread_id));
  278.   DBUG_PRINT("general",("New connection received on %s",
  279. vio_description(net->vio)));
  280.   if (!thd->host)                           // If TCP/IP connection
  281.   {
  282.     char ip[30];
  283.     if (vio_peer_addr(net->vio,ip))
  284.       return (ER_BAD_HOST_ERROR);
  285.     if (!(thd->ip = my_strdup(ip,MYF(0))))
  286.       return (ER_OUT_OF_RESOURCES);
  287. #if !defined(HAVE_SYS_UN_H) || defined(HAVE_mit_thread)
  288.     /* Fast local hostname resolve for Win32 */
  289.     if (!strcmp(thd->ip,"127.0.0.1"))
  290.       thd->host=(char*) localhost;
  291.     else
  292. #endif
  293.     if (!(specialflag & SPECIAL_NO_RESOLVE))
  294.     {
  295.       vio_in_addr(net->vio,&thd->remote.sin_addr);
  296.       thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors);
  297.       if (connect_errors > max_connect_errors)
  298. return(ER_HOST_IS_BLOCKED);
  299.     }
  300.     DBUG_PRINT("general",("Host: %s  ip: %s",
  301.   thd->host ? thd->host : "unknown host",
  302.   thd->ip ? thd->ip : "unknown ip"));
  303.     if (acl_check_host(thd->host,thd->ip))
  304.       return(ER_HOST_NOT_PRIVILEGED);
  305.   }
  306.   else /* Hostname given means that the connection was on a socket */
  307.   {
  308.     DBUG_PRINT("general",("Host: %s",thd->host));
  309.     thd->ip=0;
  310.     bzero((char*) &thd->remote,sizeof(struct sockaddr));
  311.   }
  312.   vio_keepalive(net->vio, TRUE);
  313.   /* nasty, but any other way? */
  314.   uint pkt_len = 0;
  315.   {
  316.     /* buff[] needs to big enough to hold the server_version variable */
  317.     char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH+32],*end;
  318.     int client_flags = CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB;
  319.     if (opt_using_transactions)
  320.       client_flags|=CLIENT_TRANSACTIONS;
  321. #ifdef HAVE_COMPRESS
  322.     client_flags |= CLIENT_COMPRESS;
  323. #endif /* HAVE_COMPRESS */
  324.     end=strmov(buff,server_version)+1;
  325.     int4store((uchar*) end,thd->thread_id);
  326.     end+=4;
  327.     memcpy(end,thd->scramble,SCRAMBLE_LENGTH+1);
  328.     end+=SCRAMBLE_LENGTH +1;
  329. #ifdef HAVE_OPENSSL
  330.     if (ssl_acceptor_fd)
  331.       client_flags |= CLIENT_SSL;       /* Wow, SSL is avalaible! */
  332.     /*
  333.      * Without SSL the handshake consists of one packet. This packet
  334.      * has both client capabilites and scrambled password.
  335.      * With SSL the handshake might consist of two packets. If the first
  336.      * packet (client capabilities) has CLIENT_SSL flag set, we have to
  337.      * switch to SSL and read the second packet. The scrambled password
  338.      * is in the second packet and client_capabilites field will be ignored.
  339.      * Maybe it is better to accept flags other than CLIENT_SSL from the
  340.      * second packet?
  341.   */
  342. #define  SSL_HANDSHAKE_SIZE      2
  343. #define  NORMAL_HANDSHAKE_SIZE   6
  344. #define  MIN_HANDSHAKE_SIZE      2
  345. #else
  346. #define  MIN_HANDSHAKE_SIZE      6
  347. #endif /* HAVE_OPENSSL */
  348.     int2store(end,client_flags);
  349.     end[2]=MY_CHARSET_CURRENT;
  350.     int2store(end+3,thd->server_status);
  351.     bzero(end+5,13);
  352.     end+=18;
  353.     if (net_write_command(net,protocol_version, buff,
  354.   (uint) (end-buff)) ||
  355.        (pkt_len=my_net_read(net)) == packet_error ||
  356. pkt_len < MIN_HANDSHAKE_SIZE)
  357.     {
  358.       inc_host_errors(&thd->remote.sin_addr);
  359.       return(ER_HANDSHAKE_ERROR);
  360.     }
  361.   }
  362. #ifdef _CUSTOMCONFIG_
  363. #include "_cust_sql_parse.h"
  364. #endif
  365.   if (connect_errors)
  366.     reset_host_errors(&thd->remote.sin_addr);
  367.   if (thd->packet.alloc(net_buffer_length))
  368.     return(ER_OUT_OF_RESOURCES);
  369.   thd->client_capabilities=uint2korr(net->read_pos);
  370. #ifdef HAVE_OPENSSL
  371.   DBUG_PRINT("info",
  372.      ("pkt_len:%d, client capabilities: %d",
  373.       pkt_len, thd->client_capabilities) );
  374.   if (thd->client_capabilities & CLIENT_SSL)
  375.   {
  376.     DBUG_PRINT("info", ("Agreed to change IO layer to SSL") );
  377.     /* Do the SSL layering. */
  378.     DBUG_PRINT("info", ("IO layer change in progress..."));
  379.     VioSocket* vio_socket = my_reinterpret_cast(VioSocket*)(net->vio);
  380.     VioSSL* vio_ssl =    ssl_acceptor_fd->accept(vio_socket);
  381.     net->vio =               my_reinterpret_cast(NetVio*) (vio_ssl);
  382.     DBUG_PRINT("info", ("Reading user information over SSL layer"));
  383.     if ((pkt_len=my_net_read(net)) == packet_error ||
  384. pkt_len < NORMAL_HANDSHAKE_SIZE)
  385.     {
  386.       DBUG_PRINT("info", ("pkt_len:%d", pkt_len));
  387.       DBUG_PRINT("error", ("Failed to read user information"));
  388.       inc_host_errors(&thd->remote.sin_addr);
  389.       return(ER_HANDSHAKE_ERROR);
  390.     }
  391.   }
  392.   else
  393.   {
  394.     DBUG_PRINT("info", ("Leaving IO layer intact"));
  395.     if (pkt_len < NORMAL_HANDSHAKE_SIZE)
  396.     {
  397.       inc_host_errors(&thd->remote.sin_addr);
  398.       return ER_HANDSHAKE_ERROR;
  399.     }
  400.   }
  401. #endif
  402.   thd->max_packet_length=uint3korr(net->read_pos+2);
  403.   char *user=   (char*) net->read_pos+5;
  404.   char *passwd= strend(user)+1;
  405.   char *db=0;
  406.   if (passwd[0] && strlen(passwd) != SCRAMBLE_LENGTH)
  407.     return ER_HANDSHAKE_ERROR;
  408.   if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
  409.     db=strend(passwd)+1;
  410.   if (thd->client_capabilities & CLIENT_INTERACTIVE)
  411.     thd->inactive_timeout=net_interactive_timeout;
  412.   if (thd->client_capabilities & CLIENT_TRANSACTIONS)
  413.     thd->net.return_status= &thd->server_status;
  414.   net->timeout=net_read_timeout;
  415.   if (check_user(thd,COM_CONNECT, user, passwd, db, 1))
  416.     return (-1);
  417.   thd->password=test(passwd[0]);
  418.   return 0;
  419. }
  420. pthread_handler_decl(handle_one_connection,arg)
  421. {
  422.   THD *thd=(THD*) arg;
  423.   uint launch_time  =
  424.     (uint) ((thd->thr_create_time = time(NULL)) - thd->connect_time);
  425.   if (launch_time >= slow_launch_time)
  426.     statistic_increment(slow_launch_threads,&LOCK_status );
  427.   pthread_detach_this_thread();
  428. #ifndef __WIN__ /* Win32 calls this in pthread_create */
  429.   if (my_thread_init()) // needed to be called first before we call
  430.     // DBUG_ macros
  431.   {
  432.     close_connection(&thd->net,ER_OUT_OF_RESOURCES);
  433.     statistic_increment(aborted_connects,&LOCK_thread_count);
  434.     end_thread(thd,0);
  435.     return 0;
  436.   }
  437. #endif
  438.   // handle_one_connection() is the only way a thread would start
  439.   // and would always be on top of the stack
  440.   // therefore, the thread stack always starts at the address of the first
  441.   // local variable of handle_one_connection, which is thd
  442.   // we need to know the start of the stack so that we could check for
  443.   // stack overruns
  444.   DBUG_PRINT("info", ("handle_one_connection called by thread %dn",
  445.       thd->thread_id));
  446.   // now that we've called my_thread_init(), it is safe to call DBUG_*
  447. #ifdef __WIN__
  448.   init_signals(); // IRENA; testing ?
  449. #else
  450.   sigset_t set;
  451.   VOID(sigemptyset(&set)); // Get mask in use
  452.   VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
  453. #endif
  454.   if (thd->store_globals())
  455.   {
  456.     close_connection(&thd->net,ER_OUT_OF_RESOURCES);
  457.     statistic_increment(aborted_connects,&LOCK_thread_count);
  458.     end_thread(thd,0);
  459.     return 0;
  460.   }
  461.   do
  462.   {
  463.     int error;
  464.     NET *net= &thd->net;
  465.     thd->mysys_var=my_thread_var;
  466.     thd->dbug_thread_id=my_thread_id();
  467.     thd->thread_stack= (char*) &thd;
  468.     if ((error=check_connections(thd)))
  469.     { // Wrong permissions
  470.       if (error > 0)
  471. net_printf(net,error,thd->host ? thd->host : thd->ip);
  472. #ifdef __NT__
  473.       if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)
  474. sleep(1); /* must wait after eof() */
  475. #endif
  476.       statistic_increment(aborted_connects,&LOCK_thread_count);
  477.       goto end_thread;
  478.     }
  479.     if (thd->max_join_size == HA_POS_ERROR)
  480.       thd->options |= OPTION_BIG_SELECTS;
  481.     if (thd->client_capabilities & CLIENT_COMPRESS)
  482.       net->compress=1; // Use compression
  483.     if (thd->options & OPTION_ANSI_MODE)
  484.       thd->client_capabilities|=CLIENT_IGNORE_SPACE;
  485.     thd->proc_info=0; // Remove 'login'
  486.     thd->command=COM_SLEEP;
  487.     thd->version=refresh_version;
  488.     thd->set_time();
  489.     init_sql_alloc(&thd->mem_root,8192,8192);
  490.     while (!net->error && net->vio != 0 && !thd->killed)
  491.     {
  492.       if (do_command(thd))
  493. break;
  494.     }
  495.     free_root(&thd->mem_root,MYF(0));
  496.     if (net->error && net->vio != 0)
  497.     {
  498.       sql_print_error(ER(ER_NEW_ABORTING_CONNECTION),
  499.       thd->thread_id,(thd->db ? thd->db : "unconnected"),
  500.       thd->user ? thd->user : "unauthenticated",
  501.       (thd->host ? thd->host : thd->ip ? thd->ip : "unknown"),
  502.       (net->last_errno ? ER(net->last_errno) :
  503.        ER(ER_UNKNOWN_ERROR)));
  504.       send_error(net,net->last_errno,NullS);
  505.       thread_safe_increment(aborted_threads,&LOCK_thread_count);
  506.     }
  507.     decrease_user_connections(thd->user,thd->host);
  508. end_thread:
  509.     close_connection(net);
  510.     end_thread(thd,1);
  511.     /*
  512.       If end_thread returns, we are either running with --one-thread
  513.       or this thread has been schedule to handle the next query
  514.     */
  515.     thd= current_thd;
  516.   } while (!(test_flags & TEST_NO_THREADS));
  517.   /* The following is only executed if we are not using --one-thread */
  518.   return(0); /* purecov: deadcode */
  519. }
  520. /*
  521.   Execute commands from bootstrap_file.
  522.   Used when creating the initial grant tables
  523. */
  524. pthread_handler_decl(handle_bootstrap,arg)
  525. {
  526.   THD *thd=(THD*) arg;
  527.   FILE *file=bootstrap_file;
  528.   char *buff;
  529.   /* The following must be called before DBUG_ENTER */
  530.   if (my_thread_init() || thd->store_globals())
  531.   {
  532.     close_connection(&thd->net,ER_OUT_OF_RESOURCES);
  533.     thd->fatal_error=1;
  534.     goto end;
  535.   }
  536.   DBUG_ENTER("handle_bootstrap");
  537.   pthread_detach_this_thread();
  538.   thd->thread_stack= (char*) &thd;
  539.   thd->mysys_var=my_thread_var;
  540.   thd->dbug_thread_id=my_thread_id();
  541. #ifndef __WIN__
  542.   sigset_t set;
  543.   VOID(sigemptyset(&set)); // Get mask in use
  544.   VOID(pthread_sigmask(SIG_UNBLOCK,&set,&thd->block_signals));
  545. #endif
  546.   if (thd->max_join_size == (ulong) ~0L)
  547.     thd->options |= OPTION_BIG_SELECTS;
  548.   thd->proc_info=0;
  549.   thd->version=refresh_version;
  550.   thd->priv_user=thd->user=(char*)"boot";
  551.   buff= (char*) thd->net.buff;
  552.   init_sql_alloc(&thd->mem_root,8192,8192);
  553.   while (fgets(buff, thd->net.max_packet, file))
  554.   {
  555.     uint length=(uint) strlen(buff);
  556.     while (length && (isspace(buff[length-1]) || buff[length-1] == ';'))
  557.       length--;
  558.     buff[length]=0;
  559.     thd->current_tablenr=0;
  560.     thd->query= thd->memdup(buff,length+1);
  561.     thd->query_id=query_id++;
  562.     mysql_parse(thd,thd->query,length);
  563.     close_thread_tables(thd); // Free tables
  564.     if (thd->fatal_error)
  565.       break;
  566.     free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
  567.   }
  568.   thd->priv_user=thd->user=0;
  569.   /* thd->fatal_error should be set in case something went wrong */
  570. end:
  571.   (void) pthread_mutex_lock(&LOCK_thread_count);
  572.   thread_count--;
  573.   (void) pthread_cond_broadcast(&COND_thread_count);
  574.   (void) pthread_mutex_unlock(&LOCK_thread_count);
  575.   my_thread_end();
  576.   pthread_exit(0);
  577.   DBUG_RETURN(0); // Never reached
  578. }
  579. inline void free_items(THD *thd)
  580. {
  581.     /* This works because items are allocated with sql_alloc() */
  582.   for (Item *item=thd->free_list ; item ; item=item->next)
  583.     delete item;
  584. }
  585. int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd)
  586. {
  587.   TABLE* table;
  588.   TABLE_LIST* table_list;
  589.   int error = 0;
  590.   DBUG_ENTER("mysql_table_dump");
  591.   db = (db && db[0]) ? db : thd->db;
  592.   if (!(table_list = (TABLE_LIST*) sql_calloc(sizeof(TABLE_LIST))))
  593.     DBUG_RETURN(1); // out of memory
  594.   table_list->db = db;
  595.   table_list->real_name = table_list->name = tbl_name;
  596.   table_list->lock_type = TL_READ_NO_INSERT;
  597.   table_list->next = 0;
  598.   remove_escape(table_list->real_name);
  599.   if (!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT)))
  600.     DBUG_RETURN(1);
  601.   if (!db || check_db_name(db))
  602.   {
  603.     net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL");
  604.     goto err;
  605.   }
  606.   if (check_access(thd, SELECT_ACL, db, &table_list->grant.privilege))
  607.     goto err;
  608.   if (grant_option && check_grant(thd, SELECT_ACL, table_list))
  609.     goto err;
  610.   thd->free_list = 0;
  611.   thd->query = tbl_name;
  612.   if((error = mysqld_dump_create_info(thd, table, -1)))
  613.     {
  614.       my_error(ER_GET_ERRNO, MYF(0));
  615.       goto err;
  616.     }
  617.   net_flush(&thd->net);
  618.   error = table->file->dump(thd,fd);
  619.   if(error)
  620.       my_error(ER_GET_ERRNO, MYF(0));
  621. err:
  622.   close_thread_tables(thd);
  623.   DBUG_RETURN(error);
  624. }
  625. /* Execute one command from socket (query or simple command) */
  626. bool do_command(THD *thd)
  627. {
  628.   char *packet;
  629.   uint old_timeout,packet_length;
  630.   bool error=0;
  631.   NET *net;
  632.   enum enum_server_command command;
  633.   // commands which will always take a long time should be marked with
  634.   // this so that they will not get logged to the slow query log
  635.   bool slow_command=FALSE;
  636.   DBUG_ENTER("do_command");
  637.   net= &thd->net;
  638.   thd->current_tablenr=0;
  639.   packet=0;
  640.   old_timeout=net->timeout;
  641.   net->timeout=thd->inactive_timeout; /* Wait max for 8 hours */
  642.   net->last_error[0]=0; // Clear error message
  643.   net->last_errno=0;
  644.   net_new_transaction(net);
  645.   if ((packet_length=my_net_read(net)) == packet_error)
  646.   {
  647.      DBUG_PRINT("general",("Got error reading command from socket %s",
  648. vio_description(net->vio) ));
  649.     return TRUE;
  650.   }
  651.   else
  652.   {
  653.     packet=(char*) net->read_pos;
  654.     command = (enum enum_server_command) (uchar) packet[0];
  655.     DBUG_PRINT("general",("Command on %s = %d (%s)",
  656.   vio_description(net->vio), command,
  657.   command_name[command]));
  658.   }
  659.   net->timeout=old_timeout; /* Timeout */
  660.   thd->command=command;
  661.   VOID(pthread_mutex_lock(&LOCK_thread_count));
  662.   thd->query_id=query_id;
  663.   if (command != COM_STATISTICS && command != COM_PING)
  664.     query_id++;
  665.   thread_running++;
  666.   VOID(pthread_mutex_unlock(&LOCK_thread_count));
  667.   thd->set_time();
  668.   thd->lex.options=0; // We store status here
  669.   switch(command) {
  670.   case COM_INIT_DB:
  671.     if (!mysql_change_db(thd,packet+1))
  672.       mysql_log.write(thd,command,"%s",thd->db);
  673.     break;
  674.   case COM_TABLE_DUMP:
  675.     {
  676.       slow_command = TRUE;
  677.       char* data = packet + 1;
  678.       uint db_len = *data;
  679.       uint tbl_len = *(data + db_len + 1);
  680.       char* db = sql_alloc(db_len + tbl_len + 2);
  681.       memcpy(db, data + 1, db_len);
  682.       char* tbl_name = db + db_len;
  683.       *tbl_name++ = 0;
  684.       memcpy(tbl_name, data + db_len + 2, tbl_len);
  685.       tbl_name[tbl_len] = 0;
  686.       if(mysql_table_dump(thd, db, tbl_name, -1))
  687. send_error(&thd->net); // dump to NET
  688.       break;
  689.     }
  690.   case COM_CHANGE_USER:
  691.   {
  692.     char *user=   (char*) packet+1;
  693.     char *passwd= strend(user)+1;
  694.     char *db=     strend(passwd)+1;
  695.     /* Save user and privileges */
  696.     uint save_master_access=thd->master_access;
  697.     uint save_db_access=    thd->db_access;
  698.     char *save_user=     thd->user;
  699.     char *save_priv_user=   thd->priv_user;
  700.     char *save_db=     thd->db;
  701.     if ((uint) ((uchar*) db - net->read_pos) > packet_length)
  702.     { // Check if protocol is ok
  703.       send_error(net, ER_UNKNOWN_COM_ERROR);
  704.       break;
  705.     }
  706.     if (check_user(thd, COM_CHANGE_USER, user, passwd, db, 0))
  707.     { // Restore old user
  708.       x_free(thd->user);
  709.       x_free(thd->db);
  710.       thd->master_access=save_master_access;
  711.       thd->db_access=save_db_access;
  712.       thd->db=save_db;
  713.       thd->user=save_user;
  714.       thd->priv_user=save_priv_user;
  715.       break;
  716.     }
  717.     decrease_user_connections (save_user, thd->host);
  718.     x_free((gptr) save_db);
  719.     x_free((gptr) save_user);
  720.     thd->password=test(passwd[0]);
  721.     break;
  722.   }
  723.   case COM_QUERY:
  724.   {
  725.     char *pos=packet+packet_length; // Point at end null
  726.     /* Remove garage at end of query */
  727.     while (packet_length > 0 && pos[-1] == ';')
  728.     {
  729.       pos--;
  730.       packet_length--;
  731.     }
  732.     *pos=0;
  733.     if (!(thd->query= (char*) thd->memdup((gptr) (packet+1),packet_length)))
  734.       break;
  735.     thd->packet.shrink(net_buffer_length); // Reclaim some memory
  736.     if (!(specialflag & SPECIAL_NO_PRIOR))
  737.       my_pthread_setprio(pthread_self(),QUERY_PRIOR);
  738.     mysql_log.write(thd,command,"%s",thd->query);
  739.     DBUG_PRINT("query",("%s",thd->query));
  740.     mysql_parse(thd,thd->query,packet_length-1);
  741.     if (!(specialflag & SPECIAL_NO_PRIOR))
  742.       my_pthread_setprio(pthread_self(),WAIT_PRIOR);
  743.     DBUG_PRINT("info",("query ready"));
  744.     break;
  745.   }
  746.   case COM_FIELD_LIST: // This isn't actually neaded
  747. #ifdef DONT_ALLOW_SHOW_COMMANDS
  748.     send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
  749.     break;
  750. #else
  751.   {
  752.     char *fields;
  753.     TABLE_LIST table_list;
  754.     bzero((char*) &table_list,sizeof(table_list));
  755.     if (!(table_list.db=thd->db))
  756.     {
  757.       send_error(net,ER_NO_DB_ERROR);
  758.       break;
  759.     }
  760.     thd->free_list=0;
  761.     table_list.name=table_list.real_name=thd->strdup(packet+1);
  762.     thd->query=fields=thd->strdup(strend(packet+1)+1);
  763.     mysql_log.write(thd,command,"%s %s",table_list.real_name,fields);
  764.     remove_escape(table_list.real_name); // This can't have wildcards
  765.     if (check_access(thd,SELECT_ACL,table_list.db,&thd->col_access))
  766.       break;
  767.     table_list.grant.privilege=thd->col_access;
  768.     if (grant_option && check_grant(thd,SELECT_ACL,&table_list,2))
  769.       break;
  770.     mysqld_list_fields(thd,&table_list,fields);
  771.     free_items(thd);
  772.     break;
  773.   }
  774. #endif
  775.   case COM_QUIT:
  776.     mysql_log.write(thd,command,NullS);
  777.     net->error=0; // Don't give 'abort' message
  778.     error=TRUE; // End server
  779.     break;
  780.   case COM_CREATE_DB:
  781.     {
  782.       char *db=thd->strdup(packet+1);
  783.       // null test to handle EOM
  784.       if (!db || !stripp_sp(db) || check_db_name(db))
  785.       {
  786. net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL");
  787. break;
  788.       }
  789.       if (check_access(thd,CREATE_ACL,db,0,1))
  790. break;
  791.       mysql_log.write(thd,command,packet+1);
  792.       mysql_create_db(thd,db,0);
  793.       break;
  794.     }
  795.   case COM_DROP_DB:
  796.     {
  797.       char *db=thd->strdup(packet+1);
  798.       // null test to handle EOM
  799.       if (!db || !stripp_sp(db) || check_db_name(db))
  800.       {
  801. net_printf(&thd->net,ER_WRONG_DB_NAME, db ? db : "NULL");
  802. break;
  803.       }
  804.       if (check_access(thd,DROP_ACL,db,0,1) || end_active_trans(thd))
  805. break;
  806.       mysql_log.write(thd,command,db);
  807.       mysql_rm_db(thd,db,0);
  808.       break;
  809.     }
  810.   case COM_BINLOG_DUMP:
  811.     {
  812.       slow_command = TRUE;
  813.       if(check_access(thd, FILE_ACL, any_db))
  814. break;
  815.       mysql_log.write(thd,command, 0);
  816.       ulong pos;
  817.       ushort flags;
  818.       uint32 slave_server_id;
  819.       pos = uint4korr(packet + 1);
  820.       flags = uint2korr(packet + 5);
  821.       pthread_mutex_lock(&LOCK_server_id);
  822.       kill_zombie_dump_threads(slave_server_id = uint4korr(packet+7));
  823.       thd->server_id = slave_server_id;
  824.       pthread_mutex_unlock(&LOCK_server_id);
  825.       mysql_binlog_send(thd, thd->strdup(packet + 11), pos, flags);
  826.       // fake COM_QUIT -- if we get here, the thread needs to terminate
  827.       error = TRUE;
  828.       net->error = 0;
  829.       break;
  830.     }
  831.   case COM_REFRESH:
  832.     {
  833.       uint options=(uchar) packet[1];
  834.       if (check_access(thd,RELOAD_ACL,any_db))
  835. break;
  836.       mysql_log.write(thd,command,NullS);
  837.       if (reload_acl_and_cache(thd, options, (TABLE_LIST*) 0))
  838. send_error(net,0);
  839.       else
  840. send_eof(net);
  841.       break;
  842.     }
  843.   case COM_SHUTDOWN:
  844.     if (check_access(thd,SHUTDOWN_ACL,any_db))
  845.       break; /* purecov: inspected */
  846.     DBUG_PRINT("quit",("Got shutdown command"));
  847.     mysql_log.write(thd,command,NullS);
  848.     send_eof(net);
  849. #ifdef __WIN__
  850.     sleep(1); // must wait after eof()
  851. #endif
  852.     send_eof(net); // This is for 'quit request'
  853.     close_connection(net);
  854.     close_thread_tables(thd); // Free before kill
  855.     free_root(&thd->mem_root,MYF(0));
  856.     kill_mysql();
  857.     error=TRUE;
  858.     break;
  859.   case COM_STATISTICS:
  860.   {
  861.     mysql_log.write(thd,command,NullS);
  862.     char buff[200];
  863.     ulong uptime = (ulong) (thd->start_time - start_time);
  864.     sprintf((char*) buff,
  865.     "Uptime: %ld  Threads: %d  Questions: %lu  Slow queries: %ld  Opens: %ld  Flush tables: %ld  Open tables: %d Queries per second avg: %.3f",
  866.     uptime,
  867.     (int) thread_count,thd->query_id,long_query_count,
  868.     opened_tables,refresh_version, cached_tables(),
  869.     uptime ? (float)thd->query_id/(float)uptime : 0);
  870. #ifdef SAFEMALLOC
  871.     if (lCurMemory) // Using SAFEMALLOC
  872.       sprintf(strend(buff), "  Memory in use: %ldK  Max memory used: %ldK",
  873.       (lCurMemory+1023L)/1024L,(lMaxMemory+1023L)/1024L);
  874.  #endif
  875.     VOID(my_net_write(net, buff,(uint) strlen(buff)));
  876.     VOID(net_flush(net));
  877.     break;
  878.   }
  879.   case COM_PING:
  880.     send_ok(net); // Tell client we are alive
  881.     break;
  882.   case COM_PROCESS_INFO:
  883.     if (!thd->priv_user[0] && check_access(thd,PROCESS_ACL,any_db))
  884.       break;
  885.     mysql_log.write(thd,command,NullS);
  886.     mysqld_list_processes(thd,thd->master_access & PROCESS_ACL ? NullS :
  887.   thd->priv_user,0);
  888.     break;
  889.   case COM_PROCESS_KILL:
  890.   {
  891.     ulong id=(ulong) uint4korr(packet+1);
  892.     kill_one_thread(thd,id);
  893.     break;
  894.   }
  895.   case COM_DEBUG:
  896.     if (check_access(thd,PROCESS_ACL,any_db))
  897.       break; /* purecov: inspected */
  898.     mysql_print_status(thd);
  899.     mysql_log.write(thd,command,NullS);
  900.     send_eof(net);
  901.     break;
  902.   case COM_SLEEP:
  903.   case COM_CONNECT: // Impossible here
  904.   case COM_TIME: // Impossible from client
  905.   case COM_DELAYED_INSERT:
  906.   default:
  907.     send_error(net, ER_UNKNOWN_COM_ERROR);
  908.     break;
  909.   }
  910.   if (thd->lock || thd->open_tables)
  911.   {
  912.     thd->proc_info="closing tables";
  913.     close_thread_tables(thd); /* Free tables */
  914.   }
  915.   if (thd->fatal_error)
  916.     send_error(net,0); // End of memory ?
  917.   time_t start_of_query=thd->start_time;
  918.   thd->end_time(); // Set start time
  919.   /* If not reading from backup and if the query took too long */
  920.   if (!slow_command && !thd->user_time) // do not log 'slow_command' queries
  921.   {
  922.     thd->proc_info="logging slow query";
  923.     if ((ulong) (thd->start_time - thd->time_after_lock) > long_query_time ||
  924. ((thd->lex.options &
  925.   (QUERY_NO_INDEX_USED | QUERY_NO_GOOD_INDEX_USED)) &&
  926.  (specialflag & SPECIAL_LONG_LOG_FORMAT)))
  927.     {
  928.       long_query_count++;
  929.       mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query);
  930.     }
  931.   }
  932.   thd->proc_info="cleaning up";
  933.   VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list
  934.   thd->proc_info=0;
  935.   thd->command=COM_SLEEP;
  936.   thd->query=0;
  937.   thread_running--;
  938.   VOID(pthread_mutex_unlock(&LOCK_thread_count));
  939.   thd->packet.shrink(net_buffer_length); // Reclaim some memory
  940.   free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC));
  941.   DBUG_RETURN(error);
  942. }
  943. /****************************************************************************
  944. ** mysql_execute_command
  945. ** Execute command saved in thd and current_lex->sql_command
  946. ****************************************************************************/
  947. void
  948. mysql_execute_command(void)
  949. {
  950.   int res=0;
  951.   THD *thd=current_thd;
  952.   LEX *lex= &thd->lex;
  953.   TABLE_LIST *tables=(TABLE_LIST*) lex->table_list.first;
  954.   DBUG_ENTER("mysql_execute_command");
  955.   if(table_rules_on && thd->slave_thread && tables && !tables_ok(thd,tables))
  956.     DBUG_VOID_RETURN; // skip if we are in the slave thread, some table
  957.   // rules have been given and the table list says the query should not be
  958.   // replicated
  959.   
  960.   switch (lex->sql_command) {
  961.   case SQLCOM_SELECT:
  962.   {
  963.     select_result *result;
  964.     if (lex->options & SELECT_DESCRIBE)
  965.       lex->exchange=0;
  966.     if (tables)
  967.     {
  968.       res=check_table_access(thd,
  969.      lex->exchange ? SELECT_ACL | FILE_ACL :
  970.      SELECT_ACL,
  971.      tables);
  972.     }
  973.     else
  974.       res=check_access(thd, lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL,
  975.        any_db);
  976.     if (res)
  977.     {
  978.       res=0;
  979.       break; // Error message is given
  980.     }
  981.     thd->offset_limit=lex->offset_limit;
  982.     thd->select_limit=lex->select_limit+lex->offset_limit;
  983.     if (thd->select_limit < lex->select_limit)
  984.       thd->select_limit= HA_POS_ERROR; // no limit
  985.     if (lex->exchange)
  986.     {
  987.       if (lex->exchange->dumpfile)
  988.       {
  989. if (!(result=new select_dump(lex->exchange)))
  990. {
  991.   res= -1;
  992.   break;
  993. }
  994.       }
  995.       else
  996.       {
  997. if (!(result=new select_export(lex->exchange)))
  998. {
  999.   res= -1;
  1000.   break;
  1001. }
  1002.       }
  1003.     }
  1004.     else if (!(result=new select_send()))
  1005.     {
  1006.       res= -1;
  1007. #ifdef DELETE_ITEMS
  1008.       delete lex->having;
  1009.       delete lex->where;
  1010. #endif
  1011.       break;
  1012.     }
  1013.     if (lex->options & SELECT_HIGH_PRIORITY)
  1014.     {
  1015.       TABLE_LIST *table;
  1016.       for (table = tables ; table ; table=table->next)
  1017. table->lock_type=TL_READ_HIGH_PRIORITY;
  1018.     }
  1019.     if (!(res=open_and_lock_tables(thd,tables)))
  1020.     {
  1021.       res=mysql_select(thd,tables,lex->item_list,
  1022.        lex->where,
  1023.                        lex->ftfunc_list,
  1024.        (ORDER*) lex->order_list.first,
  1025.        (ORDER*) lex->group_list.first,
  1026.        lex->having,
  1027.        (ORDER*) lex->proc_list.first,
  1028.        lex->options | thd->options,
  1029.        result);
  1030.       if (res)
  1031. result->abort();
  1032.     }
  1033.     delete result;
  1034. #ifdef DELETE_ITEMS
  1035.     delete lex->having;
  1036.     delete lex->where;
  1037. #endif
  1038.     break;
  1039.   }
  1040.   case SQLCOM_PURGE:
  1041.     {
  1042.       if(check_access(thd, PROCESS_ACL, any_db))
  1043. goto error;
  1044.       res = purge_master_logs(thd, lex->to_log);
  1045.       break;
  1046.     }
  1047.   case SQLCOM_BACKUP_TABLE:
  1048.     {
  1049.       if (check_db_used(thd,tables) ||
  1050.   check_table_access(thd,SELECT_ACL, tables) ||
  1051.   check_access(thd, FILE_ACL, any_db))
  1052. goto error; /* purecov: inspected */
  1053.       res = mysql_backup_table(thd, tables);
  1054.       break;
  1055.     }
  1056.   case SQLCOM_RESTORE_TABLE:
  1057.     {
  1058.       if (check_db_used(thd,tables) ||
  1059.   check_table_access(thd,INSERT_ACL, tables) ||
  1060.   check_access(thd, FILE_ACL, any_db))
  1061. goto error; /* purecov: inspected */
  1062.       res = mysql_restore_table(thd, tables);
  1063.       break;
  1064.     }
  1065.   case SQLCOM_CHANGE_MASTER:
  1066.     {
  1067.       if(check_access(thd, PROCESS_ACL, any_db))
  1068. goto error;
  1069.       res = change_master(thd);
  1070.       break;
  1071.     }
  1072.   case SQLCOM_SHOW_SLAVE_STAT:
  1073.     {
  1074.       if(check_access(thd, PROCESS_ACL, any_db))
  1075. goto error;
  1076.       res = show_master_info(thd);
  1077.       break;
  1078.     }
  1079.   case SQLCOM_SHOW_MASTER_STAT:
  1080.     {
  1081.       if (check_access(thd, PROCESS_ACL, any_db))
  1082. goto error;
  1083.       res = show_binlog_info(thd);
  1084.       break;
  1085.     }
  1086.   case SQLCOM_LOAD_MASTER_TABLE:
  1087.     if (!tables->db)
  1088.       tables->db=thd->db;
  1089.     if (check_access(thd,CREATE_ACL,tables->db,&tables->grant.privilege))
  1090.       goto error; /* purecov: inspected */
  1091.     if (grant_option)
  1092.     {
  1093.       /* Check that the first table has CREATE privilege */
  1094.       TABLE_LIST *tmp_table_list=tables->next;
  1095.       tables->next=0;
  1096.       bool error=check_grant(thd,CREATE_ACL,tables);
  1097.       tables->next=tmp_table_list;
  1098.       if (error)
  1099.   goto error;
  1100.     }
  1101.     if (strlen(tables->name) > NAME_LEN)
  1102.     {
  1103.       net_printf(&thd->net,ER_WRONG_TABLE_NAME,tables->name);
  1104.       res=0;
  1105.       break;
  1106.     }
  1107.     thd->last_nx_table = tables->real_name;
  1108.     thd->last_nx_db = tables->db;
  1109.     if(fetch_nx_table(thd, &glob_mi))
  1110.       // fetch_nx_table is responsible for sending
  1111.       // the error
  1112.       {
  1113. res = 0;
  1114. thd->net.no_send_ok = 0; // easier to do it here
  1115. // this way we make sure that when we are done, we are clean
  1116.         break;
  1117.       }
  1118.     res = 0;
  1119.     send_ok(&thd->net);
  1120.     break;
  1121.   case SQLCOM_CREATE_TABLE:
  1122.     if (!tables->db)
  1123.       tables->db=thd->db;
  1124.     if (check_access(thd,CREATE_ACL,tables->db,&tables->grant.privilege) ||
  1125. check_merge_table_access(thd, tables->db,
  1126.  (TABLE_LIST *)
  1127.  lex->create_info.merge_list.first))
  1128.       goto error; /* purecov: inspected */
  1129.     if (grant_option)
  1130.     {
  1131.       /* Check that the first table has CREATE privilege */
  1132.       TABLE_LIST *tmp_table_list=tables->next;
  1133.       tables->next=0;
  1134.       bool error=check_grant(thd,CREATE_ACL,tables);
  1135.       tables->next=tmp_table_list;
  1136.       if (error)
  1137. goto error;
  1138.     }
  1139.     if (strlen(tables->name) > NAME_LEN)
  1140.     {
  1141.       net_printf(&thd->net,ER_WRONG_TABLE_NAME,tables->name);
  1142.       res=0;
  1143.       break;
  1144.     }
  1145.     if (lex->item_list.elements) // With select
  1146.     {
  1147.       select_result *result;
  1148.       if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
  1149.   check_dup(thd,tables->db,tables->real_name,tables->next))
  1150.       {
  1151. net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name);
  1152. DBUG_VOID_RETURN;
  1153.       }
  1154.       if (tables->next)
  1155.       {
  1156. if (check_table_access(thd, SELECT_ACL, tables->next))
  1157.   goto error; // Error message is given
  1158.       }
  1159.       thd->offset_limit=lex->offset_limit;
  1160.       thd->select_limit=lex->select_limit+lex->offset_limit;
  1161.       if (thd->select_limit < lex->select_limit)
  1162. thd->select_limit= HA_POS_ERROR; // No limit
  1163.       if (!(res=open_and_lock_tables(thd,tables->next)))
  1164.       {
  1165. if ((result=new select_create(tables->db ? tables->db : thd->db,
  1166.       tables->real_name, &lex->create_info,
  1167.       lex->create_list,
  1168.       lex->key_list,
  1169.       lex->item_list,lex->duplicates)))
  1170. {
  1171.   res=mysql_select(thd,tables->next,lex->item_list,
  1172.    lex->where,
  1173.                            lex->ftfunc_list,
  1174.    (ORDER*) lex->order_list.first,
  1175.    (ORDER*) lex->group_list.first,
  1176.    lex->having,
  1177.    (ORDER*) lex->proc_list.first,
  1178.    lex->options | thd->options,
  1179.    result);
  1180.   if (res)
  1181.     result->abort();
  1182.   delete result;
  1183. }
  1184. else
  1185.   res= -1;
  1186.       }
  1187.     }
  1188.     else // regular create
  1189.     {
  1190.       res = mysql_create_table(thd,tables->db ? tables->db : thd->db,
  1191.        tables->real_name, &lex->create_info,
  1192.        lex->create_list,
  1193.        lex->key_list,0, 0); // do logging
  1194.       if (!res)
  1195. send_ok(&thd->net);
  1196.     }
  1197.     break;
  1198.   case SQLCOM_CREATE_INDEX:
  1199.     if (!tables->db)
  1200.       tables->db=thd->db;
  1201.     if (check_access(thd,INDEX_ACL,tables->db,&tables->grant.privilege))
  1202.       goto error; /* purecov: inspected */
  1203.     if (grant_option && check_grant(thd,INDEX_ACL,tables))
  1204.       goto error;
  1205.     if (end_active_trans(thd))
  1206.       res= -1;
  1207.     else
  1208.       res = mysql_create_index(thd, tables, lex->key_list);
  1209.     break;
  1210.   case SQLCOM_SLAVE_START:
  1211.     start_slave(thd);
  1212.     break;
  1213.   case SQLCOM_SLAVE_STOP:
  1214.     stop_slave(thd);
  1215.     break;
  1216.   case SQLCOM_ALTER_TABLE:
  1217. #if defined(DONT_ALLOW_SHOW_COMMANDS)
  1218.     send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
  1219.     break;
  1220. #else
  1221.     {
  1222.       uint priv=0;
  1223.       if (lex->name && strlen(lex->name) > NAME_LEN)
  1224.       {
  1225. net_printf(&thd->net,ER_WRONG_TABLE_NAME,lex->name);
  1226. res=0;
  1227. break;
  1228.       }
  1229.       if (!tables->db)
  1230. tables->db=thd->db;
  1231.       if (!lex->db)
  1232. lex->db=tables->db;
  1233.       if (check_access(thd,ALTER_ACL,tables->db,&tables->grant.privilege) ||
  1234.   check_access(thd,INSERT_ACL | CREATE_ACL,lex->db,&priv) ||
  1235.   check_merge_table_access(thd, tables->db, 
  1236.    (TABLE_LIST *)
  1237.    lex->create_info.merge_list.first))
  1238. goto error; /* purecov: inspected */
  1239.       if (!tables->db)
  1240. tables->db=thd->db;
  1241.       if (grant_option)
  1242.       {
  1243. if (check_grant(thd,ALTER_ACL,tables))
  1244.   goto error;
  1245. if (lex->name && !test_all_bits(priv,INSERT_ACL | CREATE_ACL))
  1246. { // Rename of table
  1247.   TABLE_LIST tmp_table;
  1248.   bzero((char*) &tmp_table,sizeof(tmp_table));
  1249.   tmp_table.real_name=lex->name;
  1250.   tmp_table.db=lex->db;
  1251.   tmp_table.grant.privilege=priv;
  1252.   if (check_grant(thd,INSERT_ACL | CREATE_ACL,tables))
  1253.     goto error;
  1254. }
  1255.       }
  1256.       /* ALTER TABLE ends previous transaction */
  1257.       if (end_active_trans(thd))
  1258. res= -1;
  1259.       else
  1260. res= mysql_alter_table(thd, lex->db, lex->name,
  1261.        &lex->create_info,
  1262.        tables, lex->create_list,
  1263.        lex->key_list, lex->drop_list, lex->alter_list,
  1264.                                (ORDER *) lex->order_list.first,
  1265.        lex->drop_primary, lex->duplicates);
  1266.       break;
  1267.     }
  1268. #endif
  1269.   case SQLCOM_RENAME_TABLE:
  1270.   {
  1271.     TABLE_LIST *table;
  1272.     if (check_db_used(thd,tables))
  1273.       goto error;
  1274.     for (table=tables ; table ; table=table->next->next)
  1275.     {
  1276.       if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
  1277.        &table->grant.privilege) ||
  1278.   check_access(thd, INSERT_ACL | CREATE_ACL, table->next->db,
  1279.        &table->next->grant.privilege))
  1280. goto error;
  1281.       if (grant_option)
  1282.       {
  1283. TABLE_LIST old_list,new_list;
  1284. old_list=table[0];
  1285. new_list=table->next[0];
  1286. old_list.next=new_list.next=0;
  1287. if (check_grant(thd,ALTER_ACL,&old_list) ||
  1288.     (!test_all_bits(table->next->grant.privilege,
  1289.    INSERT_ACL | CREATE_ACL) &&
  1290.      check_grant(thd,INSERT_ACL | CREATE_ACL, &new_list)))
  1291.   goto error;
  1292.       }
  1293.     }
  1294.     if (end_active_trans(thd))
  1295.       res= -1;
  1296.     else if (mysql_rename_tables(thd,tables))
  1297.       res= -1;
  1298.     break;
  1299.   }
  1300.   case SQLCOM_SHOW_BINLOGS:
  1301. #ifdef DONT_ALLOW_SHOW_COMMANDS
  1302.     send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
  1303.     DBUG_VOID_RETURN;
  1304. #else
  1305.     {
  1306.       if(check_access(thd, PROCESS_ACL, any_db))
  1307. goto error;
  1308.       res = show_binlogs(thd);
  1309.       break;
  1310.     }
  1311. #endif    
  1312.   case SQLCOM_SHOW_CREATE:
  1313. #ifdef DONT_ALLOW_SHOW_COMMANDS
  1314.     send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
  1315.     DBUG_VOID_RETURN;
  1316. #else
  1317.     {
  1318.       if (check_db_used(thd, tables) ||
  1319.   check_access(thd, SELECT_ACL | EXTRA_ACL, tables->db,
  1320.        &tables->grant.privilege))
  1321. goto error;
  1322.       res = mysqld_show_create(thd, tables);
  1323.       break;
  1324.     }
  1325. #endif
  1326.   case SQLCOM_REPAIR:
  1327.     {
  1328.       if (check_db_used(thd,tables) ||
  1329.   check_table_access(thd,SELECT_ACL | INSERT_ACL, tables))
  1330. goto error; /* purecov: inspected */
  1331.       res = mysql_repair_table(thd, tables, &lex->check_opt);
  1332.       break;
  1333.     }
  1334.   case SQLCOM_CHECK:
  1335.     {
  1336.       if (check_db_used(thd,tables) ||
  1337.   check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables))
  1338. goto error; /* purecov: inspected */
  1339.       res = mysql_check_table(thd, tables, &lex->check_opt);
  1340.       break;
  1341.     }
  1342.   case SQLCOM_ANALYZE:
  1343.   {
  1344.     if (check_db_used(thd,tables) ||
  1345. check_table_access(thd,SELECT_ACL | INSERT_ACL, tables))
  1346.       goto error; /* purecov: inspected */
  1347.     res = mysql_analyze_table(thd, tables, &lex->check_opt);
  1348.     break;
  1349.   }
  1350.   case SQLCOM_OPTIMIZE:
  1351.   {
  1352.     HA_CREATE_INFO create_info;
  1353.     if (check_db_used(thd,tables) ||
  1354. check_table_access(thd,SELECT_ACL | INSERT_ACL, tables))
  1355.       goto error; /* purecov: inspected */
  1356.     if (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC))
  1357.     {
  1358.       /* Use ALTER TABLE */
  1359.       lex->create_list.empty();
  1360.       lex->key_list.empty();
  1361.       lex->col_list.empty();
  1362.       lex->drop_list.empty();
  1363.       lex->alter_list.empty();
  1364.       bzero((char*) &create_info,sizeof(create_info));
  1365.       create_info.db_type=DB_TYPE_DEFAULT;
  1366.       create_info.row_type=ROW_TYPE_DEFAULT;
  1367.       res= mysql_alter_table(thd, NullS, NullS, &create_info,
  1368.      tables, lex->create_list,
  1369.      lex->key_list, lex->drop_list, lex->alter_list,
  1370.                              (ORDER *) 0,
  1371.      0,DUP_ERROR);
  1372.     }
  1373.     else
  1374.       res = mysql_optimize_table(thd, tables, &lex->check_opt);
  1375.     break;
  1376.   }
  1377.   case SQLCOM_UPDATE:
  1378.     if (check_access(thd,UPDATE_ACL,tables->db,&tables->grant.privilege))
  1379.       goto error;
  1380.     if (grant_option && check_grant(thd,UPDATE_ACL,tables))
  1381.       goto error;
  1382.     if (lex->item_list.elements != lex->value_list.elements)
  1383.     {
  1384.       send_error(&thd->net,ER_WRONG_VALUE_COUNT);
  1385.       DBUG_VOID_RETURN;
  1386.     }
  1387.     res = mysql_update(thd,tables,
  1388.        lex->item_list,
  1389.        lex->value_list,
  1390.        lex->where,
  1391.        lex->select_limit,
  1392.        lex->duplicates,
  1393.        lex->lock_option);
  1394. #ifdef DELETE_ITEMS
  1395.     delete lex->where;
  1396. #endif
  1397.     break;
  1398.   case SQLCOM_INSERT:
  1399.     if (check_access(thd,INSERT_ACL,tables->db,&tables->grant.privilege))
  1400.       goto error; /* purecov: inspected */
  1401.     if (grant_option && check_grant(thd,INSERT_ACL,tables))
  1402.       goto error;
  1403.     res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
  1404.        lex->duplicates,
  1405.        lex->lock_option);
  1406.     break;
  1407.   case SQLCOM_REPLACE:
  1408.     if (check_access(thd,INSERT_ACL | UPDATE_ACL | DELETE_ACL,
  1409.      tables->db,&tables->grant.privilege))
  1410.       goto error; /* purecov: inspected */
  1411.     if (grant_option && check_grant(thd,INSERT_ACL | UPDATE_ACL | DELETE_ACL,
  1412.     tables))
  1413.       goto error;
  1414.     res = mysql_insert(thd,tables,lex->field_list,lex->many_values,
  1415.        DUP_REPLACE,
  1416.        lex->lock_option);
  1417.     break;
  1418.   case SQLCOM_REPLACE_SELECT:
  1419.   case SQLCOM_INSERT_SELECT:
  1420.   {
  1421.     // Check that we have modify privileges for the first table and
  1422.     // select privileges for the rest
  1423.     uint privilege= (lex->sql_command == SQLCOM_INSERT_SELECT ?
  1424.      INSERT_ACL : INSERT_ACL | UPDATE_ACL | DELETE_ACL);
  1425.     TABLE_LIST *save_next=tables->next;
  1426.     tables->next=0;
  1427.     if (check_access(thd, privilege,
  1428.      tables->db,&tables->grant.privilege) ||
  1429. (grant_option && check_grant(thd, privilege, tables)))
  1430.       goto error;
  1431.     tables->next=save_next;
  1432.     if ((res=check_table_access(thd, SELECT_ACL, save_next)))
  1433.       goto error;
  1434.     select_result *result;
  1435.     thd->offset_limit=lex->offset_limit;
  1436.     thd->select_limit=lex->select_limit+lex->offset_limit;
  1437.     if (thd->select_limit < lex->select_limit)
  1438.       thd->select_limit= HA_POS_ERROR; // No limit
  1439.     if (check_dup(thd,tables->db,tables->real_name,tables->next))
  1440.     {
  1441.       net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name);
  1442.       DBUG_VOID_RETURN;
  1443.     }
  1444.     tables->lock_type=TL_WRITE; // update first table
  1445.     if (!(res=open_and_lock_tables(thd,tables)))
  1446.     {
  1447.       if ((result=new select_insert(tables->table,&lex->field_list,
  1448.     lex->sql_command == SQLCOM_REPLACE_SELECT ?
  1449.     DUP_REPLACE : DUP_IGNORE)))
  1450.       {
  1451. res=mysql_select(thd,tables->next,lex->item_list,
  1452.  lex->where,
  1453.                          lex->ftfunc_list,
  1454.  (ORDER*) lex->order_list.first,
  1455.  (ORDER*) lex->group_list.first,
  1456.  lex->having,
  1457.  (ORDER*) lex->proc_list.first,
  1458.  lex->options | thd->options,
  1459.  result);
  1460. delete result;
  1461.       }
  1462.       else
  1463. res= -1;
  1464.     }
  1465. #ifdef DELETE_ITEMS
  1466.     delete lex->having;
  1467.     delete lex->where;
  1468. #endif
  1469.     break;
  1470.   }
  1471.   case SQLCOM_TRUNCATE:
  1472.     lex->where=0;
  1473.     lex->select_limit=HA_POS_ERROR;
  1474.     /* Fall through */
  1475.   case SQLCOM_DELETE:
  1476.   {
  1477.     if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege))
  1478.       goto error; /* purecov: inspected */
  1479.     if (grant_option && check_grant(thd,DELETE_ACL,tables))
  1480.       goto error;
  1481.     // Set privilege for the WHERE clause
  1482.     tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
  1483.     /* TRUNCATE ends previous transaction */
  1484.     if (lex->sql_command == SQLCOM_TRUNCATE && end_active_trans(thd))
  1485.       res= -1;
  1486.     else
  1487.       res = mysql_delete(thd,tables,lex->where,lex->select_limit,
  1488.  lex->lock_option, lex->options);
  1489.     break;
  1490.   }
  1491.   case SQLCOM_DROP_TABLE:
  1492.     {
  1493.       if (check_table_access(thd,DROP_ACL,tables))
  1494. goto error; /* purecov: inspected */
  1495.       if (end_active_trans(thd))
  1496. res= -1;
  1497.       else
  1498. res = mysql_rm_table(thd,tables,lex->drop_if_exists);
  1499.     }
  1500.     break;
  1501.   case SQLCOM_DROP_INDEX:
  1502.     if (!tables->db)
  1503.       tables->db=thd->db;
  1504.     if (check_access(thd,INDEX_ACL,tables->db,&tables->grant.privilege))
  1505.       goto error; /* purecov: inspected */
  1506.     if (grant_option && check_grant(thd,INDEX_ACL,tables))
  1507.       goto error;
  1508.     if (end_active_trans(thd))
  1509.       res= -1;
  1510.     else
  1511.       res = mysql_drop_index(thd, tables, lex->drop_list);
  1512.     break;
  1513.   case SQLCOM_SHOW_DATABASES:
  1514. #if defined(DONT_ALLOW_SHOW_COMMANDS)
  1515.     send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
  1516.     DBUG_VOID_RETURN;
  1517. #else
  1518.     if ((specialflag & SPECIAL_SKIP_SHOW_DB) &&
  1519. check_access(thd,PROCESS_ACL,any_db))
  1520.       goto error;
  1521.     res= mysqld_show_dbs(thd, (lex->wild ? lex->wild->ptr() : NullS));
  1522.     break;
  1523. #endif
  1524.   case SQLCOM_SHOW_PROCESSLIST:
  1525.     if (!thd->priv_user[0] && check_access(thd,PROCESS_ACL,any_db))
  1526.       break;
  1527.     mysqld_list_processes(thd,thd->master_access & PROCESS_ACL ? NullS :
  1528.   thd->priv_user,lex->verbose);
  1529.     break;
  1530.   case SQLCOM_SHOW_STATUS:
  1531.     res= mysqld_show(thd,(lex->wild ? lex->wild->ptr() : NullS),status_vars);
  1532.     break;
  1533.   case SQLCOM_SHOW_VARIABLES:
  1534.     res= mysqld_show(thd, (lex->wild ? lex->wild->ptr() : NullS),
  1535.      init_vars);
  1536.     break;
  1537.   case SQLCOM_SHOW_LOGS:
  1538. #ifdef DONT_ALLOW_SHOW_COMMANDS
  1539.     send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
  1540.     DBUG_VOID_RETURN;
  1541. #else
  1542.     {
  1543.       if (grant_option && check_access(thd, FILE_ACL, any_db))
  1544. goto error;
  1545.       res= mysqld_show_logs(thd);
  1546.       break;
  1547.     }
  1548. #endif
  1549.   case SQLCOM_SHOW_TABLES:
  1550.     /* FALL THROUGH */
  1551.   case SQLCOM_SHOW_OPEN_TABLES:
  1552. #ifdef DONT_ALLOW_SHOW_COMMANDS
  1553.     send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
  1554.     DBUG_VOID_RETURN;
  1555. #else
  1556.     {
  1557.       char *db=lex->db ? lex->db : thd->db;
  1558.       if (!db)
  1559.       {
  1560. send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
  1561. goto error; /* purecov: inspected */
  1562.       }
  1563.       remove_escape(db); // Fix escaped '_'
  1564.       if (check_db_name(db))
  1565.       {
  1566.         net_printf(&thd->net,ER_WRONG_DB_NAME, db);
  1567.         goto error;
  1568.       }
  1569.       if (check_access(thd,SELECT_ACL,db,&thd->col_access))
  1570. goto error; /* purecov: inspected */
  1571.       /* grant is checked in mysqld_show_tables */
  1572.       if (lex->sql_command == SQLCOM_SHOW_OPEN_TABLES)
  1573.         res= mysqld_show_open_tables(thd,db,
  1574.      (lex->wild ? lex->wild->ptr() : NullS));
  1575.       else if (lex->options & SELECT_DESCRIBE)
  1576.         res= mysqld_extend_show_tables(thd,db,
  1577.      (lex->wild ? lex->wild->ptr() : NullS));
  1578.       else
  1579. res= mysqld_show_tables(thd,db,
  1580. (lex->wild ? lex->wild->ptr() : NullS));
  1581.       break;
  1582.     }
  1583. #endif
  1584.   case SQLCOM_SHOW_FIELDS:
  1585. #ifdef DONT_ALLOW_SHOW_COMMANDS
  1586.     send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
  1587.     DBUG_VOID_RETURN;
  1588. #else
  1589.     {
  1590.       char *db=tables->db ? tables->db : thd->db;
  1591.       if (!db)
  1592.       {
  1593. send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
  1594. goto error; /* purecov: inspected */
  1595.       }
  1596.       remove_escape(db); // Fix escaped '_'
  1597.       remove_escape(tables->name);
  1598.       if (!tables->db)
  1599. tables->db=thd->db;
  1600.       if (check_access(thd,SELECT_ACL | EXTRA_ACL,db,&thd->col_access))
  1601. goto error; /* purecov: inspected */
  1602.       tables->grant.privilege=thd->col_access;
  1603.       if (grant_option && check_grant(thd,SELECT_ACL,tables,2))
  1604. goto error;
  1605.       res= mysqld_show_fields(thd,tables,
  1606.       (lex->wild ? lex->wild->ptr() : NullS),
  1607.       lex->verbose);
  1608.       break;
  1609.     }
  1610. #endif
  1611.   case SQLCOM_SHOW_KEYS:
  1612. #ifdef DONT_ALLOW_SHOW_COMMANDS
  1613.     send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */
  1614.     DBUG_VOID_RETURN;
  1615. #else
  1616.     {
  1617.       char *db=tables->db ? tables->db : thd->db;
  1618.       if (!db)
  1619.       {
  1620. send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: inspected */
  1621. goto error; /* purecov: inspected */
  1622.       }
  1623.       remove_escape(db); // Fix escaped '_'
  1624.       remove_escape(tables->name);
  1625.       if (!tables->db)
  1626. tables->db=thd->db;
  1627.       if (check_access(thd,SELECT_ACL,db,&thd->col_access))
  1628. goto error; /* purecov: inspected */
  1629.       tables->grant.privilege=thd->col_access;
  1630.       if (grant_option && check_grant(thd,SELECT_ACL,tables,2))
  1631. goto error;
  1632.       res= mysqld_show_keys(thd,tables);
  1633.       break;
  1634.     }
  1635. #endif
  1636.   case SQLCOM_CHANGE_DB:
  1637.     mysql_change_db(thd,lex->db);
  1638.     break;
  1639.   case SQLCOM_LOAD:
  1640.   {
  1641.     uint privilege= (lex->duplicates == DUP_REPLACE ?
  1642.      INSERT_ACL | UPDATE_ACL | DELETE_ACL : INSERT_ACL);
  1643.     if (!(lex->local_file && (thd->client_capabilities & CLIENT_LOCAL_FILES)))
  1644.     {
  1645.       if (check_access(thd,privilege | FILE_ACL,tables->db))
  1646. goto error;
  1647.     }
  1648.     else
  1649.     {
  1650.       if (check_access(thd,privilege,tables->db,&tables->grant.privilege) ||
  1651.  grant_option && check_grant(thd,privilege,tables))
  1652. goto error;
  1653.     }
  1654.     res=mysql_load(thd, lex->exchange, tables, lex->field_list,
  1655.    lex->duplicates, (bool) lex->local_file, lex->lock_option);
  1656.     break;
  1657.   }
  1658.   case SQLCOM_SET_OPTION:
  1659.   {
  1660.     uint org_options=thd->options;
  1661.     thd->options=lex->options;
  1662.     thd->update_lock_default= ((thd->options & OPTION_LOW_PRIORITY_UPDATES) ?
  1663.        TL_WRITE_LOW_PRIORITY : TL_WRITE);
  1664.     thd->default_select_limit=lex->select_limit;
  1665.     DBUG_PRINT("info",("options: %ld  limit: %ld",
  1666.        thd->options,(long) thd->default_select_limit));
  1667.     /* Check if auto_commit mode changed */
  1668.     if ((org_options ^ lex->options) & OPTION_NOT_AUTO_COMMIT)
  1669.     {
  1670.       if ((org_options & OPTION_NOT_AUTO_COMMIT))
  1671.       {
  1672. /* We changed to auto_commit mode */
  1673. thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
  1674. thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
  1675. if (ha_commit(thd))
  1676. {
  1677.   res= -1;
  1678.   break;
  1679. }
  1680.       }
  1681.       else
  1682.       {
  1683. thd->options&= ~(ulong) (OPTION_STATUS_NO_TRANS_UPDATE);
  1684. thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
  1685.       }
  1686.     }
  1687.     send_ok(&thd->net);
  1688.     break;
  1689.   }
  1690.   case SQLCOM_UNLOCK_TABLES:
  1691.     if (thd->locked_tables)
  1692.     {
  1693.       thd->lock=thd->locked_tables;
  1694.       thd->locked_tables=0; // Will be automaticly closed
  1695.     }
  1696.     if (thd->global_read_lock)
  1697.     {
  1698.       thd->global_read_lock=0;
  1699.       pthread_mutex_lock(&LOCK_open);
  1700.       global_read_lock--;
  1701.       pthread_cond_broadcast(&COND_refresh);
  1702.       pthread_mutex_unlock(&LOCK_open);
  1703.     }
  1704.     send_ok(&thd->net);
  1705.     break;
  1706.   case SQLCOM_LOCK_TABLES:
  1707.     if (thd->locked_tables)
  1708.     {
  1709.       thd->lock=thd->locked_tables;
  1710.       thd->locked_tables=0; // Will be automaticly closed
  1711.       close_thread_tables(thd);
  1712.     }
  1713.     if (check_db_used(thd,tables) || end_active_trans(thd))
  1714.       goto error;
  1715.     thd->in_lock_tables=1;
  1716.     if (!(res=open_and_lock_tables(thd,tables)))
  1717.     {
  1718.       thd->locked_tables=thd->lock;
  1719.       thd->lock=0;
  1720.       send_ok(&thd->net);
  1721.     }
  1722.     thd->in_lock_tables=0;
  1723.     break;
  1724.   case SQLCOM_CREATE_DB:
  1725.     {
  1726.       if (!stripp_sp(lex->name) || check_db_name(lex->name))
  1727.       {
  1728. net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
  1729. break;
  1730.       }
  1731.       if (check_access(thd,CREATE_ACL,lex->name,0,1))
  1732. break;
  1733.       mysql_create_db(thd,lex->name,lex->create_info.options);
  1734.       break;
  1735.     }
  1736.   case SQLCOM_DROP_DB:
  1737.     {
  1738.       if (!stripp_sp(lex->name) || check_db_name(lex->name))
  1739.       {
  1740. net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name);
  1741. break;
  1742.       }
  1743.       if (check_access(thd,DROP_ACL,lex->name,0,1) ||
  1744.   end_active_trans(thd))
  1745. break;
  1746.       mysql_rm_db(thd,lex->name,lex->drop_if_exists);
  1747.       break;
  1748.     }
  1749.   case SQLCOM_CREATE_FUNCTION:
  1750.     if (check_access(thd,INSERT_ACL,"mysql",0,1))
  1751.       break;
  1752. #ifdef HAVE_DLOPEN
  1753.     if (!(res = mysql_create_function(thd,&lex->udf)))
  1754.       send_ok(&thd->net);
  1755. #else
  1756.     res= -1;
  1757. #endif
  1758.     break;
  1759.   case SQLCOM_DROP_FUNCTION:
  1760.     if (check_access(thd,DELETE_ACL,"mysql",0,1))
  1761.       break;
  1762. #ifdef HAVE_DLOPEN
  1763.     if (!(res = mysql_drop_function(thd,lex->udf.name)))
  1764.       send_ok(&thd->net);
  1765. #else
  1766.     res= -1;
  1767. #endif
  1768.     break;
  1769.  case SQLCOM_REVOKE:
  1770.  case SQLCOM_GRANT:
  1771.    {
  1772.      if (tables && !tables->db)
  1773.        tables->db=thd->db;
  1774.      if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
  1775.       tables && tables->db ? tables->db : lex->db,
  1776.       tables ? &tables->grant.privilege : 0,
  1777.       tables ? 0 : 1))
  1778.        goto error;
  1779.      /* Check that the user isn't trying to change a password for another
  1780. user if he doesn't have UPDATE privilege to the MySQL database */
  1781.      if (thd->user) // If not replication
  1782.      {
  1783.        LEX_USER *user;
  1784.        List_iterator <LEX_USER> user_list(lex->users_list);
  1785.        while ((user=user_list++))
  1786.        {
  1787.  if (user->password.str &&
  1788.      (strcmp(thd->user,user->user.str) ||
  1789.       user->host.str &&
  1790.       my_strcasecmp(user->host.str, thd->host ? thd->host : thd->ip)))
  1791.  {
  1792.    if (check_access(thd, UPDATE_ACL, "mysql",0,1))
  1793.      goto error;
  1794.    break; // We are allowed to do changes
  1795.  }
  1796.        }
  1797.      }
  1798.      if (tables)
  1799.      {
  1800.        if (grant_option && check_grant(thd,
  1801.        (lex->grant | lex->grant_tot_col |
  1802. GRANT_ACL),
  1803.        tables))
  1804.  goto error;
  1805.        res = mysql_table_grant(thd,tables,lex->users_list, lex->columns,
  1806.        lex->grant, lex->sql_command == SQLCOM_REVOKE);
  1807.        if(!res)
  1808.        {
  1809.  mysql_update_log.write(thd, thd->query,thd->query_length);
  1810.  if (mysql_bin_log.is_open())
  1811.  {
  1812.    Query_log_event qinfo(thd, thd->query);
  1813.    mysql_bin_log.write(&qinfo);
  1814.  }
  1815.        }
  1816.      }
  1817.      else
  1818.      {
  1819.        if (lex->columns.elements)
  1820.        {
  1821.  net_printf(&thd->net,ER_ILLEGAL_GRANT_FOR_TABLE);
  1822.  res=1;
  1823.        }
  1824.        else
  1825.  res = mysql_grant(thd, lex->db, lex->users_list, lex->grant,
  1826.    lex->sql_command == SQLCOM_REVOKE);
  1827.        if(!res)
  1828.        {
  1829.  mysql_update_log.write(thd, thd->query,thd->query_length);
  1830.  if (mysql_bin_log.is_open())
  1831.  {
  1832.    Query_log_event qinfo(thd, thd->query);
  1833.    mysql_bin_log.write(&qinfo);
  1834.  }
  1835.        }
  1836.      }
  1837.      break;
  1838.    }
  1839.   case SQLCOM_FLUSH:
  1840.   case SQLCOM_RESET:
  1841.     if (check_access(thd,RELOAD_ACL,any_db) || check_db_used(thd, tables))
  1842.       goto error;
  1843.     if (reload_acl_and_cache(thd, lex->type, tables))
  1844.       send_error(&thd->net,0);
  1845.     else
  1846.       send_ok(&thd->net);
  1847.     break;
  1848.   case SQLCOM_KILL:
  1849.     kill_one_thread(thd,lex->thread_id);
  1850.     break;
  1851.   case SQLCOM_SHOW_GRANTS:
  1852.     res=0;
  1853.     if ((thd->priv_user && !strcmp(thd->priv_user,lex->grant_user->user.str)) ||
  1854. !check_access(thd, SELECT_ACL, "mysql",0,1))
  1855.     {
  1856.       res = mysql_show_grants(thd,lex->grant_user);
  1857.     }
  1858.     break;
  1859.   case SQLCOM_BEGIN:
  1860.     if (end_active_trans(thd))
  1861.     {
  1862.       res= -1;
  1863.     }
  1864.     else
  1865.     {
  1866.       thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
  1867.      OPTION_BEGIN);
  1868.       thd->server_status|= SERVER_STATUS_IN_TRANS;
  1869.       send_ok(&thd->net);
  1870.     }
  1871.     break;
  1872.   case SQLCOM_COMMIT:
  1873.     /*
  1874.       We don't use end_active_trans() here to ensure that this works
  1875.       even if there is a problem with the OPTION_AUTO_COMMIT flag
  1876.       (Which of course should never happen...)
  1877.     */
  1878.     thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
  1879.     thd->server_status&= ~SERVER_STATUS_IN_TRANS;
  1880.     if (!ha_commit(thd))
  1881.       send_ok(&thd->net);
  1882.     else
  1883.       res= -1;
  1884.     break;
  1885.   case SQLCOM_ROLLBACK:
  1886.     thd->server_status&= ~SERVER_STATUS_IN_TRANS;
  1887.     if (!ha_rollback(thd))
  1888.     {
  1889.       if (thd->options & OPTION_STATUS_NO_TRANS_UPDATE)
  1890. send_warning(&thd->net,ER_WARNING_NOT_COMPLETE_ROLLBACK,0);
  1891.       else
  1892. send_ok(&thd->net);
  1893.     }
  1894.     else
  1895.       res= -1;
  1896.     thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
  1897.     break;
  1898.   default: /* Impossible */
  1899.     send_ok(&thd->net);
  1900.     break;
  1901.   }
  1902.   thd->proc_info="query end"; // QQ
  1903.   if (res < 0)
  1904.     send_error(&thd->net,thd->killed ? ER_SERVER_SHUTDOWN : 0);
  1905. error:
  1906.   DBUG_VOID_RETURN;
  1907. }
  1908. /****************************************************************************
  1909. ** Get the user (global) and database privileges for all used tables
  1910. ** Returns true (error) if we can't get the privileges and we don't use
  1911. ** table/column grants.
  1912. ** The idea of EXTRA_ACL is that one will be granted access to the table if
  1913. ** one has the asked privilege on any column combination of the table; For
  1914. ** example to be able to check a table one needs to have SELECT privilege on
  1915. ** any column of the table.
  1916. ****************************************************************************/
  1917. bool
  1918. check_access(THD *thd,uint want_access,const char *db, uint *save_priv,
  1919.      bool dont_check_global_grants)
  1920. {
  1921.   uint db_access,dummy;
  1922.   if (save_priv)
  1923.     *save_priv=0;
  1924.   else
  1925.     save_priv= &dummy;
  1926.   if (!db && !thd->db && !dont_check_global_grants)
  1927.   {
  1928.     send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: tested */
  1929.     return TRUE; /* purecov: tested */
  1930.   }
  1931.   if ((thd->master_access & want_access) == want_access)
  1932.   {
  1933.     *save_priv=thd->master_access;
  1934.     return FALSE;
  1935.   }
  1936.   if ((want_access & ~thd->master_access) & ~(DB_ACLS | EXTRA_ACL) ||
  1937.       ! db && dont_check_global_grants)
  1938.   { // We can never grant this
  1939.     net_printf(&thd->net,ER_ACCESS_DENIED_ERROR,
  1940.        thd->priv_user,
  1941.        thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"),
  1942.        thd->password ? ER(ER_YES) : ER(ER_NO));/* purecov: tested */
  1943.     return TRUE; /* purecov: tested */
  1944.   }
  1945.   if (db == any_db)
  1946.     return FALSE; // Allow select on anything
  1947.   
  1948.   if (db && (!thd->db || strcmp(db,thd->db)))
  1949.     db_access=acl_get(thd->host, thd->ip, (char*) &thd->remote.sin_addr,
  1950.       thd->priv_user, db); /* purecov: inspected */
  1951.   else
  1952.     db_access=thd->db_access;
  1953.   want_access &= ~EXTRA_ACL; // Remove SHOW attribute
  1954.   db_access= ((*save_priv=(db_access | thd->master_access)) & want_access);
  1955.   /* grant_option is set if there exists a single table or column grant */
  1956.   if (db_access == want_access ||
  1957.       ((grant_option && !dont_check_global_grants) &&
  1958.        !(want_access & ~TABLE_ACLS)))
  1959.     return FALSE; /* Ok */
  1960.   net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR,
  1961.      thd->priv_user,
  1962.      thd->host ? thd->host : (thd->ip ? thd->ip : "unknown"),
  1963.      db ? db : thd->db ? thd->db : "unknown"); /* purecov: tested */
  1964.   return TRUE; /* purecov: tested */
  1965. }
  1966. /*
  1967. ** Check the privilege for all used tables.  Table privileges are cached
  1968. ** in the table list for GRANT checking
  1969. */
  1970. static bool
  1971. check_table_access(THD *thd,uint want_access,TABLE_LIST *tables)
  1972. {
  1973.   uint found=0,found_access=0;
  1974.   TABLE_LIST *org_tables=tables;
  1975.   for (; tables ; tables=tables->next)
  1976.   {
  1977.     if ((thd->master_access & want_access) == (want_access & ~EXTRA_ACL) &&
  1978. thd->db)
  1979.       tables->grant.privilege= want_access;
  1980.     else if (tables->db && tables->db == thd->db)
  1981.     {
  1982.       if (found && !grant_option) // db already checked
  1983. tables->grant.privilege=found_access;
  1984.       else
  1985.       {
  1986. if (check_access(thd,want_access,tables->db,&tables->grant.privilege))
  1987.   return TRUE; // Access denied
  1988. found_access=tables->grant.privilege;
  1989. found=1;
  1990.       }
  1991.     }
  1992.     else if (check_access(thd,want_access,tables->db,&tables->grant.privilege))
  1993.       return TRUE; // Access denied
  1994.   }
  1995.   if (grant_option)
  1996.   {
  1997.     want_access &= ~EXTRA_ACL; // Remove SHOW attribute
  1998.     return check_grant(thd,want_access,org_tables);
  1999.   }
  2000.   return FALSE;
  2001. }
  2002. static bool check_db_used(THD *thd,TABLE_LIST *tables)
  2003. {
  2004.   for (; tables ; tables=tables->next)
  2005.   {
  2006.     if (!tables->db)
  2007.     {
  2008.       if (!(tables->db=thd->db))
  2009.       {
  2010. send_error(&thd->net,ER_NO_DB_ERROR); /* purecov: tested */
  2011. return TRUE; /* purecov: tested */
  2012.       }
  2013.     }
  2014.   }
  2015.   return FALSE;
  2016. }
  2017. static bool check_merge_table_access(THD *thd, char *db,
  2018.      TABLE_LIST *table_list)
  2019. {
  2020.   int error=0;
  2021.   if (table_list)
  2022.   {
  2023.     /* Force all tables to use the current database */
  2024.     TABLE_LIST *tmp;
  2025.     for (tmp=table_list; tmp ; tmp=tmp->next)
  2026.       tmp->db=db;
  2027.     error=check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
  2028.      table_list);
  2029.   }
  2030.   return error;
  2031. }
  2032. /****************************************************************************
  2033. Check stack size; Send error if there isn't enough stack to continue
  2034. ****************************************************************************/
  2035. #if STACK_DIRECTION < 0
  2036. #define used_stack(A,B) (long) (A - B)
  2037. #else
  2038. #define used_stack(A,B) (long) (B - A)
  2039. #endif
  2040. bool check_stack_overrun(THD *thd,char *buf __attribute__((unused)))
  2041. {
  2042.   long stack_used;
  2043.   if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >=
  2044.       (long) thread_stack_min)
  2045.   {
  2046.     sprintf(errbuff[0],ER(ER_STACK_OVERRUN),stack_used,thread_stack);
  2047.     my_message(ER_STACK_OVERRUN,errbuff[0],MYF(0));
  2048.     thd->fatal_error=1;
  2049.     return 1;
  2050.   }
  2051.   return 0;
  2052. }
  2053. #define MY_YACC_INIT 1000 // Start with big alloc
  2054. #define MY_YACC_MAX  32000 // Because of 'short'
  2055. bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, int *yystacksize)
  2056. {
  2057.   LEX *lex=current_lex;
  2058.   int  old_info=0;
  2059.   if ((uint) *yystacksize >= MY_YACC_MAX)
  2060.     return 1;
  2061.   if (!lex->yacc_yyvs)
  2062.     old_info= *yystacksize;
  2063.   *yystacksize= set_zone((*yystacksize)*2,MY_YACC_INIT,MY_YACC_MAX);
  2064.   if (!(lex->yacc_yyvs= (char*)
  2065. my_realloc((gptr) lex->yacc_yyvs,
  2066.    *yystacksize*sizeof(**yyvs),
  2067.    MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
  2068.       !(lex->yacc_yyss= (char*)
  2069. my_realloc((gptr) lex->yacc_yyss,
  2070.    *yystacksize*sizeof(**yyss),
  2071.    MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
  2072.     return 1;
  2073.   if (old_info)
  2074.   { // Copy old info from stack
  2075.     memcpy(lex->yacc_yyss, (gptr) *yyss, old_info*sizeof(**yyss));
  2076.     memcpy(lex->yacc_yyvs, (gptr) *yyvs, old_info*sizeof(**yyvs));
  2077.   }
  2078.   *yyss=(short*) lex->yacc_yyss;
  2079.   *yyvs=(YYSTYPE*) lex->yacc_yyvs;
  2080.   return 0;
  2081. }
  2082. /****************************************************************************
  2083. Initialize global thd variables neaded for query
  2084. ****************************************************************************/
  2085. static void
  2086. mysql_init_query(THD *thd)
  2087. {
  2088.   DBUG_ENTER("mysql_init_query");
  2089.   thd->lex.item_list.empty();
  2090.   thd->lex.value_list.empty();
  2091.   thd->lex.table_list.elements=0;
  2092.   thd->free_list=0;
  2093.   thd->lex.table_list.first=0;
  2094.   thd->lex.table_list.next= (byte**) &thd->lex.table_list.first;
  2095.   thd->fatal_error=0; // Safety
  2096.   thd->last_insert_id_used=thd->query_start_used=thd->insert_id_used=0;
  2097.   thd->sent_row_count=0;
  2098.   DBUG_VOID_RETURN;
  2099. }
  2100. void
  2101. mysql_init_select(LEX *lex)
  2102. {
  2103.   lex->where=lex->having=0;
  2104.   lex->select_limit=current_thd->default_select_limit;
  2105.   lex->offset_limit=0L;
  2106.   lex->options=0;
  2107.   lex->exchange = 0;
  2108.   lex->proc_list.first=0;
  2109.   lex->order_list.elements=lex->group_list.elements=0;
  2110.   lex->order_list.first=0;
  2111.   lex->order_list.next= (byte**) &lex->order_list.first;
  2112.   lex->group_list.first=0;
  2113.   lex->group_list.next= (byte**) &lex->group_list.first;
  2114. }
  2115. void
  2116. mysql_parse(THD *thd,char *inBuf,uint length)
  2117. {
  2118.   DBUG_ENTER("mysql_parse");
  2119.   mysql_init_query(thd);
  2120.   thd->query_length = length;
  2121.   LEX *lex=lex_start(thd, (uchar*) inBuf, length);
  2122.   if (!yyparse() && ! thd->fatal_error)
  2123.     mysql_execute_command();
  2124.   thd->proc_info="freeing items";
  2125.   free_items(thd);  /* Free strings used by items */
  2126.   lex_end(lex);
  2127.   DBUG_VOID_RETURN;
  2128. }
  2129. inline static void
  2130. link_in_list(SQL_LIST *list,byte *element,byte **next)
  2131. {
  2132.   list->elements++;
  2133.   (*list->next)=element;
  2134.   list->next=next;
  2135.   *next=0;
  2136. }
  2137. /*****************************************************************************
  2138. ** Store field definition for create
  2139. ** Return 0 if ok
  2140. ******************************************************************************/
  2141. bool add_field_to_list(char *field_name, enum_field_types type,
  2142.        char *length, char *decimals,
  2143.        uint type_modifier, Item *default_value,char *change,
  2144.        TYPELIB *interval)
  2145. {
  2146.   register create_field *new_field;
  2147.   THD *thd=current_thd;
  2148.   LEX  *lex= &thd->lex;
  2149.   uint allowed_type_modifier=0;
  2150.   DBUG_ENTER("add_field_to_list");
  2151.   if (strlen(field_name) > NAME_LEN)
  2152.   {
  2153.     net_printf(&thd->net, ER_TOO_LONG_IDENT, field_name); /* purecov: inspected */
  2154.     DBUG_RETURN(1); /* purecov: inspected */
  2155.   }
  2156.   if (type_modifier & PRI_KEY_FLAG)
  2157.   {
  2158.     lex->col_list.push_back(new key_part_spec(field_name,0));
  2159.     lex->key_list.push_back(new Key(Key::PRIMARY,NullS,
  2160.     lex->col_list));
  2161.     lex->col_list.empty();
  2162.   }
  2163.   if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
  2164.   {
  2165.     lex->col_list.push_back(new key_part_spec(field_name,0));
  2166.     lex->key_list.push_back(new Key(Key::UNIQUE,NullS,
  2167.     lex->col_list));
  2168.     lex->col_list.empty();
  2169.   }
  2170.   if (default_value && default_value->type() == Item::NULL_ITEM)
  2171.   {
  2172.     if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) ==
  2173. NOT_NULL_FLAG)
  2174.     {
  2175.       net_printf(&thd->net,ER_INVALID_DEFAULT,field_name);
  2176.       DBUG_RETURN(1);
  2177.     }
  2178.     default_value=0;
  2179.   }
  2180.   if (!(new_field=new create_field()))
  2181.     DBUG_RETURN(1);
  2182.   new_field->field=0;
  2183.   new_field->field_name=field_name;
  2184.   new_field->def= (type_modifier & AUTO_INCREMENT_FLAG ? 0 : default_value);
  2185.   new_field->flags= type_modifier;
  2186.   new_field->unireg_check= (type_modifier & AUTO_INCREMENT_FLAG ?
  2187.     Field::NEXT_NUMBER : Field::NONE);
  2188.   new_field->decimals= decimals ? (uint) set_zone(atoi(decimals),0,
  2189.   NOT_FIXED_DEC-1) : 0;
  2190.   new_field->sql_type=type;
  2191.   new_field->length=0;
  2192.   new_field->change=change;
  2193.   new_field->interval=0;
  2194.   new_field->pack_length=0;
  2195.   if (length)
  2196.     if (!(new_field->length= (uint) atoi(length)))
  2197.       length=0; /* purecov: inspected */
  2198.   uint sign_len=type_modifier & UNSIGNED_FLAG ? 0 : 1;
  2199.   if (new_field->length && new_field->decimals &&
  2200.       new_field->length < new_field->decimals+2 &&
  2201.       new_field->decimals != NOT_FIXED_DEC)
  2202.     new_field->length=new_field->decimals+2; /* purecov: inspected */
  2203.   switch (type) {
  2204.   case FIELD_TYPE_TINY:
  2205.     if (!length) new_field->length=3+sign_len;
  2206.     allowed_type_modifier= AUTO_INCREMENT_FLAG;
  2207.     break;
  2208.   case FIELD_TYPE_SHORT:
  2209.     if (!length) new_field->length=5+sign_len;
  2210.     allowed_type_modifier= AUTO_INCREMENT_FLAG;
  2211.     break;
  2212.   case FIELD_TYPE_INT24:
  2213.     if (!length) new_field->length=8+sign_len;
  2214.     allowed_type_modifier= AUTO_INCREMENT_FLAG;
  2215.     break;
  2216.   case FIELD_TYPE_LONG:
  2217.     if (!length) new_field->length=10+sign_len;
  2218.     allowed_type_modifier= AUTO_INCREMENT_FLAG;
  2219.     break;
  2220.   case FIELD_TYPE_LONGLONG:
  2221.     if (!length) new_field->length=20;
  2222.     allowed_type_modifier= AUTO_INCREMENT_FLAG;
  2223.     break;
  2224.   case FIELD_TYPE_STRING:
  2225.   case FIELD_TYPE_VAR_STRING:
  2226.   case FIELD_TYPE_NULL:
  2227.     break;
  2228.   case FIELD_TYPE_DECIMAL:
  2229.     if (!length)
  2230.       new_field->length = 10; // Default length for DECIMAL
  2231.     new_field->length+=sign_len;
  2232.     if (new_field->decimals)
  2233.       new_field->length++;
  2234.     break;
  2235.   case FIELD_TYPE_BLOB:
  2236.   case FIELD_TYPE_TINY_BLOB:
  2237.   case FIELD_TYPE_LONG_BLOB:
  2238.   case FIELD_TYPE_MEDIUM_BLOB:
  2239.     if (default_value) // Allow empty as default value
  2240.     {
  2241.       String str,*res;
  2242.       res=default_value->val_str(&str);
  2243.       if (res->length())
  2244.       {
  2245. net_printf(&thd->net,ER_BLOB_CANT_HAVE_DEFAULT,field_name); /* purecov: inspected */
  2246. DBUG_RETURN(1); /* purecov: inspected */
  2247.       }
  2248.       new_field->def=0;
  2249.     }
  2250.     new_field->flags|=BLOB_FLAG;
  2251.     break;
  2252.   case FIELD_TYPE_YEAR:
  2253.     if (!length || new_field->length != 2)
  2254.       new_field->length=4; // Default length
  2255.     new_field->flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
  2256.     break;
  2257.   case FIELD_TYPE_FLOAT:
  2258.     /* change FLOAT(precision) to FLOAT or DOUBLE */
  2259.     allowed_type_modifier= AUTO_INCREMENT_FLAG;
  2260.     if (length && !decimals)
  2261.     {
  2262.       uint tmp_length=new_field->length;
  2263.       if (tmp_length > PRECISION_FOR_DOUBLE)
  2264.       {
  2265. net_printf(&thd->net,ER_WRONG_FIELD_SPEC,field_name);
  2266. DBUG_RETURN(1);
  2267.       }
  2268.       else if (tmp_length > PRECISION_FOR_FLOAT)
  2269.       {
  2270. new_field->sql_type=FIELD_TYPE_DOUBLE;
  2271. new_field->length=DBL_DIG+7; // -[digits].E+###
  2272.       }
  2273.       else
  2274. new_field->length=FLT_DIG+6; // -[digits].E+##
  2275.       new_field->decimals= NOT_FIXED_DEC;
  2276.       break;
  2277.     }
  2278.     if (!length)
  2279.     {
  2280.       new_field->length =  FLT_DIG+6;
  2281.       new_field->decimals= NOT_FIXED_DEC;
  2282.     }
  2283.     break;
  2284.   case FIELD_TYPE_DOUBLE:
  2285.     allowed_type_modifier= AUTO_INCREMENT_FLAG;
  2286.     if (!length)
  2287.     {
  2288.       new_field->length = DBL_DIG+7;
  2289.       new_field->decimals=NOT_FIXED_DEC;
  2290.     }
  2291.     break;
  2292.   case FIELD_TYPE_TIMESTAMP:
  2293.     if (!length)
  2294.       new_field->length= 14; // Full date YYYYMMDDHHMMSS
  2295.     else
  2296.     {
  2297.       new_field->length=((new_field->length+1)/2)*2; /* purecov: inspected */
  2298.       new_field->length= min(new_field->length,14); /* purecov: inspected */
  2299.     }
  2300.     new_field->flags|= ZEROFILL_FLAG | UNSIGNED_FLAG | NOT_NULL_FLAG;
  2301.     break;
  2302.   case FIELD_TYPE_DATE: // Old date type
  2303.     if (protocol_version != PROTOCOL_VERSION-1)
  2304.       new_field->sql_type=FIELD_TYPE_NEWDATE;
  2305.     /* fall trough */
  2306.   case FIELD_TYPE_NEWDATE:
  2307.     new_field->length=10;
  2308.     break;
  2309.   case FIELD_TYPE_TIME:
  2310.     new_field->length=10;
  2311.     break;
  2312.   case FIELD_TYPE_DATETIME:
  2313.     new_field->length=19;
  2314.     break;
  2315.   case FIELD_TYPE_SET:
  2316.     {
  2317.       if (interval->count > sizeof(longlong)*8)
  2318.       {
  2319. net_printf(&thd->net,ER_TOO_BIG_SET,field_name); /* purecov: inspected */
  2320. DBUG_RETURN(1); /* purecov: inspected */
  2321.       }
  2322.       new_field->pack_length=(interval->count+7)/8;
  2323.       if (new_field->pack_length > 4)
  2324. new_field->pack_length=8;
  2325.       new_field->interval=interval;
  2326.       new_field->length=0;
  2327.       for (const char **pos=interval->type_names; *pos ; pos++)
  2328. new_field->length+=(uint) strlen(*pos)+1;
  2329.       new_field->length--;
  2330.       set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1);
  2331.       if (default_value)
  2332.       {
  2333. thd->cuted_fields=0;
  2334. String str,*res;
  2335. res=default_value->val_str(&str);
  2336. (void) find_set(interval,res->ptr(),res->length());
  2337. if (thd->cuted_fields)
  2338. {
  2339.   net_printf(&thd->net,ER_INVALID_DEFAULT,field_name);
  2340.   DBUG_RETURN(1);
  2341. }
  2342.       }
  2343.     }
  2344.     break;
  2345.   case FIELD_TYPE_ENUM:
  2346.     {
  2347.       new_field->interval=interval;
  2348.       new_field->pack_length=interval->count < 256 ? 1 : 2; // Should be safe
  2349.       new_field->length=(uint) strlen(interval->type_names[0]);
  2350.       for (const char **pos=interval->type_names+1; *pos ; pos++)
  2351.       {
  2352. uint length=(uint) strlen(*pos);
  2353. set_if_bigger(new_field->length,length);
  2354.       }
  2355.       set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1);
  2356.       if (default_value)
  2357.       {
  2358. String str,*res;
  2359. res=default_value->val_str(&str);
  2360. if (!find_enum(interval,res->ptr(),res->length()))
  2361. {
  2362.   net_printf(&thd->net,ER_INVALID_DEFAULT,field_name);
  2363.   DBUG_RETURN(1);
  2364. }
  2365.       }
  2366.       break;
  2367.     }
  2368.   }
  2369.   if (new_field->length >= MAX_FIELD_WIDTH ||
  2370.       (!new_field->length && !(new_field->flags & BLOB_FLAG) &&
  2371.        type != FIELD_TYPE_STRING))
  2372.   {
  2373.     net_printf(&thd->net,ER_TOO_BIG_FIELDLENGTH,field_name,
  2374.        MAX_FIELD_WIDTH-1); /* purecov: inspected */
  2375.     DBUG_RETURN(1); /* purecov: inspected */
  2376.   }
  2377.   type_modifier&= AUTO_INCREMENT_FLAG;
  2378.   if ((~allowed_type_modifier) & type_modifier)
  2379.   {
  2380.     net_printf(&thd->net,ER_WRONG_FIELD_SPEC,field_name);
  2381.     DBUG_RETURN(1);
  2382.   }
  2383.   if (!new_field->pack_length)
  2384.     new_field->pack_length=calc_pack_length(new_field->sql_type ==
  2385.     FIELD_TYPE_VAR_STRING ?
  2386.     FIELD_TYPE_STRING :
  2387.     new_field->sql_type,
  2388.     new_field->length);
  2389.   lex->create_list.push_back(new_field);
  2390.   lex->last_field=new_field;
  2391.   DBUG_RETURN(0);
  2392. }
  2393. /* Store position for column in ALTER TABLE .. ADD column */
  2394. void store_position_for_column(const char *name)
  2395. {
  2396.   current_lex->last_field->after=my_const_cast(char*) (name);
  2397. }
  2398. bool
  2399. add_proc_to_list(Item *item)
  2400. {
  2401.   ORDER *order;
  2402.   Item **item_ptr;
  2403.   if (!(order = (ORDER *) sql_alloc(sizeof(ORDER)+sizeof(Item*))))
  2404.     return 1;
  2405.   item_ptr = (Item**) (order+1);
  2406.   *item_ptr= item;
  2407.   order->item=item_ptr;
  2408.   order->free_me=0;
  2409.   link_in_list(&current_lex->proc_list,(byte*) order,(byte**) &order->next);
  2410.   return 0;
  2411. }
  2412. /* Fix escaping of _, % and  in database and table names (for ODBC) */
  2413. static void remove_escape(char *name)
  2414. {
  2415.   char *to;
  2416. #ifdef USE_MB
  2417.   char *strend=name+(uint) strlen(name);
  2418. #endif
  2419.   for (to=name; *name ; name++)
  2420.   {
  2421. #ifdef USE_MB
  2422.     int l;
  2423. /*    if ((l = ismbchar(name, name+MBMAXLEN))) { Wei He: I think it's wrong */
  2424.     if (use_mb(default_charset_info) &&
  2425.         (l = my_ismbchar(default_charset_info, name, strend)))
  2426.     {
  2427. while (l--)
  2428.     *to++ = *name++;
  2429. name--;
  2430. continue;
  2431.     }
  2432. #endif
  2433.     if (*name == '\' && name[1])
  2434.       name++; // Skipp '\'
  2435.     *to++= *name;
  2436.   }
  2437.   *to=0;
  2438. }
  2439. /****************************************************************************
  2440. ** save order by and tables in own lists
  2441. ****************************************************************************/
  2442. bool add_to_list(SQL_LIST &list,Item *item,bool asc)
  2443. {
  2444.   ORDER *order;
  2445.   Item **item_ptr;
  2446.   DBUG_ENTER("add_to_list");
  2447.   if (!(order = (ORDER *) sql_alloc(sizeof(ORDER)+sizeof(Item*))))
  2448.     DBUG_RETURN(1);
  2449.   item_ptr = (Item**) (order+1);
  2450.   *item_ptr=item;
  2451.   order->item= item_ptr;
  2452.   order->asc = asc;
  2453.   order->free_me=0;
  2454.   order->used=0;
  2455.   link_in_list(&list,(byte*) order,(byte**) &order->next);
  2456.   DBUG_RETURN(0);
  2457. }
  2458. TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
  2459.       bool updating,
  2460.       thr_lock_type flags,
  2461.       List<String> *use_index,
  2462.       List<String> *ignore_index
  2463.       )
  2464. {
  2465.   register TABLE_LIST *ptr;
  2466.   THD *thd=current_thd;
  2467.   char *alias_str;
  2468.   const char *current_db;
  2469.   DBUG_ENTER("add_table_to_list");
  2470.   if (!table)
  2471.     DBUG_RETURN(0); // End of memory
  2472.   alias_str= alias ? alias->str : table->table.str;
  2473.   if (table->table.length > NAME_LEN ||
  2474.       check_table_name(table->table.str,table->table.length) ||
  2475.       table->db.str && check_db_name(table->db.str))
  2476.   {
  2477.     net_printf(&thd->net,ER_WRONG_TABLE_NAME,table->table.str);
  2478.     DBUG_RETURN(0);
  2479.   }
  2480. #ifdef FN_LOWER_CASE
  2481.   if (!alias) /* Alias is case sensitive */
  2482.     if (!(alias_str=sql_strmake(alias_str,table->table.length)))
  2483.       DBUG_RETURN(0);
  2484.   if (lower_case_table_names)
  2485.     casedn_str(table->table.str);
  2486. #endif
  2487.   if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
  2488.     DBUG_RETURN(0); /* purecov: inspected */
  2489.   ptr->db= table->db.str;
  2490.   ptr->real_name=table->table.str;
  2491.   ptr->name=alias_str;
  2492.   ptr->lock_type=flags;
  2493.   ptr->updating=updating;
  2494.   if (use_index)
  2495.     ptr->use_index=(List<String> *) thd->memdup((gptr) use_index,
  2496.        sizeof(*use_index));
  2497.   if (ignore_index)
  2498.     ptr->ignore_index=(List<String> *) thd->memdup((gptr) ignore_index,
  2499.    sizeof(*ignore_index));
  2500.   /* check that used name is unique */
  2501.   current_db=thd->db ? thd->db : "";
  2502.   if (flags != TL_IGNORE)
  2503.   {
  2504.     for (TABLE_LIST *tables=(TABLE_LIST*) thd->lex.table_list.first ; tables ;
  2505.  tables=tables->next)
  2506.     {
  2507.       if (!strcmp(alias_str,tables->name) &&
  2508.   !strcmp(ptr->db ? ptr->db : current_db,
  2509.   tables->db ? tables->db : current_db))
  2510.       {
  2511. net_printf(&thd->net,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */
  2512. DBUG_RETURN(0); /* purecov: tested */
  2513.       }
  2514.     }
  2515.   }
  2516.   link_in_list(&thd->lex.table_list,(byte*) ptr,(byte**) &ptr->next);
  2517.   DBUG_RETURN(ptr);
  2518. }
  2519. void add_join_on(TABLE_LIST *b,Item *expr)
  2520. {
  2521.   if (!b->on_expr)
  2522.     b->on_expr=expr;
  2523.   else
  2524.   {
  2525.     // This only happens if you have both a right and left join
  2526.     b->on_expr=new Item_cond_and(b->on_expr,expr);
  2527.   }
  2528. }
  2529. void add_join_natural(TABLE_LIST *a,TABLE_LIST *b)
  2530. {
  2531.   b->natural_join=a;
  2532. }
  2533. /* Check if name is used in table list */
  2534. static bool check_dup(THD *thd,const char *db,const char *name,
  2535.       TABLE_LIST *tables)
  2536. {
  2537.   const char *thd_db=thd->db ? thd->db : any_db;
  2538.   for (; tables ; tables=tables->next)
  2539.     if (!strcmp(name,tables->real_name) &&
  2540. !strcmp(db ? db : thd_db, tables->db ? tables->db : thd_db))
  2541.       return 1;
  2542.   return 0;
  2543. }
  2544. bool reload_acl_and_cache(THD *thd, uint options, TABLE_LIST *tables)
  2545. {
  2546.   bool result=0;
  2547.   select_errors=0; /* Write if more errors */
  2548.   // mysql_log.flush(); // Flush log
  2549.   if (options & REFRESH_GRANT)
  2550.   {
  2551.     acl_reload();
  2552.     grant_reload();
  2553.   }
  2554.   if (options & REFRESH_LOG)
  2555.   {
  2556.     mysql_log.new_file();
  2557.     mysql_update_log.new_file();
  2558.     mysql_bin_log.new_file();
  2559.     mysql_slow_log.new_file();
  2560.     if (ha_flush_logs())
  2561.       result=1;
  2562.   }
  2563.   if (options & (REFRESH_TABLES | REFRESH_READ_LOCK))
  2564.   {
  2565.     if ((options & REFRESH_READ_LOCK) && thd && ! thd->global_read_lock)
  2566.     {
  2567.       thd->global_read_lock=1;
  2568.       thread_safe_increment(global_read_lock,&LOCK_open);
  2569.     }
  2570.     result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables);
  2571.   }
  2572.   if (options & REFRESH_HOSTS)
  2573.     hostname_cache_refresh();
  2574.   if (options & REFRESH_STATUS)
  2575.     refresh_status();
  2576.   if (options & REFRESH_THREADS)
  2577.     flush_thread_cache();
  2578.   if (options & REFRESH_MASTER)
  2579.     reset_master();
  2580.   if (options & REFRESH_SLAVE)
  2581.     reset_slave();
  2582.   return result;
  2583. }
  2584. void kill_one_thread(THD *thd, ulong id)
  2585. {
  2586.   VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
  2587.   I_List_iterator<THD> it(threads);
  2588.   THD *tmp;
  2589.   uint error=ER_NO_SUCH_THREAD;
  2590.   while ((tmp=it++))
  2591.   {
  2592.     if (tmp->thread_id == id)
  2593.     {
  2594.       if ((thd->master_access & PROCESS_ACL) ||
  2595.   !strcmp(thd->user,tmp->user))
  2596.       {
  2597. tmp->prepare_to_die();
  2598. error=0;
  2599.       }
  2600.       else
  2601. error=ER_KILL_DENIED_ERROR;
  2602.       break; // Found thread
  2603.     }
  2604.   }
  2605.   VOID(pthread_mutex_unlock(&LOCK_thread_count));
  2606.   if (!error)
  2607.     send_ok(&thd->net);
  2608.   else
  2609.     net_printf(&thd->net,error,id);
  2610. }
  2611. /* Clear most status variables */
  2612. static void refresh_status(void)
  2613. {
  2614.   pthread_mutex_lock(&THR_LOCK_keycache);
  2615.   pthread_mutex_lock(&LOCK_status);
  2616.   for (struct show_var_st *ptr=status_vars; ptr->name; ptr++)
  2617.   {
  2618.     if (ptr->type == SHOW_LONG)
  2619.       *(ulong*) ptr->value=0;
  2620.   }
  2621.   pthread_mutex_unlock(&LOCK_status);
  2622.   pthread_mutex_unlock(&THR_LOCK_keycache);
  2623. }