[Commits] Rev 3497: MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). in file:///home/hf/wmar/mdev-318/

holyfoot at askmonty.org holyfoot at askmonty.org
Tue Feb 19 15:11:24 EET 2013


At file:///home/hf/wmar/mdev-318/

------------------------------------------------------------
revno: 3497
revision-id: holyfoot at askmonty.org-20130219125224-a1i75s2zpvzht14k
parent: sergii at pisem.net-20130131203221-2xsc0dp0r916bnu1
committer: Alexey Botchkov <holyfoot at askmonty.org>
branch nick: mdev-318
timestamp: Tue 2013-02-19 16:52:24 +0400
message:
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
  Syntax modified to allow statements:
        ALTER TABLE ADD/DROP COLUMN
        ALTER TABLE ADD/DROP INDEX
        ALTER TABLE ADD/DROP FOREIGN KEY
        ALTER TABLE ADD/DROP PARTITION
        ALTER TABLE CHANGE COLUMN
        ALTER TABLE MODIFY COLUMN
        DROP INDEX
  to have IF (NOT) EXISTS options.
  Appropriate implementations added to mysql_alter_table().
  
  per-file comments:
    mysql-test/r/alter_table.result
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
          test result updated.
    mysql-test/r/fulltext.result
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
    mysql-test/r/partition.result
          test result updated.
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
    mysql-test/t/alter_table.test
          tests added.
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
    mysql-test/t/fulltext.test
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
          tests added.
    mysql-test/t/partition.test
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
          tests added.
    sql/field.cc
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
          create_if_not_exists field added.
    sql/field.h
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
          create_if_not_exists field added.
    sql/partition_info.h
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
          has_unique_name made public.
    sql/sp_head.cc
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
    sql/sql_class.cc
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
          create_if_not_exists inited.
    sql/sql_class.h
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
          create_if_not_exists inited.
    sql/sql_lex.cc
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
          check_exists inited.
    sql/sql_lex.h
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
          check_exists inited.
    sql/sql_parse.cc
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
          check_exists inited.
    sql/sql_table.cc
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
          handle_if_exists_options() added.
          it's called in mysql_alter_table().
    sql/sql_trigger.cc
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
          check_exists instead of drop_if_exists.
    sql/sql_view.cc
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
          check_exists instead of drop_if_exists.
    sql/sql_yacc.yy
  MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252).
          sintax modified.
-------------- next part --------------
=== modified file 'mysql-test/r/alter_table.result'
--- a/mysql-test/r/alter_table.result	2012-12-20 18:58:40 +0000
+++ b/mysql-test/r/alter_table.result	2013-02-19 12:52:24 +0000
@@ -1340,3 +1340,43 @@ rename table t2 to t1;
 execute stmt1;
 deallocate prepare stmt1;
 drop table t2;
+CREATE TABLE t1 (
+id INT(11) NOT NULL,
+x_param INT(11) DEFAULT NULL,
+PRIMARY KEY (id)
+);
+ALTER TABLE t1 ADD COLUMN IF NOT EXISTS id INT,
+ADD COLUMN IF NOT EXISTS lol INT AFTER id;
+Warnings:
+Note    1060    Duplicate column name 'id'
+ALTER TABLE t1 ADD COLUMN IF NOT EXISTS lol INT AFTER id;
+Warnings:
+Note    1060    Duplicate column name 'lol'
+ALTER TABLE t1 DROP COLUMN IF EXISTS lol;
+ALTER TABLE t1 DROP COLUMN IF EXISTS lol;
+Warnings:
+Note    1091    Can't DROP 'lol'; check that column/key exists
+ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param);
+ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param);
+Warnings:
+Note    1061    Duplicate key name 'x_param'
+ALTER TABLE t1 MODIFY IF EXISTS lol INT;
+Warnings:
+Note    1054    Unknown column 'lol' in 't1'
+DROP INDEX IF EXISTS x_param ON t1;
+DROP INDEX IF EXISTS x_param ON t1;
+Warnings:
+Note    1091    Can't DROP 'x_param'; check that column/key exists
+CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param);
+CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param);
+Warnings:
+Note    1061    Duplicate key name 'x_param1'
+SHOW CREATE TABLE t1;
+Table   Create Table
+t1      CREATE TABLE `t1` (
+  `id` int(11) NOT NULL,
+  `x_param` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  KEY `x_param1` (`x_param`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;

=== modified file 'mysql-test/r/fulltext.result'
--- a/mysql-test/r/fulltext.result	2012-05-21 18:54:41 +0000
+++ b/mysql-test/r/fulltext.result	2013-02-19 12:52:24 +0000
@@ -699,3 +699,14 @@ EXECUTE stmt;
 DEALLOCATE PREPARE stmt;
 DROP TABLE t1;
 End of 5.1 tests
+CREATE TABLE t1 (
+id int(11)  auto_increment,
+title varchar(100)  default '',
+PRIMARY KEY  (id),
+KEY ind5 (title)
+) ENGINE=MyISAM;
+CREATE FULLTEXT INDEX IF NOT EXISTS ft1 ON t1(title);
+CREATE FULLTEXT INDEX IF NOT EXISTS ft1 ON t1(title);
+Warnings:
+Note    1061    Duplicate key name 'ft1'
+DROP TABLE t1;

=== modified file 'mysql-test/r/partition.result'
--- a/mysql-test/r/partition.result	2012-11-22 09:19:31 +0000
+++ b/mysql-test/r/partition.result	2013-02-19 12:52:24 +0000
@@ -2493,3 +2493,25 @@ SELECT * from t1 order by i;
 3
 4
 DROP TABLE t1;
+CREATE TABLE t1 ( d DATE NOT NULL)
+PARTITION BY RANGE( YEAR(d) ) (
+PARTITION p0 VALUES LESS THAN (1960),
+PARTITION p1 VALUES LESS THAN (1970),
+PARTITION p2 VALUES LESS THAN (1980),
+PARTITION p3 VALUES LESS THAN (1990)
+);
+ALTER TABLE t1 ADD PARTITION IF NOT EXISTS(
+PARTITION `p5` VALUES LESS THAN (2010)
+COMMENT 'APSTART \' APEND'
+);
+ALTER TABLE t1 ADD PARTITION IF NOT EXISTS(
+PARTITION `p5` VALUES LESS THAN (2010)
+COMMENT 'APSTART \' APEND'
+);
+Warnings:
+Note    1517    Duplicate partition name p5
+alter table t1 drop partition if exists p5;
+alter table t1 drop partition if exists p5;
+Warnings:
+Note    1507    Error in list of partitions to DROP
+DROP TABLE t1;

=== modified file 'mysql-test/t/alter_table.test'
--- a/mysql-test/t/alter_table.test	2012-05-21 13:30:25 +0000
+++ b/mysql-test/t/alter_table.test	2013-02-19 12:52:24 +0000
@@ -1231,3 +1231,30 @@ execute stmt1;
 deallocate prepare stmt1;
 drop table t2;
 
+#
+# Test of ALTER TABLE IF [NOT] EXISTS
+#
+
+CREATE TABLE t1 (
+  id INT(11) NOT NULL,
+  x_param INT(11) DEFAULT NULL,
+  PRIMARY KEY (id)
+);
+
+ALTER TABLE t1 ADD COLUMN IF NOT EXISTS id INT,
+               ADD COLUMN IF NOT EXISTS lol INT AFTER id;
+ALTER TABLE t1 ADD COLUMN IF NOT EXISTS lol INT AFTER id;
+ALTER TABLE t1 DROP COLUMN IF EXISTS lol;
+ALTER TABLE t1 DROP COLUMN IF EXISTS lol;
+
+ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param);
+ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param);
+ALTER TABLE t1 MODIFY IF EXISTS lol INT;
+
+DROP INDEX IF EXISTS x_param ON t1;
+DROP INDEX IF EXISTS x_param ON t1;
+CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param);
+CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+

