List:Commits« Previous MessageNext Message »
From:mhansson Date:March 11 2008 1:46pm
Subject:bk commit into 6.0 tree (mhansson:1.2609) BUG#35138
View as plain text  
Below is the list of changes that have just been committed into a local
6.0 repository of mhansson.  When mhansson 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, 2008-03-11 14:45:48+01:00, mhansson@riffraff.(none) +5 -0
  Bug#35138: illegal sql_cache select syntax
  
  The options SQL_CACHE and SQL_NO_CACHE were allowed in combination in 
  any SELECT queries, where the use of one should deny 
  use of the other.
  Fixed by adding flags to the parse tree and a semantic check after parsing.

  mysql-test/r/select.result@stripped, 2008-03-11 14:45:46+01:00, mhansson@riffraff.(none) +26 -0
    Bug#35138: Test result.

  mysql-test/t/select.test@stripped, 2008-03-11 14:45:46+01:00, mhansson@riffraff.(none) +33 -0
    Bug#35138: Test case.

  sql/mysql_priv.h@stripped, 2008-03-11 14:45:46+01:00, mhansson@riffraff.(none) +3 -1
    Bug#35138: New type for SELECT clause options bitmap. New #define's for 
    bit indexes.

  sql/sql_parse.cc@stripped, 2008-03-11 14:45:46+01:00, mhansson@riffraff.(none) +55 -0
    Bug#35138: Added semantics checking for SELECT options statements.
    This could work as a hook for any semantic checking that is not
    dependent on anything but the parse tree.

  sql/sql_yacc.yy@stripped, 2008-03-11 14:45:46+01:00, mhansson@riffraff.(none) +2 -7
    Bug#35138: Moved semantics check for DISTINCT to after parsing. 
    Added setting of SQL_CACHE/SQL_NO_CACHE flags.

diff -Nrup a/mysql-test/r/select.result b/mysql-test/r/select.result
--- a/mysql-test/r/select.result	2008-02-18 16:21:45 +01:00
+++ b/mysql-test/r/select.result	2008-03-11 14:45:46 +01:00
@@ -4358,3 +4358,29 @@ a
 4
 5
 DROP TABLE t1;
+CREATE TABLE t1( a INT );
+SELECT ALL DISTINCT * FROM t1;
+ERROR HY000: Incorrect usage of ALL and DISTINCT
+SELECT * FROM t1 UNION SELECT ALL DISTINCT * FROM t1;
+ERROR HY000: Incorrect usage of ALL and DISTINCT
+SELECT ( SELECT ALL DISTINCT * FROM t1 );
+ERROR HY000: Incorrect usage of ALL and DISTINCT
+SELECT * FROM ( SELECT ALL DISTINCT * FROM t1 ) alias;
+ERROR HY000: Incorrect usage of ALL and DISTINCT
+SELECT * FROM t1 WHERE a = ( SELECT ALL DISTINCT * FROM t1 );
+ERROR HY000: Incorrect usage of ALL and DISTINCT
+SELECT * FROM t1 WHERE a IN ( SELECT ALL DISTINCT * FROM t1 );
+ERROR HY000: Incorrect usage of ALL and DISTINCT
+SELECT * FROM t1 WHERE EXISTS ( SELECT ALL DISTINCT * FROM t1 );
+ERROR HY000: Incorrect usage of ALL and DISTINCT
+SELECT * FROM t1 WHERE NOT EXISTS ( SELECT ALL DISTINCT * FROM t1 );
+ERROR HY000: Incorrect usage of ALL and DISTINCT
+SELECT SQL_NO_CACHE SQL_CACHE * FROM t1;
+ERROR HY000: Incorrect usage of SQL_CACHE and SQL_NO_CACHE
+SELECT SQL_CACHE SQL_NO_CACHE SQL_CACHE * FROM t1;
+ERROR HY000: Incorrect usage of SQL_CACHE and SQL_NO_CACHE
+SELECT SQL_CACHE 1 a    UNION SELECT SQL_NO_CACHE 2 a;
+ERROR HY000: Incorrect usage of SQL_CACHE and SQL_NO_CACHE
+SELECT SQL_NO_CACHE 1 a UNION SELECT SQL_CACHE    2 a;
+ERROR HY000: Incorrect usage of SQL_CACHE and SQL_NO_CACHE
+DROP TABLE t1;
diff -Nrup a/mysql-test/t/select.test b/mysql-test/t/select.test
--- a/mysql-test/t/select.test	2008-02-18 16:21:45 +01:00
+++ b/mysql-test/t/select.test	2008-03-11 14:45:46 +01:00
@@ -3701,3 +3701,36 @@ SELECT a FROM t1 ORDER BY a LIMIT 2;
 SELECT a FROM t1 ORDER BY a LIMIT 2,4294967296;
 SELECT a FROM t1 ORDER BY a LIMIT 2,4294967297;
 DROP TABLE t1;
