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

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