=== modified file 'mysql-test/t/fulltext.test'
--- a/mysql-test/t/fulltext.test	2011-11-22 17:04:38 +0000
+++ b/mysql-test/t/fulltext.test	2013-02-19 12:52:24 +0000
@@ -646,3 +646,14 @@ DEALLOCATE PREPARE stmt;
 DROP TABLE t1;
 
 --echo End of 5.1 tests
+
+CREATE TABLE t1 (
+  id int(11)  auto_increment,
+  title varchar(100)  default '',
+  PRIMARY KEY  (id),
+  KEY ind5 (title)
+) ENGINE=MyISAM;
+
+CREATE FULLTEXT INDEX IF NOT EXISTS ft1 ON t1(title);
+CREATE FULLTEXT INDEX IF NOT EXISTS ft1 ON t1(title);
+DROP TABLE t1;

=== modified file 'mysql-test/t/partition.test'
--- a/mysql-test/t/partition.test	2012-11-22 09:19:31 +0000
+++ b/mysql-test/t/partition.test	2013-02-19 12:52:24 +0000
@@ -2494,3 +2494,31 @@ INSERT INTO t1 VALUES (1),(2),(2),(3),(4
 ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
 SELECT * from t1 order by i;
 DROP TABLE t1;
+
+#
+# Test ALTER TABLE ADD/DROP PARTITION IF EXISTS
+#
+
+CREATE TABLE t1 ( d DATE NOT NULL)
+PARTITION BY RANGE( YEAR(d) ) (
+    PARTITION p0 VALUES LESS THAN (1960),
+    PARTITION p1 VALUES LESS THAN (1970),
+    PARTITION p2 VALUES LESS THAN (1980),
+    PARTITION p3 VALUES LESS THAN (1990)
+);
+
+ALTER TABLE t1 ADD PARTITION IF NOT EXISTS(
+PARTITION `p5` VALUES LESS THAN (2010)
+COMMENT 'APSTART \' APEND'
+);
+
+ALTER TABLE t1 ADD PARTITION IF NOT EXISTS(
+PARTITION `p5` VALUES LESS THAN (2010)
+COMMENT 'APSTART \' APEND'
+);
+
+alter table t1 drop partition if exists p5;
+alter table t1 drop partition if exists p5;
+
+DROP TABLE t1;
+

=== modified file 'sql/field.cc'
--- a/sql/field.cc	2013-01-31 08:48:19 +0000
+++ b/sql/field.cc	2013-02-19 12:52:24 +0000
@@ -8870,6 +8870,7 @@ void Create_field::init_for_tmp_table(en
                        FLAGSTR(pack_flag, FIELDFLAG_DECIMAL),
                        f_packtype(pack_flag)));
   vcol_info= 0;
+  create_if_not_exists= FALSE;
   stored_in_db= TRUE;
 
   DBUG_VOID_RETURN;
