summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <marko@hundin.mysql.fi>2004-04-23 11:03:52 +0300
committerunknown <marko@hundin.mysql.fi>2004-04-23 11:03:52 +0300
commit9a8a680beb54e4236578ce7155323c0e3b2d1bea (patch)
treecbf10db887bdf375085f401d457be74c2b0e191d /sql
parentef20f83ef1c97eaa6fb57a3d6690fad93d083d6f (diff)
parentc9e1538298ccfc2172d4db06df54f0f321b7db09 (diff)
downloadmariadb-git-9a8a680beb54e4236578ce7155323c0e3b2d1bea.tar.gz
Merge marko@build.mysql.com:/home/bk/mysql-4.1
into hundin.mysql.fi:/home/marko/j/mysql-4.1
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_class.cc28
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_table.cc33
-rw-r--r--sql/sql_yacc.yy4
4 files changed, 63 insertions, 5 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 1b4c8bec416..f297ddf2917 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -79,6 +79,34 @@ extern "C" void free_user_var(user_var_entry *entry)
}
+bool key_part_spec::operator==(const key_part_spec& other) const
+{
+ return length == other.length && !strcmp(field_name, other.field_name);
+}
+
+/* Equality comparison of keys (ignoring name) */
+bool Key::operator==(Key& other)
+{
+ if (type == other.type &&
+ algorithm == other.algorithm &&
+ columns.elements == other.columns.elements)
+ {
+ List_iterator<key_part_spec> col_it1(columns);
+ List_iterator<key_part_spec> col_it2(other.columns);
+ const key_part_spec *col1, *col2;
+ while ((col1 = col_it1++))
+ {
+ col2 = col_it2++;
+ DBUG_ASSERT(col2 != NULL);
+ if (!(*col1 == *col2))
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+
/****************************************************************************
** Thread specific functions
****************************************************************************/
diff --git a/sql/sql_class.h b/sql/sql_class.h
index d5eb7a9fd0e..a2094d8fe7c 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -210,6 +210,7 @@ public:
const char *field_name;
uint length;
key_part_spec(const char *name,uint len=0) :field_name(name), length(len) {}
+ bool operator==(const key_part_spec& other) const;
};
@@ -245,6 +246,8 @@ public:
:type(type_par), algorithm(alg_par), columns(cols), name(name_arg)
{}
~Key() {}
+ /* Equality comparison of keys (ignoring name) */
+ bool operator==(Key& other);
};
class Table_ident;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index c46a9823a52..d00cb7ed546 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -639,12 +639,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
/* Create keys */
- List_iterator<Key> key_iterator(keys);
+ List_iterator<Key> key_iterator(keys), key_iterator2(keys);
uint key_parts=0, fk_key_count=0;
- List<Key> keys_in_order; // Add new keys here
bool primary_key=0,unique_key=0;
- Key *key;
+ Key *key, *key2;
uint tmp, key_number;
+ /* special marker for keys to be ignored */
+ static char ignore_key[1];
/* Calculate number of key segements */
*key_count= 0;
@@ -677,7 +678,21 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
my_error(ER_TOO_LONG_IDENT, MYF(0), key->name);
DBUG_RETURN(-1);
}
- key_parts+=key->columns.elements;
+ key_iterator2.rewind ();
+ while ((key2 = key_iterator2++) != key)
+ {
+ if (*key == *key2)
+ {
+ /* TO DO: issue warning message */
+ /* mark that the key should be ignored */
+ key->name=ignore_key;
+ break;
+ }
+ }
+ if (key->name != ignore_key)
+ key_parts+=key->columns.elements;
+ else
+ (*key_count)--;
if (key->name && !tmp_table &&
!my_strcasecmp(system_charset_info,key->name,primary_key_name))
{
@@ -704,6 +719,16 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
uint key_length=0;
key_part_spec *column;
+ if (key->name == ignore_key)
+ {
+ /* ignore redundant keys */
+ do
+ key=key_iterator++;
+ while (key && key->name == ignore_key);
+ if (!key)
+ break;
+ }
+
switch(key->type){
case Key::MULTIPLE:
key_info->flags = 0;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 568a526fd58..85257f90fe0 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1200,12 +1200,14 @@ key_def:
| opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
{
LEX *lex=Lex;
- lex->key_list.push_back(new foreign_key($4, lex->col_list,
+ lex->key_list.push_back(new foreign_key($4 ? $4:$1, lex->col_list,
$8,
lex->ref_list,
lex->fk_delete_opt,
lex->fk_update_opt,
lex->fk_match_option));
+ lex->key_list.push_back(new Key(Key::MULTIPLE, $4 ? $4:$1,
+ HA_KEY_ALG_UNDEF, lex->col_list));
lex->col_list.empty(); /* Alloced by sql_alloc */
}
| opt_constraint check_constraint