+
+#
+# Bug#35138: Incompatible SELECT options should not be allowed.
+#
+CREATE TABLE t1( a INT );
+
+--error ER_WRONG_USAGE
+SELECT ALL DISTINCT * FROM t1;
+--error ER_WRONG_USAGE
+SELECT * FROM t1 UNION SELECT ALL DISTINCT * FROM t1;
+--error ER_WRONG_USAGE
+SELECT ( SELECT ALL DISTINCT * FROM t1 );
+--error ER_WRONG_USAGE
+SELECT * FROM ( SELECT ALL DISTINCT * FROM t1 ) alias;
+--error ER_WRONG_USAGE
+SELECT * FROM t1 WHERE a = ( SELECT ALL DISTINCT * FROM t1 );
+--error ER_WRONG_USAGE
+SELECT * FROM t1 WHERE a IN ( SELECT ALL DISTINCT * FROM t1 );
+--error ER_WRONG_USAGE
+SELECT * FROM t1 WHERE EXISTS ( SELECT ALL DISTINCT * FROM t1 );
+--error ER_WRONG_USAGE
+SELECT * FROM t1 WHERE NOT EXISTS ( SELECT ALL DISTINCT * FROM t1 );
+
+--error ER_WRONG_USAGE
+SELECT SQL_NO_CACHE SQL_CACHE * FROM t1;
+--error ER_WRONG_USAGE
+SELECT SQL_CACHE SQL_NO_CACHE SQL_CACHE * FROM t1;
+--error ER_WRONG_USAGE
+SELECT SQL_CACHE 1 a    UNION SELECT SQL_NO_CACHE 2 a;
+--error ER_WRONG_USAGE
+SELECT SQL_NO_CACHE 1 a UNION SELECT SQL_CACHE    2 a;
+
+DROP TABLE t1;
diff -Nrup a/sql/mysql_priv.h b/sql/mysql_priv.h
--- a/sql/mysql_priv.h	2008-02-29 12:07:42 +01:00
+++ b/sql/mysql_priv.h	2008-03-11 14:45:46 +01:00
@@ -73,6 +73,7 @@ typedef ulonglong nested_join_map;
 
 /* query_id */
 typedef ulonglong query_id_t;
+typedef ulonglong select_options_t;
 extern query_id_t global_query_id;
 
 /* increment query_id and return it.  */
@@ -489,7 +490,8 @@ enum open_table_mode
 */
 #define TMP_TABLE_FORCE_MYISAM          (ULL(1) << 32)
 #define OPTION_PROFILING                (ULL(1) << 33)