@@ -8907,7 +8908,7 @@ bool Create_field::init(THD *thd, char *
                         char *fld_change, List<String> *fld_interval_list,
                         CHARSET_INFO *fld_charset, uint fld_geom_type,
                         Virtual_column_info *fld_vcol_info,
-                        engine_option_value *create_opt)
+                        engine_option_value *create_opt, bool check_exists)
 {
   uint sign_len, allowed_type_modifier= 0;
   ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
@@ -8961,6 +8962,7 @@ bool Create_field::init(THD *thd, char *
 
   comment= *fld_comment;
   vcol_info= fld_vcol_info;
+  create_if_not_exists= check_exists;
   stored_in_db= TRUE;
 
   /* Initialize data for a computed field */
@@ -9567,6 +9569,7 @@ Create_field::Create_field(Field *old_fi
   comment=    old_field->comment;
   decimals=   old_field->decimals();
   vcol_info=  old_field->vcol_info;
+  create_if_not_exists= FALSE;
   stored_in_db= old_field->stored_in_db;
   option_list= old_field->option_list;
   option_struct= old_field->option_struct;

=== modified file 'sql/field.h'
--- a/sql/field.h	2013-01-29 14:10:47 +0000
+++ b/sql/field.h	2013-02-19 12:52:24 +0000
@@ -2384,8 +2384,9 @@ class Create_field :public Sql_alloc
 
   uint8 row,col,sc_length,interval_id;  // For rea_create_table
   uint  offset,pack_flag;
+  bool create_if_not_exists;            // Used in ALTER TABLE IF NOT EXISTS
 
-    /* 
+  /* 
     This is additinal data provided for any computed(virtual) field.
     In particular it includes a pointer to the item by  which this field
     can be computed from other fields.
@@ -2398,7 +2399,8 @@ class Create_field :public Sql_alloc
   */
   bool stored_in_db;
 
-  Create_field() :after(0), option_list(NULL), option_struct(NULL)
+  Create_field() :after(0), option_list(NULL), option_struct(NULL),
+                  create_if_not_exists(FALSE)
   {}
   Create_field(Field *field, Field *orig_field);
   /* Used to make a clone of this object for ALTER/CREATE TABLE */
@@ -2416,7 +2418,7 @@ class Create_field :public Sql_alloc
             Item *on_update_value, LEX_STRING *comment, char *change,
             List<String> *interval_list, CHARSET_INFO *cs,
             uint uint_geom_type, Virtual_column_info *vcol_info,
-            engine_option_value *option_list);
+            engine_option_value *option_list, bool check_exists);
 
   bool field_flags_are_binary()
   {

=== modified file 'sql/partition_info.h'
--- a/sql/partition_info.h	2011-06-30 15:46:53 +0000
+++ b/sql/partition_info.h	2013-02-19 12:52:24 +0000
@@ -306,6 +306,7 @@ class partition_info : public Sql_alloc
   char *create_default_partition_names(uint part_no, uint num_parts,
                                        uint start_no);
   char *create_subpartition_name(uint subpart_no, const char *part_name);
+public:
   bool has_unique_name(partition_element *element);
 };
 

=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc	2013-01-31 08:48:19 +0000
+++ b/sql/sp_head.cc	2013-02-19 12:52:24 +0000
@@ -2432,7 +2432,7 @@ sp_head::fill_field_definition(THD *thd,
                       lex->charset ? lex->charset :
                                      thd->variables.collation_database,
                       lex->uint_geom_type,
-                      lex->vcol_info, NULL))
+                      lex->vcol_info, NULL, FALSE))
     return TRUE;
 
   if (field_def->interval_list.elements)

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2013-01-31 08:48:19 +0000
+++ b/sql/sql_class.cc	2013-02-19 12:52:24 +0000
@@ -112,7 +112,8 @@ Key::Key(const Key &rhs, MEM_ROOT *mem_r
   columns(rhs.columns, mem_root),
   name(rhs.name),
   option_list(rhs.option_list),
-  generated(rhs.generated)
+  generated(rhs.generated),
+  create_if_not_exists(rhs.create_if_not_exists)
 {
   list_copy_and_replace_each_value(columns, mem_root);
 }

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2013-01-31 08:48:19 +0000
+++ b/sql/sql_class.h	2013-02-19 12:52:24 +0000
@@ -235,8 +235,9 @@ class Alter_drop :public Sql_alloc {
   enum drop_type {KEY, COLUMN };
   const char *name;
   enum drop_type type;
-  Alter_drop(enum drop_type par_type,const char *par_name)
-    :name(par_name), type(par_type) {}
+  bool drop_if_exists;
+  Alter_drop(enum drop_type par_type,const char *par_name, bool par_exists)
+    :name(par_name), type(par_type), drop_if_exists(par_exists) {}
   /**
     Used to make a clone of this object for ALTER/CREATE TABLE
     @sa comment for Key_part_spec::clone
@@ -270,20 +271,23 @@ class Key :public Sql_alloc {
   LEX_STRING name;
   engine_option_value *option_list;
   bool generated;
+  bool create_if_not_exists;
 
   Key(enum Keytype type_par, const LEX_STRING &name_arg,
       KEY_CREATE_INFO *key_info_arg,
       bool generated_arg, List<Key_part_spec> &cols,
-      engine_option_value *create_opt)
+      engine_option_value *create_opt, bool if_not_exists_opt)
     :type(type_par), key_create_info(*key_info_arg), columns(cols),
-    name(name_arg), option_list(create_opt), generated(generated_arg)
+    name(name_arg), option_list(create_opt), generated(generated_arg),
+    create_if_not_exists(if_not_exists_opt)
   {}
   Key(enum Keytype type_par, const char *name_arg, size_t name_len_arg,
       KEY_CREATE_INFO *key_info_arg, bool generated_arg,
       List<Key_part_spec> &cols,
-      engine_option_value *create_opt)
+      engine_option_value *create_opt, bool if_not_exists_opt)
     :type(type_par), key_create_info(*key_info_arg), columns(cols),
-    option_list(create_opt), generated(generated_arg)
+    option_list(create_opt), generated(generated_arg),
+    create_if_not_exists(if_not_exists_opt)
   {
     name.str= (char *)name_arg;
     name.length= name_len_arg;
@@ -314,8 +318,10 @@ class Foreign_key: public Key {
   uint delete_opt, update_opt, match_opt;
   Foreign_key(const LEX_STRING &name_arg, List<Key_part_spec> &cols,
               Table_ident *table,   List<Key_part_spec> &ref_cols,
-              uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg)
-    :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols, NULL),
+              uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg,
+              bool if_not_exists_opt)
+    :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols, NULL,
+         if_not_exists_opt),
     ref_table(table), ref_columns(ref_cols),
     delete_opt(delete_opt_arg), update_opt(update_opt_arg),
     match_opt(match_opt_arg)

=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc	2013-01-31 08:48:19 +0000
+++ b/sql/sql_lex.cc	2013-02-19 12:52:24 +0000
@@ -507,6 +507,7 @@ void lex_start(THD *thd)
   lex->expr_allows_subselect= TRUE;
   lex->use_only_table_context= FALSE;
   lex->parse_vcol_expr= FALSE;
+  lex->check_exists= FALSE;
   lex->verbose= 0;
 
   lex->name.str= 0;

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2013-01-31 08:48:19 +0000
+++ b/sql/sql_lex.h	2013-02-19 12:52:24 +0000
@@ -2433,7 +2433,8 @@ struct LEX: public Query_tables_list
   uint16 create_view_algorithm;
   uint8 create_view_check;
   uint8 context_analysis_only;
-  bool drop_if_exists, drop_temporary, local_file, one_shot_set;
+  bool drop_temporary, local_file, one_shot_set;
+  bool check_exists;
   bool autocommit;
   bool verbose, no_write_to_binlog;
 

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2013-01-31 08:48:19 +0000
+++ b/sql/sql_parse.cc	2013-02-19 12:52:24 +0000
@@ -2277,7 +2277,7 @@ mysql_execute_command(THD *thd)
     if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
         !(lex->sql_command == SQLCOM_SET_OPTION) &&
         !(lex->sql_command == SQLCOM_DROP_TABLE &&
-          lex->drop_temporary && lex->drop_if_exists) &&
+          lex->drop_temporary && lex->check_exists) &&
         all_tables_not_ok(thd, all_tables))
     {
       /* we warn the slave SQL thread */
@@ -3489,7 +3489,7 @@ mysql_execute_command(THD *thd)
       thd->variables.option_bits|= OPTION_KEEP_LOG;
     }
     /* DDL and binlog write order are protected by metadata locks. */
-    res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
+    res= mysql_rm_table(thd, first_table, lex->check_exists,
                         lex->drop_temporary);
   }
   break;
