List:Commits« Previous MessageNext Message »
From:Davi Arnaut Date:December 10 2007 2:34pm
Subject:bk commit into 5.1 tree (davi:1.2680) BUG#28317
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of davi. When davi does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-12-10 11:34:12-02:00, davi@stripped +7 -0
  Bug#28317 Left Outer Join with {oj outer-join}
  
  Parser rejects ODBC's escape sequences for outer joins other than
  left outer join, yet the escape sequence BNF specifies that this
  syntax can be used for left, right, and full outer join syntax.
  
  The problem is that although the MySQL Connector/ODBC advertises
  "Outer Join Escape Sequence" capabilities, the parsing is done in
  the server and historically it only supported this syntax for left
  outer joins and applications such as Crystal Reports 11 tries to
  use this syntax for inner joins.
  
  The OJ (Outer Join) escape sequence should be handled and translated
  by the Connector/ODBC before sending the query to the server, but
  since historically this has been carried out by the server, the chosen
  solution is to remove the OJ escape sequence in the preprocessor so that
  it's not seen by the parser. Removing the OJ escape sequence is harmless
  because the various SQL join clauses are supported by the server.

  include/m_ctype.h@stripped, 2007-12-10 11:34:09-02:00, davi@stripped +1 -0
    Introduce Lex flag for the OJ escape sequence.

  mysql-test/r/parser.result@stripped, 2007-12-10 11:34:09-02:00, davi@stripped +13 -0
    Add test case result for Bug#28317

  mysql-test/t/parser.test@stripped, 2007-12-10 11:34:09-02:00, davi@stripped +16 -0
    Add test case for Bug#28317

  mysys/charset.c@stripped, 2007-12-10 11:34:10-02:00, davi@stripped +1 -0
    Map the curly brackets to the OJ Lex flag.

  sql/sql_lex.cc@stripped, 2007-12-10 11:34:10-02:00, davi@stripped +24 -7
    Skip the ODBC OJ (Outer Join) escape sequence.

  sql/sql_lex.h@stripped, 2007-12-10 11:34:10-02:00, davi@stripped +21 -1
    Introduce helper function and flag for the OJES.

  sql/sql_yacc.yy@stripped, 2007-12-10 11:34:10-02:00, davi@stripped +2 -21
    Remove grammar rule for the ODBC OJES, it's not needed anymore.

diff -Nrup a/include/m_ctype.h b/include/m_ctype.h
--- a/include/m_ctype.h	2007-08-13 16:39:23 -03:00
+++ b/include/m_ctype.h	2007-12-10 11:34:09 -02:00
@@ -122,6 +122,7 @@ enum my_lex_states
   MY_LEX_USER_VARIABLE_DELIMITER, MY_LEX_SYSTEM_VAR,
   MY_LEX_IDENT_OR_KEYWORD,
   MY_LEX_IDENT_OR_HEX, MY_LEX_IDENT_OR_BIN, MY_LEX_IDENT_OR_NCHAR,
+  MY_LEX_OJES /* Outer Join Escape Sequence  */,
   MY_LEX_STRING_OR_DELIMITER
 };
 