-
+#define OPTION_SQL_CACHE                (ULL(1) << 34)
+#define OPTION_SQL_NO_CACHE             (ULL(1) << 35)
 /*
   Dont report errors for individual rows,
   But just report error on commit (or read ofcourse)
diff -Nrup a/sql/sql_parse.cc b/sql/sql_parse.cc
--- a/sql/sql_parse.cc	2008-02-29 15:00:03 +01:00
+++ b/sql/sql_parse.cc	2008-03-11 14:45:46 +01:00
@@ -46,6 +46,9 @@ int execute_backup_command(THD*,LEX*);
 
 static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
 static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
+static bool check_semantics(LEX *lex);
+static bool check_select_semantics(SELECT_LEX_UNIT *unit);
+static bool check_select_semantics(SELECT_LEX *node);
 
 const char *any_db="*any*";	// Special symbol for check_access
 
@@ -5516,6 +5519,9 @@ void mysql_parse(THD *thd, const char *i
     bool err= parse_sql(thd, &lip, NULL);
     *found_semicolon= lip.found_semicolon;
 
+    if (!err) 
+      err= check_semantics(lex);
+
     if (!err)
     {
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -7391,6 +7397,55 @@ bool parse_sql(THD *thd,
   /* That's it. */
 
   return mysql_parse_status || thd->is_fatal_error;
+}
+
+static bool check_select_options_semantics(select_options_t options)
+{
+  if (options & SELECT_DISTINCT && options & SELECT_ALL)
+  {
+    my_error(ER_WRONG_USAGE, MYF(0), "ALL", "DISTINCT");
+    return true;
+  }
+  return FALSE;
+}
+
+static bool check_select_semantics(SELECT_LEX_UNIT *unit)
+{
+  return check_select_semantics(unit->first_select());
+}
+
+static bool check_select_semantics(SELECT_LEX *node)
+{
+  if (check_select_options_semantics(node->options))
+    return TRUE;
+
+  select_options_t options= (select_options_t)0;
+  /* Examine all SELECT statements within a UNION. */
+  for (SELECT_LEX *sl= node; sl; sl= sl->next_select_in_list()) 
+    options+= sl->options;
+
+  if (options & OPTION_SQL_CACHE && options & OPTION_SQL_NO_CACHE)
+  {
+    my_error(ER_WRONG_USAGE, MYF(0), "SQL_CACHE", "SQL_NO_CACHE");
+    return true;
+  }  
+
+  SELECT_LEX_UNIT *child= node->first_inner_unit();
+  if (child)
+    return check_select_semantics(child);
+
+  return FALSE;
+}
+
+static bool check_semantics(LEX *lex)
+{
+  SELECT_LEX *current_select= lex->current_select;
+  switch (lex->sql_command) {
+  case SQLCOM_SELECT:
+    return check_select_semantics(current_select);  
+  default:
+    return FALSE;
+  }
 }
 
 /**
diff -Nrup a/sql/sql_yacc.yy b/sql/sql_yacc.yy
--- a/sql/sql_yacc.yy	2008-03-06 09:20:50 +01:00
+++ b/sql/sql_yacc.yy	2008-03-11 14:45:46 +01:00
@@ -6563,13 +6563,6 @@ select_from:
 select_options:
           /* empty*/
         | select_option_list
-          {
-            if (Select->options & SELECT_DISTINCT && Select->options & SELECT_ALL)
-            {
-              my_error(ER_WRONG_USAGE, MYF(0), "ALL", "DISTINCT");
-              MYSQL_YYABORT;
-            }
-          }
         ;
 
 select_option_list:
@@ -6602,12 +6595,14 @@ select_option:
           }
         | SQL_NO_CACHE_SYM
           {
+            Select->options|= OPTION_SQL_NO_CACHE;
             Lex->safe_to_cache_query=0;
             Lex->select_lex.options&= ~OPTION_TO_QUERY_CACHE;
             Lex->select_lex.sql_cache= SELECT_LEX::SQL_NO_CACHE;
           }
         | SQL_CACHE_SYM
           {
+            Select->options|= OPTION_SQL_CACHE;
             /*
              Honor this flag only if SQL_NO_CACHE wasn't specified AND
              we are parsing the outermost SELECT in the query.
Thread
bk commit into 6.0 tree (mhansson:1.2609) BUG#35138mhansson12 Mar