@@ -3703,7 +3703,7 @@ mysql_execute_command(THD *thd)
 #endif
     if (check_access(thd, DROP_ACL, lex->name.str, NULL, NULL, 1, 0))
       break;
-    res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
+    res= mysql_rm_db(thd, lex->name.str, lex->check_exists, 0);
     break;
   }
   case SQLCOM_ALTER_DB_UPGRADE:
@@ -3831,7 +3831,7 @@ mysql_execute_command(THD *thd)
   case SQLCOM_DROP_EVENT:
     if (!(res= Events::drop_event(thd,
                                   lex->spname->m_db, lex->spname->m_name,
-                                  lex->drop_if_exists)))
+                                  lex->check_exists)))
       my_ok(thd);
     break;
 #else
@@ -4520,7 +4520,7 @@ mysql_execute_command(THD *thd)
 
         if (lex->spname->m_db.str == NULL)
         {
-          if (lex->drop_if_exists)
+          if (lex->check_exists)
           {
             push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
                                 ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
@@ -4589,7 +4589,7 @@ mysql_execute_command(THD *thd)
         my_ok(thd);
         break;
       case SP_KEY_NOT_FOUND:
-        if (lex->drop_if_exists)
+        if (lex->check_exists)
         {
           res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
           push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
@@ -4804,7 +4804,7 @@ mysql_execute_command(THD *thd)
 
     if ((err_code= drop_server(thd, &lex->server_options)))
     {
-      if (! lex->drop_if_exists && err_code == ER_FOREIGN_SERVER_DOESNT_EXIST)
+      if (! lex->check_exists && err_code == ER_FOREIGN_SERVER_DOESNT_EXIST)
       {
         DBUG_PRINT("info", ("problem dropping server %s",
                             lex->server_options.server_name));
@@ -6227,7 +6227,7 @@ bool add_field_to_list(THD *thd, LEX_STR
     lex->col_list.push_back(new Key_part_spec(*field_name, 0));
     key= new Key(Key::PRIMARY, null_lex_str,
                       &default_key_create_info,
-                      0, lex->col_list, NULL);
+                      0, lex->col_list, NULL, lex->check_exists);
     lex->alter_info.key_list.push_back(key);
     lex->col_list.empty();
   }
@@ -6237,7 +6237,7 @@ bool add_field_to_list(THD *thd, LEX_STR
     lex->col_list.push_back(new Key_part_spec(*field_name, 0));
     key= new Key(Key::UNIQUE, null_lex_str,
                  &default_key_create_info, 0,
-                 lex->col_list, NULL);
+                 lex->col_list, NULL, lex->check_exists);
     lex->alter_info.key_list.push_back(key);
     lex->col_list.empty();
   }
@@ -6289,7 +6289,7 @@ bool add_field_to_list(THD *thd, LEX_STR
       new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
                       default_value, on_update_value, comment, change,
                       interval_list, cs, uint_geom_type, vcol_info,
-                      create_options))
+                      create_options, lex->check_exists))
     DBUG_RETURN(1);
 
   lex->alter_info.create_list.push_back(new_field);

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2013-01-31 08:48:19 +0000
+++ b/sql/sql_table.cc	2013-02-19 12:52:24 +0000
@@ -5031,6 +5031,246 @@ is_index_maintenance_unique (TABLE *tabl
 }
 
 