diff -Nrup a/mysql-test/r/parser.result b/mysql-test/r/parser.result
--- a/mysql-test/r/parser.result	2007-11-30 09:34:22 -02:00
+++ b/mysql-test/r/parser.result	2007-12-10 11:34:09 -02:00
@@ -527,3 +527,16 @@ SELECT * FROM t1 WHERE a = INTERVAL(3,2,
 a	b
 3	1998-01-01 00:00:00
 DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 LIKE t1;
+CREATE TABLE t3 LIKE t1;
+SELECT t1.* FROM t1 AS t0, { OJ t2 INNER JOIN t1 ON (t1.a=t2.a) } WHERE t0.a=2;
+a
+SELECT t1.*,t2.* FROM { OJ ((t1 INNER JOIN t2 ON (t1.a=t2.a)) LEFT OUTER JOIN t3 ON
t3.a=t2.a)};
+a	a
+SELECT t1.*,t2.* FROM { OJ ((t1 LEFT OUTER JOIN t2 ON t1.a=t2.a) INNER JOIN t3 ON
(t3.a=t2.a))};
+a	a
+SELECT t1.*,t2.* FROM { OJ (t1 LEFT OUTER JOIN t2 ON t1.a=t2.a) CROSS JOIN t3 ON
(t3.a=t2.a)};
+a	a
+DROP TABLE t1, t2, t3;
diff -Nrup a/mysql-test/t/parser.test b/mysql-test/t/parser.test
--- a/mysql-test/t/parser.test	2007-11-30 09:34:22 -02:00
+++ b/mysql-test/t/parser.test	2007-12-10 11:34:09 -02:00
@@ -657,3 +657,19 @@ CREATE TABLE t1 (a INT, b DATETIME);
 INSERT INTO t1 VALUES (INTERVAL(3,2,1) + 1, "1997-12-31 23:59:59" + INTERVAL 1 SECOND);
 SELECT * FROM t1 WHERE a = INTERVAL(3,2,1) + 1;
 DROP TABLE t1;
+
+#
+# Bug#28317 Left Outer Join with {oj outer-join}
+#
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 LIKE t1;
+CREATE TABLE t3 LIKE t1;
+SELECT t1.* FROM t1 AS t0, { OJ t2 INNER JOIN t1 ON (t1.a=t2.a) } WHERE t0.a=2;
+SELECT t1.*,t2.* FROM { OJ ((t1 INNER JOIN t2 ON (t1.a=t2.a)) LEFT OUTER JOIN t3 ON
t3.a=t2.a)};
+SELECT t1.*,t2.* FROM { OJ ((t1 LEFT OUTER JOIN t2 ON t1.a=t2.a) INNER JOIN t3 ON
(t3.a=t2.a))};
+SELECT t1.*,t2.* FROM { OJ (t1 LEFT OUTER JOIN t2 ON t1.a=t2.a) CROSS JOIN t3 ON
(t3.a=t2.a)};
+DROP TABLE t1, t2, t3;
diff -Nrup a/mysys/charset.c b/mysys/charset.c
--- a/mysys/charset.c	2007-10-25 07:05:01 -02:00
+++ b/mysys/charset.c	2007-12-10 11:34:10 -02:00
@@ -100,6 +100,7 @@ static my_bool init_state_maps(CHARSET_I
   state_map[(uchar)'@']= (uchar) MY_LEX_USER_END;
   state_map[(uchar) '`']= (uchar) MY_LEX_USER_VARIABLE_DELIMITER;
   state_map[(uchar)'"']= (uchar) MY_LEX_STRING_OR_DELIMITER;
+  state_map[(uchar)'{']= state_map[(uchar)'}']= (uchar) MY_LEX_OJES;
 
   /*
     Create a second map to make it faster to find identifiers
diff -Nrup a/sql/sql_lex.cc b/sql/sql_lex.cc
--- a/sql/sql_lex.cc	2007-11-10 08:58:37 -02:00
+++ b/sql/sql_lex.cc	2007-12-10 11:34:10 -02:00
@@ -135,6 +135,7 @@ Lex_input_stream::Lex_input_stream(THD *
   ignore_space(test(thd->variables.sql_mode & MODE_IGNORE_SPACE)),
   stmt_prepare_mode(FALSE),
   in_comment(NO_COMMENT),
+  in_ojes(FALSE),
   m_underscore_cs(NULL)
 {
   m_cpp_buf= (char*) thd->alloc(length + 1);
@@ -745,13 +746,7 @@ int MYSQLlex(void *arg, void *yythd)
     case MY_LEX_OPERATOR_OR_IDENT:	// Next is operator or keyword
     case MY_LEX_START:			// Start of token
       // Skip starting whitespace
-      while(state_map[c= lip->yyPeek()] == MY_LEX_SKIP)
-      {
-	if (c == '\n')
-	  lip->yylineno++;
-
-        lip->yySkip();
-      }
+      lip->skip_whitespace(state_map);
 
       /* Start of real token */
       lip->restart_token();
@@ -1423,6 +1418,28 @@ int MYSQLlex(void *arg, void *yythd)
                                     lip->m_cpp_text_end);
 
       return(result_state);
+
+    case MY_LEX_OJES:
+      c= lip->yyGetLast();
+      if (c == '{')
+      {
+        if (lip->in_ojes)
+          return(ABORT_SYM);
+        lip->skip_whitespace(state_map);
+        c= lip->yyGet();
+        if (c != 'o' && c != 'O')
+          return(ABORT_SYM);
+        c= lip->yyGet();
+        if (c != 'j' && c != 'J')
+          return(ABORT_SYM);
+        lip->in_ojes= TRUE;
+      }
+      else if (lip->in_ojes)
+        lip->in_ojes= FALSE;
+      else
+        return(ABORT_SYM);
+      state= MY_LEX_START;
+      break;
     }
   }
 }
