List:Commits« Previous MessageNext Message »
From:Alexey Botchkov Date:November 3 2009 3:11am
Subject:bzr commit into mysql-5.5-next-mr-bugfixing branch (holyfoot:2936)
View as plain text  
#At file:///home/hf/work/mysql_common/41371/ based on revid:holyfoot@stripped

 2936 Alexey Botchkov	2009-11-03 [merge]
      merging

    modified:
      client/mysqlbinlog.cc
      client/mysqltest.cc
      include/violite.h
      mysql-test/lib/My/ConfigFactory.pm
      mysql-test/r/fulltext.result
      mysql-test/r/view.result
      mysql-test/t/named_pipe.test
      mysql-test/t/view.test
      sql-common/client.c
      sql/mysqld.cc
      sql/sql_lex.cc
      sql/sql_lex.h
      sql/sql_yacc.yy
      tests/mysql_client_test.c
      vio/vio.c
      vio/vio_priv.h
      vio/viosocket.c
=== modified file 'client/mysqlbinlog.cc'
--- a/client/mysqlbinlog.cc	2009-10-22 22:30:28 +0000
+++ b/client/mysqlbinlog.cc	2009-11-03 00:45:16 +0000
@@ -78,6 +78,9 @@ static const char* host = 0;
 static int port= 0;
 static uint my_end_arg;
 static const char* sock= 0;
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name= 0;
+#endif
 static const char* user = 0;
 static char* pass = 0;
 static char *charset= 0;