+ /*
+   Preparation for table creation
+
+   SYNOPSIS
+     handle_if_exists_option()
+       thd                       Thread object.
+       table                     The altered table.
+       alter_info                List of columns and indexes to create
+
+   DESCRIPTION
+     Looks for the IF [NOT] EXISTS options, checks the states and remove items
+     from the list if existing found.
+
+   RETURN VALUES
+     NONE
+*/
+
+static void
+handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
+{
+  Field **f_ptr;
+  DBUG_ENTER("handle_if_exists_option");
+
+  /* Handle ADD COLUMN IF NOT EXISTS. */
+  {
+    List_iterator<Create_field> it(alter_info->create_list);
+    Create_field *sql_field;
+
+    while ((sql_field=it++))
+    {
+      if (!sql_field->create_if_not_exists || sql_field->change)
+        continue;
+      /*
+         If there is a field with the same name in the table already,
+         remove the sql_field from the list.
+      */
+      for (f_ptr=table->field; *f_ptr; f_ptr++)
+      {
+        if (my_strcasecmp(system_charset_info,
+              sql_field->field_name, (*f_ptr)->field_name) == 0)
+        {
+          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+              ER_DUP_FIELDNAME, ER(ER_DUP_FIELDNAME),
+              sql_field->field_name);
+          it.remove();
+          if (alter_info->create_list.is_empty())
+          {
+            alter_info->flags&= ~ALTER_ADD_COLUMN;
+            if (alter_info->key_list.is_empty())
+              alter_info->flags&= ~ALTER_ADD_INDEX;
+          }
+          break;
+        }
+      }
+    }
+  }
+
+  /* Handle MODIFY COLUMN IF EXISTS. */
+  {
+    List_iterator<Create_field> it(alter_info->create_list);
+    Create_field *sql_field;
+
+    while ((sql_field=it++))
+    {
+      if (!sql_field->create_if_not_exists || !sql_field->change)
+        continue;
+      /*
+         If there is NO field with the same name in the table already,
+         remove the sql_field from the list.
+      */
+      for (f_ptr=table->field; *f_ptr; f_ptr++)
+      {
+        if (my_strcasecmp(system_charset_info,
+              sql_field->field_name, (*f_ptr)->field_name) == 0)
+        {
+          break;
+        }
+      }
+      if (*f_ptr == NULL)
+      {
+        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+            ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR),
+            sql_field->change, table->s->table_name.str);
+        it.remove();
+        if (alter_info->create_list.is_empty())
+        {
+          alter_info->flags&= ~(ALTER_ADD_COLUMN | ALTER_CHANGE_COLUMN);
+          if (alter_info->key_list.is_empty())
+            alter_info->flags&= ~ALTER_ADD_INDEX;
+        }
+      }
+    }
+  }
+
+  /* Handle DROP COLUMN/KEY IF EXISTS. */
+  {
+    List_iterator<Alter_drop> drop_it(alter_info->drop_list);
+    Alter_drop *drop;
+    bool remove_drop;
+    while ((drop= drop_it++))
+    {
+      if (!drop->drop_if_exists)
+        continue;
+      remove_drop= TRUE;
+      if (drop->type == Alter_drop::COLUMN)
+      {
+        /*
+           If there is NO field with that name in the table,
+           remove the 'drop' from the list.
+        */
+        for (f_ptr=table->field; *f_ptr; f_ptr++)
+        {
+          if (my_strcasecmp(system_charset_info,
+                            drop->name, (*f_ptr)->field_name) == 0)
+          {
+            remove_drop= FALSE;
+            break;
+          }
+        }
+      }
+      else /* Alter_drop::KEY */
+      {
+        uint n_key;
+        for (n_key=0; n_key < table->s->keys; n_key++)
+        {
+          if (my_strcasecmp(system_charset_info,
+                            drop->name, table->key_info[n_key].name) == 0)
+          {
+            remove_drop= FALSE;
+            break;
+          }
+        }
+      }
+      if (remove_drop)
+      {
+        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+            ER_CANT_DROP_FIELD_OR_KEY, ER(ER_CANT_DROP_FIELD_OR_KEY),
+            drop->name);
+        drop_it.remove();
+        if (alter_info->drop_list.is_empty())
+          alter_info->flags&= ~(ALTER_DROP_COLUMN | ALTER_DROP_INDEX);
+      }
+    }
+  }
+
+  /* ALTER TABLE ADD KEY IF NOT EXISTS */
+  /* ALTER TABLE ADD FOREIGN KEY IF NOT EXISTS */
+  {
+    Key *key;
+    List_iterator<Key> key_it(alter_info->key_list);
+    uint n_key;
+    while ((key=key_it++))
+    {
+      if (!key->create_if_not_exists)
+        continue;
+      for (n_key=0; n_key < table->s->keys; n_key++)
+      {
+        if (my_strcasecmp(system_charset_info,
+              key->name.str, table->key_info[n_key].name) == 0)
+        {
+          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+              ER_DUP_KEYNAME, ER(ER_DUP_KEYNAME), key->name);
+          key_it.remove();
+          if (key->type == Key::FOREIGN_KEY)
+          {
+            /* ADD FOREIGN KEY appends two items. */
+            key_it.remove();
+          }
+          if (alter_info->key_list.is_empty())
+            alter_info->flags&= ~ALTER_ADD_INDEX;
+          break;
+        }
+      }
+    }
+  }
+  
+#ifdef WITH_PARTITION_STORAGE_ENGINE
+  partition_info *tab_part_info= table->part_info;
+  if (tab_part_info && thd->lex->check_exists)
+  {
+    /* ALTER TABLE ADD PARTITION IF NOT EXISTS */
+    if (alter_info->flags & ALTER_ADD_PARTITION)
+    {
+      partition_info *alt_part_info= thd->lex->part_info;
+      if (alt_part_info)
+      {
+        List_iterator<partition_element> new_part_it(alt_part_info->partitions);
+        partition_element *pe;
+        while ((pe= new_part_it++))
+        {
+          if (!tab_part_info->has_unique_name(pe))
+          {
+            push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+                ER_SAME_NAME_PARTITION, ER(ER_SAME_NAME_PARTITION),
+                pe->partition_name);
+            alter_info->flags&= ~ALTER_ADD_PARTITION;
+            thd->lex->part_info= NULL;
+            break;
+          }
+        }
+      }
+    }
+    /* ALTER TABLE DROP PARTITION IF EXISTS */
+    if (alter_info->flags & ALTER_DROP_PARTITION)
+    {
+      List_iterator<char> names_it(alter_info->partition_names);
+      char *name;
+
+      while ((name= names_it++))
+      {
+        List_iterator<partition_element> part_it(tab_part_info->partitions);
+        partition_element *part_elem;
+        while ((part_elem= part_it++))
+        {
+          if (my_strcasecmp(system_charset_info,
+                              part_elem->partition_name, name) == 0)
+            break;
+        }
+        if (!part_elem)
+        {
+          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+              ER_DROP_PARTITION_NON_EXISTENT,
+              ER(ER_DROP_PARTITION_NON_EXISTENT), "DROP");
+          names_it.remove();
+        }
+      }
+      if (alter_info->partition_names.elements == 0)
+        alter_info->flags&= ~ALTER_DROP_PARTITION;
+    }
+  }
+#endif /*WITH_PARTITION_STORAGE_ENGINE*/
+
+  /* Clear the ALTER_FOREIGN_KEY flag if nothing other than that set. */
+  if (alter_info->flags == ALTER_FOREIGN_KEY)
+    alter_info->flags= 0;
+
+  DBUG_VOID_RETURN;
+}
+
+
 /*
   SYNOPSIS
     mysql_compare_tables()
@@ -5950,7 +6190,7 @@ mysql_prepare_alter_table(THD *thd, TABL
       key= new Key(key_type, key_name, strlen(key_name),
                    &key_create_info,
                    test(key_info->flags & HA_GENERATED_KEY),
-                   key_parts, key_info->option_list);
+                   key_parts, key_info->option_list, FALSE);
       new_key_list.push_back(key);
     }
   }
@@ -6475,6 +6715,17 @@ bool mysql_alter_table(THD *thd,char *ne
     DBUG_RETURN(error);
   }
 
+  handle_if_exists_options(thd, table, alter_info);
+
+  /* Look if we have to do anything at all. */
+  /* Normally ALTER can become NOOP only after handling */
+  /* the IF (NOT) EXISTS options. */
+  if (alter_info->flags == 0)
+  {
+    copied= deleted= 0;
+    goto end_temporary;
+  }
+
   /* We have to do full alter table. */
 
 #ifdef WITH_PARTITION_STORAGE_ENGINE