diff -Nrup a/sql/sql_lex.h b/sql/sql_lex.h
--- a/sql/sql_lex.h	2007-11-28 12:34:10 -02:00
+++ b/sql/sql_lex.h	2007-12-10 11:34:10 -02:00
@@ -1143,6 +1143,23 @@ public:
   }
 
   /**
+    Skip starting whitespace from the input stream.
+  */
+  void skip_whitespace(uchar *state_map)
+  {
+    uchar ch;
+
+    while(state_map[ch= yyPeek()] == MY_LEX_SKIP)
+    {
+      if (ch == '\n')
+        yylineno++;
+
+      yySkip();
+    }
+  }
+
+
+  /**
     Get a character, and advance in the stream.
     @return the next character to parse.
   */
@@ -1445,8 +1462,11 @@ public:
   */
   bool stmt_prepare_mode;
 
-  /** State of the lexical analyser for comments. */
+  /** State of the lexical analyzer for comments. */
   enum_comment_state in_comment;
+
+  /** State of the lexical analyzer for OJES */
+  bool in_ojes;
 
   /**
     Starting position of the TEXT_STRING or IDENT in the pre-processed
diff -Nrup a/sql/sql_yacc.yy b/sql/sql_yacc.yy
--- a/sql/sql_yacc.yy	2007-11-30 09:34:23 -02:00
+++ b/sql/sql_yacc.yy	2007-12-10 11:34:10 -02:00
@@ -508,10 +508,10 @@ bool my_yyoverflow(short **a, YYSTYPE **
 
 %pure_parser                                    /* We have threads */
 /*
-  Currently there are 177 shift/reduce conflicts.
+  Currently there are 176 shift/reduce conflicts.
   We should not introduce new conflicts any more.
 */
-%expect 177
+%expect 176
 
 /*
    Comments for TOKENS.
@@ -7611,25 +7611,6 @@ table_factor:
                                                 Select->pop_index_hints())))
               MYSQL_YYABORT;
             Select->add_joined_table($$);
-          }
-        | '{' ident table_ref LEFT OUTER JOIN_SYM table_ref
-          ON
-          {
-            /* Change the current name resolution context to a local context. */
-            if (push_new_name_resolution_context(YYTHD, $3, $7))
-              MYSQL_YYABORT;
-
-          }
-          expr '}'
-          {
-            LEX *lex= Lex;
-            MYSQL_YYABORT_UNLESS($3 && $7);
-            add_join_on($7,$10);
-            Lex->pop_context();
-            $7->outer_join|=JOIN_TYPE_LEFT;
-            $$=$7;
-            if (!($$= lex->current_select->nest_last_join(lex->thd)))
-              MYSQL_YYABORT;
           }
         | select_derived_init get_select_lex select_derived2
           {
Thread
bk commit into 5.1 tree (davi:1.2680) BUG#28317Davi Arnaut10 Dec
  • Re: bk commit into 5.1 tree (davi:1.2680) BUG#28317Sergei Golubchik10 Dec
    • Re: bk commit into 5.1 tree (davi:1.2680) BUG#28317Davi Arnaut10 Dec
      • Re: bk commit into 5.1 tree (davi:1.2680) BUG#28317Sergei Golubchik10 Dec
        • Re: bk commit into 5.1 tree (davi:1.2680) BUG#28317Davi Arnaut10 Dec
          • Re: bk commit into 5.1 tree (davi:1.2680) BUG#28317Davi Arnaut10 Dec