@@ -1077,6 +1080,12 @@ static struct my_option my_long_options[
   {"set-charset", OPT_SET_CHARSET,
    "Add 'SET NAMES character_set' to the output.", (uchar**) &charset,
    (uchar**) &charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SMEM
+  {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
+   "Base name of shared memory.", (uchar**) &shared_memory_base_name, 
+   (uchar**) &shared_memory_base_name, 
+   0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
   {"short-form", 's', "Just show regular queries: no extra info and no "
    "row-based events. This is for testing only, and should not be used in "
    "production systems. If you want to suppress base64-output, consider "
@@ -1378,6 +1387,11 @@ static Exit_status safe_connect()
 
   if (opt_protocol)
     mysql_options(mysql, MYSQL_OPT_PROTOCOL, (char*) &opt_protocol);
+#ifdef HAVE_SMEM
+  if (shared_memory_base_name)
+    mysql_options(mysql, MYSQL_SHARED_MEMORY_BASE_NAME,
+                  shared_memory_base_name);
+#endif
   if (!mysql_real_connect(mysql, host, user, pass, 0, port, sock, 0))
   {
     error("Failed on connect: %s", mysql_error(mysql));

=== modified file 'client/mysqltest.cc'
--- a/client/mysqltest.cc	2009-10-22 20:24:32 +0000
+++ b/client/mysqltest.cc	2009-11-03 00:45:16 +0000
@@ -81,6 +81,9 @@ enum {
 static int record= 0, opt_sleep= -1;
 static char *opt_db= 0, *opt_pass= 0;
 const char *opt_user= 0, *opt_host= 0, *unix_sock= 0, *opt_basedir= "./";
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name=0;
+#endif
 const char *opt_logdir= "";
 const char *opt_include= 0, *opt_charsets_dir;
 static int opt_port= 0;
@@ -4900,6 +4903,8 @@ do_handle_error:
   <opts> - options to use for the connection
    * SSL - use SSL if available
    * COMPRESS - use compression if available
+   * SHM - use shared memory if available
+   * PIPE - use named pipe if available
 
 */
 
@@ -4908,6 +4913,7 @@ void do_connect(struct st_command *comma
   int con_port= opt_port;
   char *con_options;
   my_bool con_ssl= 0, con_compress= 0;
+  my_bool con_pipe= 0, con_shm= 0;
   struct st_connection* con_slot;
 
   static DYNAMIC_STRING ds_connection_name;
@@ -4918,6 +4924,9 @@ void do_connect(struct st_command *comma
   static DYNAMIC_STRING ds_port;
   static DYNAMIC_STRING ds_sock;
   static DYNAMIC_STRING ds_options;
+#ifdef HAVE_SMEM
+  static DYNAMIC_STRING ds_shm;
+#endif
   const struct command_arg connect_args[] = {
     { "connection name", ARG_STRING, TRUE, &ds_connection_name, "Name of the connection" },
     { "host", ARG_STRING, TRUE, &ds_host, "Host to connect to" },
@@ -4945,6 +4954,11 @@ void do_connect(struct st_command *comma
       die("Illegal argument for port: '%s'", ds_port.str);
   }
 
+#ifdef HAVE_SMEM
+  /* Shared memory */
+  init_dynamic_string(&ds_shm, ds_sock.str, 0, 0);
+#endif
+
   /* Sock */
   if (ds_sock.length)
   {
@@ -4983,6 +4997,10 @@ void do_connect(struct st_command *comma
       con_ssl= 1;
     else if (!strncmp(con_options, "COMPRESS", 8))
       con_compress= 1;
+    else if (!strncmp(con_options, "PIPE", 4))
+      con_pipe= 1;
+    else if (!strncmp(con_options, "SHM", 3))
+      con_shm= 1;
     else
       die("Illegal option to connect: %.*s", 
           (int) (end - con_options), con_options);
@@ -5030,6 +5048,31 @@ void do_connect(struct st_command *comma
   }
 #endif
 
+#ifdef __WIN__
+  if (con_pipe)
+  {
+    uint protocol= MYSQL_PROTOCOL_PIPE;
+    mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol);
+  }
+#endif
+
+#ifdef HAVE_SMEM
+  if (con_shm)
+  {
+    uint protocol= MYSQL_PROTOCOL_MEMORY;
+    if (!ds_shm.length)
+      die("Missing shared memory base name");
+    mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME, ds_shm.str);
+    mysql_options(&con_slot->mysql, MYSQL_OPT_PROTOCOL, &protocol);
+  }
+  else if(shared_memory_base_name)
+  {
+    mysql_options(&con_slot->mysql, MYSQL_SHARED_MEMORY_BASE_NAME,
+      shared_memory_base_name);
+  }
+#endif
+
+
   /* Use default db name */
   if (ds_database.length == 0)
     dynstr_set(&ds_database, opt_db);
@@ -5062,6 +5105,9 @@ void do_connect(struct st_command *comma
   dynstr_free(&ds_port);
   dynstr_free(&ds_sock);
   dynstr_free(&ds_options);
+#ifdef HAVE_SMEM
+  dynstr_free(&ds_shm);
+#endif
   DBUG_VOID_RETURN;
 }
 
@@ -5728,6 +5774,12 @@ static struct my_option my_long_options[
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"server-file", 'F', "Read embedded server arguments from file.",
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifdef HAVE_SMEM
+  {"shared-memory-base-name", OPT_SHARED_MEMORY_BASE_NAME,
+   "Base name of shared memory.", (uchar**) &shared_memory_base_name, 
+   (uchar**) &shared_memory_base_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 
+   0, 0, 0},
+#endif
   {"silent", 's', "Suppress all normal output. Synonym for --quiet.",
    (uchar**) &silent, (uchar**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
@@ -7677,6 +7729,11 @@ int main(int argc, char **argv)
   }
 #endif
 
+#ifdef HAVE_SMEM
+  if (shared_memory_base_name)
+    mysql_options(&con->mysql,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name);
+#endif
+
   if (!(con->name = my_strdup("default", MYF(MY_WME))))
     die("Out of memory");
 

=== modified file 'include/violite.h'
--- a/include/violite.h	2009-07-23 11:53:28 +0000
+++ b/include/violite.h	2009-11-02 22:19:58 +0000
@@ -44,7 +44,7 @@ enum enum_vio_type
 Vio*	vio_new(my_socket sd, enum enum_vio_type type, uint flags);
 #ifdef __WIN__
 Vio* vio_new_win32pipe(HANDLE hPipe);
-Vio* vio_new_win32shared_memory(NET *net,HANDLE handle_file_map,
+Vio* vio_new_win32shared_memory(HANDLE handle_file_map,
                                 HANDLE handle_map,
                                 HANDLE event_server_wrote,
                                 HANDLE event_server_read,
@@ -221,7 +221,11 @@ struct st_vio
   HANDLE  event_conn_closed;
   size_t  shared_memory_remain;
   char    *shared_memory_pos;
-  NET     *net;
 #endif /* HAVE_SMEM */
+#ifdef _WIN32
+  OVERLAPPED pipe_overlapped;
+  DWORD read_timeout_millis;
+  DWORD write_timeout_millis;
+#endif
 };
 #endif /* vio_violite_h_ */

=== modified file 'mysql-test/lib/My/ConfigFactory.pm'
--- a/mysql-test/lib/My/ConfigFactory.pm	2009-10-15 12:23:43 +0000
+++ b/mysql-test/lib/My/ConfigFactory.pm	2009-11-03 00:45:16 +0000
@@ -7,6 +7,7 @@ use Carp;
 
 use My::Config;
 use My::Find;
+use My::Platform;
 
 use File::Basename;
 
@@ -218,7 +219,13 @@ my @mysqld_rules=
  { 'ssl-key' => \&fix_ssl_server_key },
   );
 
-
+if (IS_WINDOWS)
+{
+  # For simplicity, we use the same names for shared memory and 
+  # named pipes.
+  push(@mysqld_rules, {'shared-memory-base-name' => \&fix_socket});
+}
+ 
 sub fix_ndb_mgmd_port {
   my ($self, $config, $group_name, $group)= @_;
   my $hostname= $group->value('HostName');
@@ -347,6 +354,16 @@ sub post_check_client_group {
     }
     $config->insert($client_group_name, $name_to, $option->value())
   }
+  
+  if (IS_WINDOWS)
+  {
+    # Shared memory base may or may not be defined (e.g not defined in embedded)
+    my $shm = $group_to_copy_from->option("shared-memory-base-name");
+    if (defined $shm)
+    {
+      $config->insert($client_group_name,"shared-memory-base-name", $shm->value());
+    }
+  }
 }
 
 
@@ -393,6 +410,7 @@ sub post_check_embedded_group {
     (
      '#log-error', # Embedded server writes stderr to mysqltest's log file
      'slave-net-timeout', # Embedded server are not build with replication
+     'shared-memory-base-name', # No shared memory for embedded
     );
 
   foreach my $option ( $mysqld->options(), $first_mysqld->options() ) {

=== modified file 'mysql-test/r/fulltext.result'
--- a/mysql-test/r/fulltext.result	2009-10-19 13:13:45 +0000
+++ b/mysql-test/r/fulltext.result	2009-11-02 16:31:00 +0000
@@ -49,7 +49,7 @@ a	b
 Full-text indexes	are called collections
 Only MyISAM tables	support collections
 select * from t1 where MATCH(a,b) AGAINST ("indexes" IN BOOLEAN MODE WITH QUERY EXPANSION);
-ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WITH QUERY EXPANSION)' at line 1
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'QUERY EXPANSION)' at line 1
 explain select * from t1 where MATCH(a,b) AGAINST ("collections");
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	SIMPLE	t1	fulltext	a	a	0		1	Using where

=== modified file 'mysql-test/r/view.result'
--- a/mysql-test/r/view.result	2009-10-19 13:14:43 +0000
+++ b/mysql-test/r/view.result	2009-11-02 16:31:00 +0000
@@ -3958,3 +3958,16 @@ DROP TABLE t1;
 # -----------------------------------------------------------------
 # -- End of 5.1 tests.
 # -----------------------------------------------------------------
+drop table if exists t_9801;
+drop view if exists v_9801;
+create table t_9801 (s1 int);
+create view v_9801 as
+select sum(s1) from t_9801 with check option;
+ERROR HY000: CHECK OPTION on non-updatable view 'test.v_9801'
+create view v_9801 as
+select sum(s1) from t_9801 group by s1 with check option;
+ERROR HY000: CHECK OPTION on non-updatable view 'test.v_9801'
+create view v_9801 as
+select sum(s1) from t_9801 group by s1 with rollup with check option;
+ERROR HY000: CHECK OPTION on non-updatable view 'test.v_9801'
+drop table t_9801;

=== modified file 'mysql-test/t/named_pipe.test'
--- a/mysql-test/t/named_pipe.test	2007-09-24 10:42:44 +0000
+++ b/mysql-test/t/named_pipe.test	2009-11-03 00:19:37 +0000
@@ -9,6 +9,11 @@ if (`SELECT '$nmp' != 'ON'`){
   skip No named pipe support;
 }
 
+# Connect using named pipe for testing
+connect(pipe_con,localhost,root,,,,,PIPE);
+
 # Source select test case
 -- source include/common-tests.inc
 
+connection default;
+disconnect pipe_con;

=== modified file 'mysql-test/t/view.test'
--- a/mysql-test/t/view.test	2009-09-16 06:55:17 +0000
+++ b/mysql-test/t/view.test	2009-11-02 16:31:00 +0000
@@ -3905,3 +3905,29 @@ DROP TABLE t1;
 --echo # -----------------------------------------------------------------
 --echo # -- End of 5.1 tests.
 --echo # -----------------------------------------------------------------
+
+#
+# Bug#9801 (Views: imperfect error message)
+#
+
+--disable_warnings
+drop table if exists t_9801;
+drop view if exists v_9801;
+--enable_warnings
+
+create table t_9801 (s1 int);
+
+--error ER_VIEW_NONUPD_CHECK
+create view v_9801 as
+  select sum(s1) from t_9801 with check option;
+
+--error ER_VIEW_NONUPD_CHECK
+create view v_9801 as
+  select sum(s1) from t_9801 group by s1 with check option;
+
+ --error ER_VIEW_NONUPD_CHECK
+create view v_9801 as
+  select sum(s1) from t_9801 group by s1 with rollup with check option;
+
+drop table t_9801;
+

=== modified file 'sql-common/client.c'
--- a/sql-common/client.c	2009-10-27 09:57:44 +0000
+++ b/sql-common/client.c	2009-11-02 22:24:24 +0000
@@ -426,7 +426,7 @@ HANDLE create_named_pipe(MYSQL *mysql, u
 			    0,
 			    NULL,
 			    OPEN_EXISTING,
-			    0,
+			    FILE_FLAG_OVERLAPPED,
 			    NULL )) != INVALID_HANDLE_VALUE)
       break;
     if (GetLastError() != ERROR_PIPE_BUSY)
@@ -660,7 +660,7 @@ HANDLE create_shared_memory(MYSQL *mysql
 err2:
   if (error_allow == 0)
   {
-    net->vio= vio_new_win32shared_memory(net,handle_file_map,handle_map,
+    net->vio= vio_new_win32shared_memory(handle_file_map,handle_map,
                                          event_server_wrote,
                                          event_server_read,event_client_wrote,
                                          event_client_read,event_conn_closed);
@@ -2315,7 +2315,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,cons
     }
     else
     {
-      net->vio=vio_new_win32pipe(hPipe);
+      net->vio= vio_new_win32pipe(hPipe);
       my_snprintf(host_info=buff, sizeof(buff)-1,
                   ER(CR_NAMEDPIPE_CONNECTION), unix_socket);
     }

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2009-11-03 03:06:47 +0000
+++ b/sql/mysqld.cc	2009-11-03 03:11:19 +0000
@@ -1739,7 +1739,7 @@ static void network_init(void)
     saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
     saPipeSecurity.bInheritHandle = FALSE;
     if ((hPipe= CreateNamedPipe(pipe_name,
-				PIPE_ACCESS_DUPLEX,
+				PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
 				PIPE_TYPE_BYTE |
 				PIPE_READMODE_BYTE |
 				PIPE_WAIT,
@@ -5232,17 +5232,26 @@ pthread_handler_t handle_connections_soc
 pthread_handler_t handle_connections_namedpipes(void *arg)
 {
   HANDLE hConnectedPipe;
-  BOOL fConnected;
+  OVERLAPPED connectOverlapped = {0};
   THD *thd;
   my_thread_init();
   DBUG_ENTER("handle_connections_namedpipes");
-  (void) my_pthread_getprio(pthread_self());		// For debugging
+  connectOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
 
   DBUG_PRINT("general",("Waiting for named pipe connections."));
   while (!abort_loop)
   {
     /* wait for named pipe connection */
-    fConnected = ConnectNamedPipe(hPipe, NULL);
+    BOOL fConnected= ConnectNamedPipe(hPipe, &connectOverlapped);
+    if (!fConnected && (GetLastError() == ERROR_IO_PENDING))
+    {
+        /*
+          ERROR_IO_PENDING says async IO has started but not yet finished.
+          GetOverlappedResult will wait for completion.
+        */
+        DWORD bytes;
+        fConnected= GetOverlappedResult(hPipe, &connectOverlapped,&bytes, TRUE);
+    }
     if (abort_loop)
       break;
     if (!fConnected)
@@ -5251,7 +5260,7 @@ pthread_handler_t handle_connections_nam
     {
       CloseHandle(hPipe);
       if ((hPipe= CreateNamedPipe(pipe_name,
-                                  PIPE_ACCESS_DUPLEX,
+                                  PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
                                   PIPE_TYPE_BYTE |
                                   PIPE_READMODE_BYTE |
                                   PIPE_WAIT,
@@ -5271,7 +5280,7 @@ pthread_handler_t handle_connections_nam
     hConnectedPipe = hPipe;
     /* create new pipe for new connection */
     if ((hPipe = CreateNamedPipe(pipe_name,
-				 PIPE_ACCESS_DUPLEX,
+				 PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
 				 PIPE_TYPE_BYTE |
 				 PIPE_READMODE_BYTE |
 				 PIPE_WAIT,
@@ -5293,7 +5302,7 @@ pthread_handler_t handle_connections_nam
       CloseHandle(hConnectedPipe);
       continue;
     }
-    if (!(thd->net.vio = vio_new_win32pipe(hConnectedPipe)) ||
+    if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) ||
 	my_net_init(&thd->net, thd->net.vio))
     {
       close_connection(thd, ER_OUT_OF_RESOURCES, 1);
@@ -5304,7 +5313,7 @@ pthread_handler_t handle_connections_nam
     thd->security_ctx->host= my_strdup(my_localhost, MYF(0));
     create_new_thread(thd);
   }
-
+  CloseHandle(connectOverlapped.hEvent);
   decrement_handler_count();
   DBUG_RETURN(0);
 }
@@ -5481,8 +5490,7 @@ pthread_handler_t handle_connections_sha
       errmsg= "Could not set client to read mode";
       goto errorconn;
     }
-    if (!(thd->net.vio= vio_new_win32shared_memory(&thd->net,
-                                                   handle_client_file_map,
+    if (!(thd->net.vio= vio_new_win32shared_memory(handle_client_file_map,
                                                    handle_client_map,
                                                    event_client_wrote,
                                                    event_client_read,

=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc	2009-09-17 15:25:52 +0000
+++ b/sql/sql_lex.cc	2009-11-02 16:31:00 +0000
@@ -24,6 +24,8 @@
 #include "sp.h"
 #include "sp_head.h"
 
+static int lex_one_token(void *arg, void *yythd);
+
 /*
   We are using pointer to this variable for distinguishing between assignment
   to NEW row field (when parsing trigger definition) and structured variable.
@@ -117,6 +119,8 @@ Lex_input_stream::Lex_input_stream(THD *
   yylineno(1),
   yytoklen(0),
   yylval(NULL),
+  lookahead_token(-1),
+  lookahead_yylval(NULL),
   m_ptr(buffer),
   m_tok_start(NULL),
   m_tok_end(NULL),
@@ -780,6 +784,60 @@ bool consume_comment(Lex_input_stream *l
 
 int MYSQLlex(void *arg, void *yythd)
 {
+  THD *thd= (THD *)yythd;
+  Lex_input_stream *lip= & thd->m_parser_state->m_lip;
+  YYSTYPE *yylval=(YYSTYPE*) arg;
+  int token;
+
+  if (lip->lookahead_token >= 0)
+  {
+    /*
+      The next token was already parsed in advance,
+      return it.
+    */
+    token= lip->lookahead_token;
+    lip->lookahead_token= -1;
+    *yylval= *(lip->lookahead_yylval);
+    lip->lookahead_yylval= NULL;
+    return token;
+  }
+
+  token= lex_one_token(arg, yythd);
+
+  switch(token) {
+  case WITH:
+    /*
+      Parsing 'WITH' 'ROLLUP' or 'WITH' 'CUBE' requires 2 look ups,
+      which makes the grammar LALR(2).
+      Replace by a single 'WITH_ROLLUP' or 'WITH_CUBE' token,
+      to transform the grammar into a LALR(1) grammar,
+      which sql_yacc.yy can process.
+    */
+    token= lex_one_token(arg, yythd);
+    switch(token) {
+    case CUBE_SYM:
+      return WITH_CUBE_SYM;
+    case ROLLUP_SYM:
+      return WITH_ROLLUP_SYM;
+    default:
+      /*
+        Save the token following 'WITH'
+      */
+      lip->lookahead_yylval= lip->yylval;
+      lip->yylval= NULL;
+      lip->lookahead_token= token;
+      return WITH;
+    }
+    break;
+  default:
+    break;
+  }
+
+  return token;
+}
+
+int lex_one_token(void *arg, void *yythd)
+{
   reg1	uchar c= 0;
   bool comment_closed;
   int	tokval, result_state;

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2009-10-27 09:59:09 +0000
+++ b/sql/sql_lex.h	2009-11-02 16:31:00 +0000
@@ -1411,6 +1411,17 @@ public:
   /** Interface with bison, value of the last token parsed. */
   LEX_YYSTYPE yylval;
 
+  /**
+    LALR(2) resolution, look ahead token.
+    Value of the next token to return, if any,
+    or -1, if no token was parsed in advance.
+    Note: 0 is a legal token, and represents YYEOF.
+  */
+  int lookahead_token;
+
+  /** LALR(2) resolution, value of the look ahead token.*/
+  LEX_YYSTYPE lookahead_yylval;
+
 private:
   /** Pointer to the current position in the raw input stream. */
   const char *m_ptr;

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2009-10-29 16:51:04 +0000
+++ b/sql/sql_yacc.yy	2009-11-02 16:31:00 +0000
@@ -521,10 +521,10 @@ bool my_yyoverflow(short **a, YYSTYPE **
 
 %pure_parser                                    /* We have threads */
 /*
-  Currently there are 169 shift/reduce conflicts.
+  Currently there are 168 shift/reduce conflicts.
   We should not introduce new conflicts any more.
 */
-%expect 169
+%expect 168
 
 /*
    Comments for TOKENS.
@@ -1118,6 +1118,8 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  WHERE                         /* SQL-2003-R */
 %token  WHILE_SYM
 %token  WITH                          /* SQL-2003-R */
+%token  WITH_CUBE_SYM                 /* INTERNAL */
+%token  WITH_ROLLUP_SYM               /* INTERNAL */
 %token  WORK_SYM                      /* SQL-2003-N */
 %token  WRAPPER_SYM
 %token  WRITE_SYM                     /* SQL-2003-N */
@@ -9153,8 +9155,15 @@ group_list:
 
 olap_opt:
           /* empty */ {}
-        | WITH CUBE_SYM
+        | WITH_CUBE_SYM
           {
+            /*
+              'WITH CUBE' is reserved in the MySQL syntax, but not implemented,
+              and cause LALR(2) conflicts.
+              This syntax is not standard.
+              MySQL syntax: GROUP BY col1, col2, col3 WITH CUBE
+              SQL-2003: GROUP BY ... CUBE(col1, col2, col3)
+            */
             LEX *lex=Lex;
             if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
             {
@@ -9164,10 +9173,17 @@ olap_opt:
             }
             lex->current_select->olap= CUBE_TYPE;
             my_error(ER_NOT_SUPPORTED_YET, MYF(0), "CUBE");
-            MYSQL_YYABORT; /* To be deleted in 5.1 */
+            MYSQL_YYABORT;
           }
-        | WITH ROLLUP_SYM
+        | WITH_ROLLUP_SYM
           {
+            /*
+              'WITH ROLLUP' is needed for backward compatibility,
+              and cause LALR(2) conflicts.
+              This syntax is not standard.
+              MySQL syntax: GROUP BY col1, col2, col3 WITH ROLLUP
+              SQL-2003: GROUP BY ... ROLLUP(col1, col2, col3)
+            */
             LEX *lex= Lex;
             if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
             {

=== modified file 'tests/mysql_client_test.c'
--- a/tests/mysql_client_test.c	2009-10-23 09:19:54 +0000
+++ b/tests/mysql_client_test.c	2009-11-03 00:45:16 +0000
@@ -46,6 +46,9 @@ static char *opt_user= 0;
 static char *opt_password= 0;
 static char *opt_host= 0;
 static char *opt_unix_socket= 0;
+#ifdef HAVE_SMEM
+static char *shared_memory_base_name= 0;
+#endif
 static unsigned int  opt_port;
 static my_bool tty_password= 0, opt_silent= 0;
 
@@ -230,6 +233,26 @@ static void print_st_error(MYSQL_STMT *s
   }
 }
 
+/*
+  Enhanced version of mysql_client_init(), which may also set shared memory 
+  base on Windows.
+*/
+static MYSQL *mysql_client_init(MYSQL* con)
+{
+  MYSQL* res = mysql_init(con);
+#ifdef HAVE_SMEM
+  if (res && shared_memory_base_name)
+    mysql_options(res, MYSQL_SHARED_MEMORY_BASE_NAME, shared_memory_base_name);
+#endif
+  return res;
+}
+
+/*
+  Disable direct calls of mysql_init, as it disregards  shared memory base.
+*/
+#define mysql_init(A) Please use mysql_client_init instead of mysql_init
+
+
 /* Check if the connection has InnoDB tables */
 
 static my_bool check_have_innodb(MYSQL *conn)
@@ -293,10 +316,10 @@ static MYSQL* client_connect(ulong flag,
     fprintf(stdout, "\n Establishing a connection to '%s' ...",
             opt_host ? opt_host : "");
 
-  if (!(mysql= mysql_init(NULL)))
+  if (!(mysql= mysql_client_init(NULL)))
   {
     opt_silent= 0;
-    myerror("mysql_init() failed");
+    myerror("mysql_client_init() failed");
     exit(1);
   }
   /* enable local infile, in non-binary builds often disabled by default */
@@ -1160,9 +1183,9 @@ static my_bool thread_query(char *query)
   error= 0;
   if (!opt_silent)
     fprintf(stdout, "\n in thread_query(%s)", query);
-  if (!(l_mysql= mysql_init(NULL)))
+  if (!(l_mysql= mysql_client_init(NULL)))
   {
-    myerror("mysql_init() failed");
+    myerror("mysql_client_init() failed");
     return 1;
   }
   if (!(mysql_real_connect(l_mysql, opt_host, opt_user,
@@ -2512,9 +2535,9 @@ static void test_ps_query_cache()
     case TEST_QCACHE_ON_WITH_OTHER_CONN:
       if (!opt_silent)
         fprintf(stdout, "\n Establishing a test connection ...");
-      if (!(lmysql= mysql_init(NULL)))
+      if (!(lmysql= mysql_client_init(NULL)))
       {
-        printf("mysql_init() failed");
+        printf("mysql_client_init() failed");
         DIE_UNLESS(0);
       }
       if (!(mysql_real_connect(lmysql, opt_host, opt_user,
@@ -4960,9 +4983,9 @@ static void test_stmt_close()
 
   if (!opt_silent)
     fprintf(stdout, "\n Establishing a test connection ...");
-  if (!(lmysql= mysql_init(NULL)))
+  if (!(lmysql= mysql_client_init(NULL)))
   {
-    myerror("mysql_init() failed");
+    myerror("mysql_client_init() failed");
     exit(1);
   }
   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
@@ -5851,9 +5874,9 @@ DROP TABLE IF EXISTS test_multi_tab";
   rc= mysql_more_results(mysql);
   DIE_UNLESS(rc == 0);
 
-  if (!(mysql_local= mysql_init(NULL)))
+  if (!(mysql_local= mysql_client_init(NULL)))
   {
-    fprintf(stdout, "\n mysql_init() failed");
+    fprintf(stdout, "\n mysql_client_init() failed");
     exit(1);
   }
 
@@ -5976,9 +5999,9 @@ static void test_prepare_multi_statement
   char query[MAX_TEST_QUERY_LENGTH];
   myheader("test_prepare_multi_statements");
 
-  if (!(mysql_local= mysql_init(NULL)))
+  if (!(mysql_local= mysql_client_init(NULL)))
   {
-    fprintf(stderr, "\n mysql_init() failed");
+    fprintf(stderr, "\n mysql_client_init() failed");
     exit(1);
   }
 
@@ -7459,9 +7482,9 @@ static void test_prepare_grant()
 
     if (!opt_silent)
       fprintf(stdout, "\n Establishing a test connection ...");
-    if (!(lmysql= mysql_init(NULL)))
+    if (!(lmysql= mysql_client_init(NULL)))
     {
-      myerror("mysql_init() failed");
+      myerror("mysql_client_init() failed");
       exit(1);
     }
     if (!(mysql_real_connect(lmysql, opt_host, "test_grant",
@@ -7915,9 +7938,9 @@ static void test_drop_temp()
 
     if (!opt_silent)
       fprintf(stdout, "\n Establishing a test connection ...");
-    if (!(lmysql= mysql_init(NULL)))
+    if (!(lmysql= mysql_client_init(NULL)))
     {
-      myerror("mysql_init() failed");
+      myerror("mysql_client_init() failed");
       exit(1);
     }
 
@@ -13159,7 +13182,7 @@ static void test_bug15518()
   int rc;
   myheader("test_bug15518");
 
-  mysql1= mysql_init(NULL);
+  mysql1= mysql_client_init(NULL);
 
   if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
                           opt_db ? opt_db : "test", opt_port, opt_unix_socket,
@@ -13315,9 +13338,9 @@ static void test_bug8378()
 
   if (!opt_silent)
     fprintf(stdout, "\n Establishing a test connection ...");
-  if (!(lmysql= mysql_init(NULL)))
+  if (!(lmysql= mysql_client_init(NULL)))
   {
-    myerror("mysql_init() failed");
+    myerror("mysql_client_init() failed");
     exit(1);
   }
   if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk"))
@@ -13856,7 +13879,7 @@ static void test_bug9992()
   if (!opt_silent)
     printf("Establishing a connection with option CLIENT_MULTI_STATEMENTS..\n");
 
-  mysql1= mysql_init(NULL);
+  mysql1= mysql_client_init(NULL);
 
   if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
                           opt_db ? opt_db : "test", opt_port, opt_unix_socket,
@@ -14445,9 +14468,9 @@ static void test_bug12001()
 
   myheader("test_bug12001");
 
-  if (!(mysql_local= mysql_init(NULL)))
+  if (!(mysql_local= mysql_client_init(NULL)))
   {
-    fprintf(stdout, "\n mysql_init() failed");
+    fprintf(stdout, "\n mysql_client_init() failed");
     exit(1);
   }
 
@@ -15172,9 +15195,9 @@ static void test_opt_reconnect()
 
   myheader("test_opt_reconnect");
 
-  if (!(lmysql= mysql_init(NULL)))
+  if (!(lmysql= mysql_client_init(NULL)))
   {
-    myerror("mysql_init() failed");
+    myerror("mysql_client_init() failed");
     exit(1);
   }
 
@@ -15209,9 +15232,9 @@ static void test_opt_reconnect()
 
   mysql_close(lmysql);
 
-  if (!(lmysql= mysql_init(NULL)))
+  if (!(lmysql= mysql_client_init(NULL)))
   {
-    myerror("mysql_init() failed");
+    myerror("mysql_client_init() failed");
     DIE_UNLESS(0);
   }
 
@@ -15246,7 +15269,7 @@ static void test_bug12744()
   int rc;
   myheader("test_bug12744");
 
-  lmysql= mysql_init(NULL);
+  lmysql= mysql_client_init(NULL);
   DIE_UNLESS(lmysql);
 
   if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
@@ -15819,7 +15842,7 @@ static void test_bug15752()
   rc= mysql_query(mysql, "create procedure p1() select 1");
   myquery(rc);
 
-  mysql_init(&mysql_local);
+  mysql_client_init(&mysql_local);
   if (! mysql_real_connect(&mysql_local, opt_host, opt_user,
                            opt_password, current_db, opt_port,
                            opt_unix_socket,
@@ -16705,7 +16728,7 @@ static void test_bug29692()
 {
   MYSQL* conn;
 
-  if (!(conn= mysql_init(NULL)))
+  if (!(conn= mysql_client_init(NULL)))
   {
     myerror("test_bug29692 init failed");
     exit(1);
@@ -16840,7 +16863,7 @@ static void test_bug30472()
 
   /* Create a new connection. */
 
-  DIE_UNLESS(mysql_init(&con));
+  DIE_UNLESS(mysql_client_init(&con));
 
   DIE_UNLESS(mysql_real_connect(&con,
                                 opt_host,
@@ -17014,7 +17037,7 @@ static void test_bug20023()
 
   /* Create a new connection. */
 
-  DIE_UNLESS(mysql_init(&con));
+  DIE_UNLESS(mysql_client_init(&con));
 
   DIE_UNLESS(mysql_real_connect(&con,
                                 opt_host,
@@ -17151,7 +17174,7 @@ static void bug31418_impl()
 
   /* Create a new connection. */
 
-  DIE_UNLESS(mysql_init(&con));
+  DIE_UNLESS(mysql_client_init(&con));
 
   DIE_UNLESS(mysql_real_connect(&con,
                                 opt_host,
@@ -18001,7 +18024,7 @@ static void test_bug44495()
                          "END;");
   myquery(rc);
 
-  DIE_UNLESS(mysql_init(&con));
+  DIE_UNLESS(mysql_client_init(&con));
 
   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
                                 current_db, opt_port, opt_unix_socket,
@@ -18064,6 +18087,11 @@ static struct my_option client_test_long
    0, 0, 0, 0, 0, 0},
   {"silent", 's', "Be more silent", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0,
    0},
+#ifdef HAVE_SMEM
+  {"shared-memory-base-name", 'm', "Base name of shared memory.", 
+  (uchar**) &shared_memory_base_name, (uchar**)&shared_memory_base_name, 0, 
+  GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#endif
   {"socket", 'S', "Socket file to use for connection",
    (uchar **) &opt_unix_socket, (uchar **) &opt_unix_socket, 0, GET_STR,
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},

=== modified file 'vio/vio.c'
--- a/vio/vio.c	2007-05-10 09:59:39 +0000
+++ b/vio/vio.c	2009-11-02 22:19:58 +0000
@@ -43,7 +43,7 @@ static void vio_init(Vio* vio, enum enum
   if ((flags & VIO_BUFFERED_READ) &&
       !(vio->read_buffer= (char*)my_malloc(VIO_READ_BUFFER_SIZE, MYF(MY_WME))))
     flags&= ~VIO_BUFFERED_READ;
-#ifdef __WIN__ 
+#ifdef _WIN32
   if (type == VIO_TYPE_NAMEDPIPE)
   {
     vio->viodelete	=vio_delete;
@@ -59,9 +59,16 @@ static void vio_init(Vio* vio, enum enum
     vio->in_addr	=vio_in_addr;
     vio->vioblocking	=vio_blocking;
     vio->is_blocking	=vio_is_blocking;
-    vio->timeout	=vio_ignore_timeout;
+
+    vio->timeout=vio_win32_timeout;
+    /* Set default timeout */
+    vio->read_timeout_millis = INFINITE;
+    vio->write_timeout_millis = INFINITE;
+
+    memset(&(vio->pipe_overlapped), 0, sizeof(OVERLAPPED));
+    vio->pipe_overlapped.hEvent= CreateEvent(NULL, TRUE, FALSE, NULL);
+    DBUG_VOID_RETURN;
   }
-  else					/* default is VIO_TYPE_TCPIP */
 #endif
 #ifdef HAVE_SMEM 
   if (type == VIO_TYPE_SHARED_MEMORY)
@@ -79,9 +86,14 @@ static void vio_init(Vio* vio, enum enum
     vio->in_addr	=vio_in_addr;
     vio->vioblocking	=vio_blocking;
     vio->is_blocking	=vio_is_blocking;
-    vio->timeout	=vio_ignore_timeout;
+
+    /* Currently, shared memory is on Windows only, hence the below is ok*/
+    vio->timeout= vio_win32_timeout; 
+    /* Set default timeout */
+    vio->read_timeout_millis= INFINITE;
+    vio->write_timeout_millis= INFINITE;
+    DBUG_VOID_RETURN;
   }
-  else
 #endif   
 #ifdef HAVE_OPENSSL 
   if (type == VIO_TYPE_SSL)
@@ -100,8 +112,8 @@ static void vio_init(Vio* vio, enum enum
     vio->vioblocking	=vio_ssl_blocking;
     vio->is_blocking	=vio_is_blocking;
     vio->timeout	=vio_timeout;
+    DBUG_VOID_RETURN;
   }
-  else					/* default is VIO_TYPE_TCPIP */
 #endif /* HAVE_OPENSSL */
   {
     vio->viodelete	=vio_delete;
@@ -193,7 +205,7 @@ Vio *vio_new_win32pipe(HANDLE hPipe)
 }
 
 #ifdef HAVE_SMEM
-Vio *vio_new_win32shared_memory(NET *net,HANDLE handle_file_map, HANDLE handle_map,
+Vio *vio_new_win32shared_memory(HANDLE handle_file_map, HANDLE handle_map,
                                 HANDLE event_server_wrote, HANDLE event_server_read,
                                 HANDLE event_client_wrote, HANDLE event_client_read,
                                 HANDLE event_conn_closed)
@@ -212,7 +224,6 @@ Vio *vio_new_win32shared_memory(NET *net
     vio->event_conn_closed= event_conn_closed;
     vio->shared_memory_remain= 0;
     vio->shared_memory_pos= handle_map;
-    vio->net= net;
     strmov(vio->desc, "shared memory");
   }
   DBUG_RETURN(vio);

=== modified file 'vio/vio_priv.h'
--- a/vio/vio_priv.h	2009-09-23 21:32:31 +0000
+++ b/vio/vio_priv.h	2009-11-02 22:24:24 +0000
@@ -25,7 +25,10 @@
 #include <m_string.h>
 #include <violite.h>
 
-void	vio_ignore_timeout(Vio *vio, uint which, uint timeout);
+#ifdef _WIN32
+void	vio_win32_timeout(Vio *vio, uint which, uint timeout);
+#endif
+
 void	vio_timeout(Vio *vio,uint which, uint timeout);
 
 #ifdef HAVE_OPENSSL

=== modified file 'vio/viosocket.c'
--- a/vio/viosocket.c	2009-09-30 20:10:22 +0000
+++ b/vio/viosocket.c	2009-11-02 22:24:24 +0000
@@ -261,19 +261,13 @@ int vio_close(Vio * vio)
 {
   int r=0;
   DBUG_ENTER("vio_close");
-#ifdef __WIN__
-  if (vio->type == VIO_TYPE_NAMEDPIPE)
-  {
-#if defined(MYSQL_SERVER)
-    CancelIo(vio->hPipe);
-    DisconnectNamedPipe(vio->hPipe);
-#endif
-    r=CloseHandle(vio->hPipe);
-  }
-  else
-#endif /* __WIN__ */
+
  if (vio->type != VIO_CLOSED)
   {
+    DBUG_ASSERT(vio->type ==  VIO_TYPE_TCPIP ||
+      vio->type == VIO_TYPE_SOCKET ||
+      vio->type == VIO_TYPE_SSL);
+
     DBUG_ASSERT(vio->sd >= 0);
     if (shutdown(vio->sd, SHUT_RDWR))
       r= -1;
@@ -417,44 +411,98 @@ void vio_timeout(Vio *vio, uint which, u
 
 
 #ifdef __WIN__
-size_t vio_read_pipe(Vio * vio, uchar* buf, size_t size)
+
+/*
+  Finish pending IO on pipe. Honor wait timeout
+*/
+static int pipe_complete_io(Vio* vio, char* buf, size_t size, DWORD timeout_millis)
 {
   DWORD length;
+  DWORD ret;
+
+  DBUG_ENTER("pipe_complete_io");
+
+  ret= WaitForSingleObject(vio->pipe_overlapped.hEvent, timeout_millis);
+  /*
+    WaitForSingleObjects will normally return WAIT_OBJECT_O (success, IO completed)
+    or WAIT_TIMEOUT.
+  */
+  if(ret != WAIT_OBJECT_0)
+  {
+    CancelIo(vio->hPipe);
+    DBUG_PRINT("error",("WaitForSingleObject() returned  %d", ret));
+    DBUG_RETURN(-1);
+  }
+
+  if (!GetOverlappedResult(vio->hPipe,&(vio->pipe_overlapped),&length, FALSE))
+  {
+    DBUG_PRINT("error",("GetOverlappedResult() returned last error  %d", 
+      GetLastError()));
+    DBUG_RETURN(-1);
+  }
+
+  DBUG_RETURN(length);
+}
+
+
+size_t vio_read_pipe(Vio * vio, uchar *buf, size_t size)
+{
+  DWORD bytes_read;
   DBUG_ENTER("vio_read_pipe");
   DBUG_PRINT("enter", ("sd: %d  buf: 0x%lx  size: %u", vio->sd, (long) buf,
                        (uint) size));
 
-  if (!ReadFile(vio->hPipe, buf, size, &length, NULL))
-    DBUG_RETURN(-1);
+  if (!ReadFile(vio->hPipe, buf, (DWORD)size, &bytes_read,
+      &(vio->pipe_overlapped)))
+  {
+    if (GetLastError() != ERROR_IO_PENDING)
+    {
+      DBUG_PRINT("error",("ReadFile() returned last error %d",
+        GetLastError()));
+      DBUG_RETURN((size_t)-1);
+    }
+    bytes_read= pipe_complete_io(vio, buf, size,vio->read_timeout_millis);
+  }
 
-  DBUG_PRINT("exit", ("%d", length));
-  DBUG_RETURN((size_t) length);
+  DBUG_PRINT("exit", ("%d", bytes_read));
+  DBUG_RETURN(bytes_read);
 }
 
 
 size_t vio_write_pipe(Vio * vio, const uchar* buf, size_t size)
 {
-  DWORD length;
+  DWORD bytes_written;
   DBUG_ENTER("vio_write_pipe");
   DBUG_PRINT("enter", ("sd: %d  buf: 0x%lx  size: %u", vio->sd, (long) buf,
                        (uint) size));
 
-  if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL))
-    DBUG_RETURN(-1);
+  if (!WriteFile(vio->hPipe, buf, (DWORD)size, &bytes_written,
+      &(vio->pipe_overlapped)))
+  {
+    if (GetLastError() != ERROR_IO_PENDING)
+    {
+      DBUG_PRINT("vio_error",("WriteFile() returned last error %d",
+        GetLastError()));
+      DBUG_RETURN((size_t)-1);
+    }
+    bytes_written = pipe_complete_io(vio, (char *)buf, size, 
+        vio->write_timeout_millis);
+  }
 
-  DBUG_PRINT("exit", ("%d", length));
-  DBUG_RETURN((size_t) length);
+  DBUG_PRINT("exit", ("%d", bytes_written));
+  DBUG_RETURN(bytes_written);
 }
 
+
 int vio_close_pipe(Vio * vio)
 {
   int r;
   DBUG_ENTER("vio_close_pipe");
-#if defined(MYSQL_SERVER)
+
   CancelIo(vio->hPipe);
+  CloseHandle(vio->pipe_overlapped.hEvent);
   DisconnectNamedPipe(vio->hPipe);
-#endif
-  r=CloseHandle(vio->hPipe);
+  r= CloseHandle(vio->hPipe);
   if (r)
   {
     DBUG_PRINT("vio_error", ("close() failed, error: %d",GetLastError()));
@@ -466,10 +514,23 @@ int vio_close_pipe(Vio * vio)
 }
 
 
-void vio_ignore_timeout(Vio *vio __attribute__((unused)),
-			uint which __attribute__((unused)),
-			uint timeout __attribute__((unused)))
+void vio_win32_timeout(Vio *vio, uint which , uint timeout_sec)
 {
+    DWORD timeout_millis;
+    /*
+      Windows is measuring timeouts in milliseconds. Check for possible int 
+      overflow.
+    */
+    if (timeout_sec > UINT_MAX/1000)
+      timeout_millis= INFINITE;
+    else
+      timeout_millis= timeout_sec * 1000;
+
+    /* which == 1 means "write", which == 0 means "read".*/
+    if(which)
+      vio->write_timeout_millis= timeout_millis;
+    else
+      vio->read_timeout_millis= timeout_millis;
 }
 
 
@@ -504,7 +565,7 @@ size_t vio_read_shared_memory(Vio * vio,
          WAIT_ABANDONED_0 and WAIT_TIMEOUT - fail.  We can't read anything
       */
       if (WaitForMultipleObjects(array_elements(events), events, FALSE,
-                                 vio->net->read_timeout*1000) != WAIT_OBJECT_0)
+                                 vio->read_timeout_millis) != WAIT_OBJECT_0)
       {
         DBUG_RETURN(-1);
       };
@@ -561,7 +622,7 @@ size_t vio_write_shared_memory(Vio * vio
   while (remain != 0)
   {
     if (WaitForMultipleObjects(array_elements(events), events, FALSE,
-                               vio->net->write_timeout*1000) != WAIT_OBJECT_0)
+                               vio->write_timeout_millis) != WAIT_OBJECT_0)
     {
       DBUG_RETURN((size_t) -1);
     }


Attachment: [text/bzr-bundle] bzr/holyfoot@mysql.com-20091103031119-ecukn13m51bwisfv.bundle
Thread
bzr commit into mysql-5.5-next-mr-bugfixing branch (holyfoot:2936)Alexey Botchkov3 Nov