=== modified file 'sql/sql_trigger.cc'
--- a/sql/sql_trigger.cc	2013-01-23 15:18:09 +0000
+++ b/sql/sql_trigger.cc	2013-02-19 12:52:24 +0000
@@ -443,7 +443,7 @@ bool mysql_create_or_drop_trigger(THD *t
 
   if (!create)
   {
-    bool if_exists= thd->lex->drop_if_exists;
+    bool if_exists= thd->lex->check_exists;
 
     /*
       Protect the query table list from the temporary and potentially

=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc	2012-09-27 18:09:46 +0000
+++ b/sql/sql_view.cc	2013-02-19 12:52:24 +0000
@@ -1678,7 +1678,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
     {
       char name[FN_REFLEN];
       my_snprintf(name, sizeof(name), "%s.%s", view->db, view->table_name);
-      if (thd->lex->drop_if_exists)
+      if (thd->lex->check_exists)
       {
         push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
                             ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2013-01-31 08:48:19 +0000
+++ b/sql/sql_yacc.yy	2013-02-19 12:52:24 +0000
@@ -722,7 +722,7 @@ static bool add_create_index (LEX *lex, 
 {
   Key *key;
   key= new Key(type, name, info ? info : &lex->key_create_info, generated, 
-               lex->col_list, lex->option_list);
+               lex->col_list, lex->option_list, lex->check_exists);
   if (key == NULL)
     return TRUE;
 
@@ -1566,7 +1566,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
         IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
         NCHAR_STRING opt_component key_cache_name
         sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
-        opt_constraint constraint opt_ident
+        opt_constraint constraint opt_ident opt_if_not_exists_ident
 
 %type <lex_str_ptr>
         opt_table_alias
@@ -1583,7 +1583,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 
 %type <num>
         type type_with_opt_collate int_type real_type order_dir lock_option
-        udf_type if_exists opt_local opt_table_options table_options
+        udf_type opt_if_exists opt_local opt_table_options table_options
         table_option opt_if_not_exists opt_no_write_to_binlog
         opt_temporary all_or_any opt_distinct
         opt_ignore_leaves fulltext_options spatial_type union_option
@@ -2254,36 +2254,36 @@ rule: <-- starts at col 1
             }
             create_table_set_open_action_and_adjust_tables(lex);
           }
-        | CREATE opt_unique INDEX_SYM ident key_alg ON table_ident
+        | CREATE opt_unique INDEX_SYM opt_if_not_exists ident key_alg ON table_ident
           {
-            if (add_create_index_prepare(Lex, $7))
+            if (add_create_index_prepare(Lex, $8))
               MYSQL_YYABORT;
           }
           '(' key_list ')' normal_key_options
           {
-            if (add_create_index(Lex, $2, $4))
+            if (add_create_index(Lex, $2, $5))
               MYSQL_YYABORT;
           }
-        | CREATE fulltext INDEX_SYM ident init_key_options ON
+        | CREATE fulltext INDEX_SYM opt_if_not_exists ident init_key_options ON
           table_ident
           {
-            if (add_create_index_prepare(Lex, $7))
+            if (add_create_index_prepare(Lex, $8))
               MYSQL_YYABORT;
           }
           '(' key_list ')' fulltext_key_options
           {
-            if (add_create_index(Lex, $2, $4))
+            if (add_create_index(Lex, $2, $5))
               MYSQL_YYABORT;
           }
-        | CREATE spatial INDEX_SYM ident init_key_options ON
+        | CREATE spatial INDEX_SYM opt_if_not_exists ident init_key_options ON
           table_ident
           {
-            if (add_create_index_prepare(Lex, $7))
+            if (add_create_index_prepare(Lex, $8))
               MYSQL_YYABORT;
           }
           '(' key_list ')' spatial_key_options
           {
-            if (add_create_index(Lex, $2, $4))
+            if (add_create_index(Lex, $2, $5))
               MYSQL_YYABORT;
           }
         | CREATE DATABASE opt_if_not_exists ident
@@ -5224,9 +5224,17 @@ rule: <-- starts at col 1
         ;
 
 opt_if_not_exists:
-          /* empty */ { $$= 0; }
-        | IF not EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; }
-        ;
+          /* empty */
+          {
+            Lex->check_exists= FALSE;
+            $$= 0;
+          }
+        | IF not EXISTS
+          {
+            Lex->check_exists= TRUE;
+            $$=HA_LEX_CREATE_IF_NOT_EXISTS;
+          }
+         ;
 
 opt_create_table_options:
           /* empty */
@@ -5544,14 +5552,14 @@ rule: <-- starts at col 1
         ;
 
 key_def:
-          normal_key_type opt_ident key_alg '(' key_list ')'
+          normal_key_type opt_if_not_exists_ident key_alg '(' key_list ')'
           { Lex->option_list= NULL; }
           normal_key_options
           {
             if (add_create_index (Lex, $1, $2))
               MYSQL_YYABORT;
           }
-        | fulltext opt_key_or_index opt_ident init_key_options 
+        | fulltext opt_key_or_index opt_if_not_exists_ident init_key_options 
             '(' key_list ')'
           { Lex->option_list= NULL; }
             fulltext_key_options
@@ -5559,7 +5567,7 @@ rule: <-- starts at col 1
             if (add_create_index (Lex, $1, $3))
               MYSQL_YYABORT;
           }
-        | spatial opt_key_or_index opt_ident init_key_options 
+        | spatial opt_key_or_index opt_if_not_exists_ident init_key_options 
             '(' key_list ')'
           { Lex->option_list= NULL; }
             spatial_key_options
@@ -5575,7 +5583,7 @@ rule: <-- starts at col 1
             if (add_create_index (Lex, $2, $3.str ? $3 : $1))
               MYSQL_YYABORT;
           }
-        | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
+        | opt_constraint FOREIGN KEY_SYM opt_if_not_exists_ident '(' key_list ')' references
           {
             LEX *lex=Lex;
             Key *key= new Foreign_key($4.str ? $4 : $1, lex->col_list,
@@ -5583,7 +5591,8 @@ rule: <-- starts at col 1
                                       lex->ref_list,
                                       lex->fk_delete_opt,
                                       lex->fk_update_opt,
-                                      lex->fk_match_option);
+                                      lex->fk_match_option,
+                                      lex->check_exists);
             if (key == NULL)
               MYSQL_YYABORT;
             lex->alter_info.key_list.push_back(key);
@@ -6552,6 +6561,18 @@ rule: <-- starts at col 1
         | field_ident { $$= $1; }
         ;
 
+opt_if_not_exists_ident:
+        opt_if_not_exists opt_ident
+        {
+          LEX *lex= Lex;
+          if (lex->check_exists && lex->sql_command != SQLCOM_ALTER_TABLE)
+          {
+            my_parse_error(ER(ER_SYNTAX_ERROR));
+            MYSQL_YYABORT;
+          }
+          $$= $2;
+        };
+
 opt_component:
           /* empty */    { $$= null_lex_str; }
         | '.' ident      { $$= $2; }
@@ -6808,7 +6829,7 @@ rule: <-- starts at col 1
   new table and so forth.
 */
         | add_partition_rule
-        | DROP PARTITION_SYM alt_part_name_list
+        | DROP PARTITION_SYM opt_if_exists alt_part_name_list
           {
             Lex->alter_info.flags|= ALTER_DROP_PARTITION;
           }
@@ -6909,7 +6930,7 @@ rule: <-- starts at col 1
         ;
 
 add_partition_rule:
-          ADD PARTITION_SYM opt_no_write_to_binlog
+          ADD PARTITION_SYM opt_if_not_exists opt_no_write_to_binlog
           {
             LEX *lex= Lex;
             lex->part_info= new partition_info();
@@ -6919,7 +6940,7 @@ rule: <-- starts at col 1
               MYSQL_YYABORT;
             }
             lex->alter_info.flags|= ALTER_ADD_PARTITION;
-            lex->no_write_to_binlog= $3;
+            lex->no_write_to_binlog= $4;
           }
           add_part_extra
           {}
@@ -6995,7 +7016,7 @@ rule: <-- starts at col 1
         ;
 
 add_column:
-          ADD opt_column
+          ADD opt_column opt_if_not_exists
           {
             LEX *lex=Lex;
             lex->change=0;
@@ -7017,10 +7038,10 @@ rule: <-- starts at col 1
           {
             Lex->alter_info.flags|= ALTER_ADD_COLUMN | ALTER_ADD_INDEX;
           }
-        | CHANGE opt_column field_ident
+        | CHANGE opt_column opt_if_exists field_ident
           {
             LEX *lex=Lex;
-            lex->change= $3.str;
+            lex->change= $4.str;
             lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
             lex->option_list= NULL;
           }
@@ -7028,7 +7049,7 @@ rule: <-- starts at col 1
           {
             Lex->create_last_non_select_table= Lex->last_table();
           }
-        | MODIFY_SYM opt_column field_ident
+        | MODIFY_SYM opt_column opt_if_exists field_ident
           {
             LEX *lex=Lex;
             lex->length=lex->dec=0; lex->type=0;
@@ -7042,12 +7063,12 @@ rule: <-- starts at col 1
           field_def
           {
             LEX *lex=Lex;
-            if (add_field_to_list(lex->thd,&$3,
-                                  (enum enum_field_types) $5,
+            if (add_field_to_list(lex->thd,&$4,
+                                  (enum enum_field_types) $6,
                                   lex->length,lex->dec,lex->type,
                                   lex->default_value, lex->on_update_value,
                                   &lex->comment,
-                                  $3.str, &lex->interval_list, lex->charset,
+                                  $4.str, &lex->interval_list, lex->charset,
                                   lex->uint_geom_type,
                                   lex->vcol_info, lex->option_list))
               MYSQL_YYABORT;
@@ -7056,32 +7077,33 @@ rule: <-- starts at col 1
           {
             Lex->create_last_non_select_table= Lex->last_table();
           }
-        | DROP opt_column field_ident opt_restrict
+        | DROP opt_column opt_if_exists field_ident opt_restrict
           {
             LEX *lex=Lex;
-            Alter_drop *ad= new Alter_drop(Alter_drop::COLUMN, $3.str);
+            Alter_drop *ad= new Alter_drop(Alter_drop::COLUMN, $4.str, $3);
             if (ad == NULL)
               MYSQL_YYABORT;
             lex->alter_info.drop_list.push_back(ad);
             lex->alter_info.flags|= ALTER_DROP_COLUMN;
           }
-        | DROP FOREIGN KEY_SYM opt_ident
+        | DROP FOREIGN KEY_SYM opt_if_exists opt_ident
           {
             Lex->alter_info.flags|= ALTER_DROP_INDEX | ALTER_FOREIGN_KEY;
           }
         | DROP PRIMARY_SYM KEY_SYM
           {
             LEX *lex=Lex;
-            Alter_drop *ad= new Alter_drop(Alter_drop::KEY, primary_key_name);
+            Alter_drop *ad= new Alter_drop(Alter_drop::KEY, primary_key_name,
+                                           FALSE);
             if (ad == NULL)
               MYSQL_YYABORT;
             lex->alter_info.drop_list.push_back(ad);
             lex->alter_info.flags|= ALTER_DROP_INDEX;
           }
-        | DROP key_or_index field_ident
+        | DROP key_or_index opt_if_exists field_ident
           {
             LEX *lex=Lex;
-            Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $3.str);
+            Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $4.str, $3);
             if (ad == NULL)
               MYSQL_YYABORT;
             lex->alter_info.drop_list.push_back(ad);
@@ -11002,41 +11024,41 @@ select_var_ident:  
 */
 
 drop:
-          DROP opt_temporary table_or_tables if_exists
+          DROP opt_temporary table_or_tables opt_if_exists
           {
             LEX *lex=Lex;
             lex->sql_command = SQLCOM_DROP_TABLE;
             lex->drop_temporary= $2;
-            lex->drop_if_exists= $4;
+            lex->check_exists= $4;
             YYPS->m_lock_type= TL_UNLOCK;
             YYPS->m_mdl_type= MDL_EXCLUSIVE;
           }
           table_list opt_restrict
           {}
-        | DROP INDEX_SYM ident ON table_ident {}
+        | DROP INDEX_SYM opt_if_exists ident ON table_ident {}
           {
             LEX *lex=Lex;
-            Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $3.str);
+            Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $4.str, $3);
             if (ad == NULL)
               MYSQL_YYABORT;
             lex->sql_command= SQLCOM_DROP_INDEX;
             lex->alter_info.reset();
             lex->alter_info.flags= ALTER_DROP_INDEX;
             lex->alter_info.drop_list.push_back(ad);
-            if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL,
+            if (!lex->current_select->add_table_to_list(lex->thd, $6, NULL,
                                                         TL_OPTION_UPDATING,
                                                         TL_READ_NO_INSERT,
                                                         MDL_SHARED_NO_WRITE))
               MYSQL_YYABORT;
           }
-        | DROP DATABASE if_exists ident
+        | DROP DATABASE opt_if_exists ident
           {
             LEX *lex=Lex;
             lex->sql_command= SQLCOM_DROP_DB;
-            lex->drop_if_exists=$3;
+            lex->check_exists=$3;
             lex->name= $4;
           }
-        | DROP FUNCTION_SYM if_exists ident '.' ident
+        | DROP FUNCTION_SYM opt_if_exists ident '.' ident
           {
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
@@ -11052,14 +11074,14 @@ select_var_ident:  
               MYSQL_YYABORT;
             }
             lex->sql_command = SQLCOM_DROP_FUNCTION;
-            lex->drop_if_exists= $3;
+            lex->check_exists= $3;
             spname= new sp_name($4, $6, true);
             if (spname == NULL)
               MYSQL_YYABORT;
             spname->init_qname(thd);
             lex->spname= spname;
           }
-        | DROP FUNCTION_SYM if_exists ident
+        | DROP FUNCTION_SYM opt_if_exists ident
           {
             THD *thd= YYTHD;
             LEX *lex= thd->lex;
@@ -11073,14 +11095,14 @@ select_var_ident:  
             if (thd->db && lex->copy_db_to(&db.str, &db.length))
               MYSQL_YYABORT;
             lex->sql_command = SQLCOM_DROP_FUNCTION;
-            lex->drop_if_exists= $3;
+            lex->check_exists= $3;
             spname= new sp_name(db, $4, false);
             if (spname == NULL)
               MYSQL_YYABORT;
             spname->init_qname(thd);
             lex->spname= spname;
           }
-        | DROP PROCEDURE_SYM if_exists sp_name
+        | DROP PROCEDURE_SYM opt_if_exists sp_name
           {
             LEX *lex=Lex;
             if (lex->sphead)
@@ -11089,34 +11111,34 @@ select_var_ident:  
               MYSQL_YYABORT;
             }
             lex->sql_command = SQLCOM_DROP_PROCEDURE;
-            lex->drop_if_exists= $3;
+            lex->check_exists= $3;
             lex->spname= $4;
           }
         | DROP USER clear_privileges user_list
           {
             Lex->sql_command = SQLCOM_DROP_USER;
           }
-        | DROP VIEW_SYM if_exists
+        | DROP VIEW_SYM opt_if_exists
           {
             LEX *lex= Lex;
             lex->sql_command= SQLCOM_DROP_VIEW;
-            lex->drop_if_exists= $3;
+            lex->check_exists= $3;
             YYPS->m_lock_type= TL_UNLOCK;
             YYPS->m_mdl_type= MDL_EXCLUSIVE;
           }
           table_list opt_restrict
           {}
-        | DROP EVENT_SYM if_exists sp_name
+        | DROP EVENT_SYM opt_if_exists sp_name
           {
-            Lex->drop_if_exists= $3;
+            Lex->check_exists= $3;
             Lex->spname= $4;
             Lex->sql_command = SQLCOM_DROP_EVENT;
           }
-        | DROP TRIGGER_SYM if_exists sp_name
+        | DROP TRIGGER_SYM opt_if_exists sp_name
           {
             LEX *lex= Lex;
             lex->sql_command= SQLCOM_DROP_TRIGGER;
-            lex->drop_if_exists= $3;
+            lex->check_exists= $3;
             lex->spname= $4;
           }
         | DROP TABLESPACE tablespace_name opt_ts_engine opt_ts_wait
@@ -11129,10 +11151,10 @@ select_var_ident:  
             LEX *lex= Lex;
             lex->alter_tablespace_info->ts_cmd_type= DROP_LOGFILE_GROUP;
           }
-        | DROP SERVER_SYM if_exists ident_or_text
+        | DROP SERVER_SYM opt_if_exists ident_or_text
           {
             Lex->sql_command = SQLCOM_DROP_SERVER;
-            Lex->drop_if_exists= $3;
+            Lex->check_exists= $3;
             Lex->server_options.server_name= $4.str;
             Lex->server_options.server_name_length= $4.length;
           }
@@ -11170,9 +11192,17 @@ select_var_ident:  
           }
         ;
 
-if_exists:
-          /* empty */ { $$= 0; }
-        | IF EXISTS { $$= 1; }
+opt_if_exists:
+          /* empty */
+        {
+          Lex->check_exists= FALSE;
+          $$= 0;
+        }
+        | IF EXISTS
+        {
+          Lex->check_exists= TRUE;
+          $$= 1;
+        }
         ;
 
 opt_temporary:



More information about the commits mailing list