diff --git a/sql/sql_list.h b/sql/sql_list.h
|
index f5d8ed98b02..f47300d6954 100644
|
--- a/sql/sql_list.h
|
+++ b/sql/sql_list.h
|
@@ -20,6 +20,7 @@
|
#endif
|
|
#include "sql_alloc.h"
|
+#include <iterator>
|
|
/**
|
Simple intrusive linked list.
|
@@ -524,6 +525,45 @@ template <class T> class List :public base_list
|
List<T> *res= new (mem_root) List<T>;
|
return res == NULL || res->push_back(first, mem_root) ? NULL : res;
|
}
|
+
|
+ class Iterator;
|
+ using value_type = T;
|
+ using iterator = Iterator;
|
+ using const_iterator = const Iterator;
|
+
|
+ Iterator begin() const { return Iterator(first); }
|
+ Iterator end() const { return Iterator(); }
|
+
|
+ class Iterator : public std::iterator<std::input_iterator_tag, T>
|
+ {
|
+ public:
|
+ Iterator(list_node *p= &end_of_list) : node{p} {}
|
+
|
+ Iterator &operator++()
|
+ {
|
+ DBUG_ASSERT(node != &end_of_list);
|
+
|
+ node= node->next;
|
+ return *this;
|
+ }
|
+
|
+ T operator++(int)
|
+ {
|
+ Iterator tmp(*this);
|
+ operator++();
|
+ return tmp;
|
+ }
|
+
|
+ T &operator*() { return *static_cast<T *>(node->info); }
|
+
|
+ bool operator!=(const typename List<T>::iterator &rhs)
|
+ {
|
+ return node != rhs.node;
|
+ }
|
+
|
+ private:
|
+ list_node *node{&end_of_list};
|
+ };
|
};
|
|
|
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
|
index 2fdfdb1c420..cac6f42ded7 100644
|
--- a/sql/sql_table.cc
|
+++ b/sql/sql_table.cc
|
@@ -54,6 +54,7 @@
|
#include "sql_audit.h"
|
#include "sql_sequence.h"
|
#include "tztime.h"
|
+#include <algorithm>
|
|
|
#ifdef __WIN__
|
@@ -3017,28 +3018,25 @@ CHARSET_INFO* get_sql_field_charset(Column_definition *sql_field,
|
|
void promote_first_timestamp_column(List<Create_field> *column_definitions)
|
{
|
- List_iterator_fast<Create_field> it(*column_definitions);
|
- Create_field *column_definition;
|
-
|
- while ((column_definition= it++) != NULL)
|
+ for (Create_field &column_definition : *column_definitions)
|
{
|
- if (column_definition->is_timestamp_type() || // TIMESTAMP
|
- column_definition->unireg_check == Field::TIMESTAMP_OLD_FIELD) // Legacy
|
+ if (column_definition.is_timestamp_type() || // TIMESTAMP
|
+ column_definition.unireg_check == Field::TIMESTAMP_OLD_FIELD) // Legacy
|
{
|
- DBUG_PRINT("info", ("field-ptr:%p", column_definition->field));
|
- if ((column_definition->flags & NOT_NULL_FLAG) != 0 && // NOT NULL,
|
- column_definition->default_value == NULL && // no constant default,
|
- column_definition->unireg_check == Field::NONE && // no function default
|
- column_definition->vcol_info == NULL &&
|
- column_definition->period == NULL &&
|
- !(column_definition->flags & VERS_SYSTEM_FIELD)) // column isn't generated
|
+ DBUG_PRINT("info", ("field-ptr:%p", column_definition.field));
|
+ if ((column_definition.flags & NOT_NULL_FLAG) != 0 && // NOT NULL,
|
+ column_definition.default_value == NULL && // no constant default,
|
+ column_definition.unireg_check == Field::NONE && // no function default
|
+ column_definition.vcol_info == NULL &&
|
+ column_definition.period == NULL &&
|
+ !(column_definition.flags & VERS_SYSTEM_FIELD)) // column isn't generated
|
{
|
DBUG_PRINT("info", ("First TIMESTAMP column '%s' was promoted to "
|
"DEFAULT CURRENT_TIMESTAMP ON UPDATE "
|
"CURRENT_TIMESTAMP",
|
- column_definition->field_name.str
|
+ column_definition.field_name.str
|
));
|
- column_definition->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
|
+ column_definition.unireg_check= Field::TIMESTAMP_DNUN_FIELD;
|
}
|
return;
|
}
|
@@ -3066,21 +3064,17 @@ static void check_duplicate_key(THD *thd, Key *key, KEY *key_info,
|
if (!key->key_create_info.check_for_duplicate_indexes || key->generated)
|
return;
|
|
- List_iterator_fast<Key> key_list_iterator(*key_list);
|
- List_iterator_fast<Key_part_spec> key_column_iterator(key->columns);
|
- Key *k;
|
-
|
- while ((k= key_list_iterator++))
|
+ for (const Key &k : *key_list)
|
{
|
// Looking for a similar key...
|
|
- if (k == key)
|
+ if (&k == key)
|
break;
|
|
- if (k->generated ||
|
- (key->type != k->type) ||
|
- (key->key_create_info.algorithm != k->key_create_info.algorithm) ||
|
- (key->columns.elements != k->columns.elements))
|
+ if (k.generated ||
|
+ (key->type != k.type) ||
|
+ (key->key_create_info.algorithm != k.key_create_info.algorithm) ||
|
+ (key->columns.elements != k.columns.elements))
|
{
|
// Keys are different.
|
continue;
|
@@ -3091,31 +3085,16 @@ static void check_duplicate_key(THD *thd, Key *key, KEY *key_info,
|
Check that the keys have identical columns in the same order.
|
*/
|
|
- List_iterator_fast<Key_part_spec> k_column_iterator(k->columns);
|
- uint i;
|
- key_column_iterator.rewind();
|
-
|
- for (i= 0; i < key->columns.elements; ++i)
|
- {
|
- Key_part_spec *c1= key_column_iterator++;
|
- Key_part_spec *c2= k_column_iterator++;
|
-
|
- DBUG_ASSERT(c1 && c2);
|
-
|
- if (lex_string_cmp(system_charset_info,
|
- &c1->field_name, &c2->field_name) ||
|
- (c1->length != c2->length))
|
- break;
|
- }
|
-
|
- // Report a warning if we have two identical keys.
|
-
|
- if (i == key->columns.elements)
|
+ if (std::equal(key->columns.begin(), key->columns.end(), k.columns.begin(),
|
+ [](const Key_part_spec &a, const Key_part_spec &b) {
|
+ return !lex_string_cmp(system_charset_info, &a.field_name,
|
+ &b.field_name) &&
|
+ a.length == b.length;
|
+ }))
|
{
|
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
|
- ER_DUP_INDEX, ER_THD(thd, ER_DUP_INDEX),
|
- key_info->name.str);
|
- break;
|
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_DUP_INDEX,
|
+ ER_THD(thd, ER_DUP_INDEX), key_info->name.str);
|
+ return;
|
}
|
}
|
}
|
|
Adding my prototype: the simplest (and fastest) possible implementation, works with <algorithm> functions.
diff --git a/sql/sql_list.h b/sql/sql_list.h
index f5d8ed98b02..f47300d6954 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -20,6 +20,7 @@
#endif
#include "sql_alloc.h"
+#include <iterator>
/**
Simple intrusive linked list.
@@ -524,6 +525,45 @@ template <class T> class List :public base_list
List<T> *res= new (mem_root) List<T>;
return res == NULL || res->push_back(first, mem_root) ? NULL : res;
}
+
+ class Iterator;
+ using value_type = T;
+ using iterator = Iterator;
+ using const_iterator = const Iterator;
+
+ Iterator begin() const { return Iterator(first); }
+ Iterator end() const { return Iterator(); }
+
+ class Iterator : public std::iterator<std::input_iterator_tag, T>
+ {
+ public:
+ Iterator(list_node *p= &end_of_list) : node{p} {}
+
+ Iterator &operator++()
+ {
+ DBUG_ASSERT(node != &end_of_list);
+
+ node= node->next;
+ return *this;
+ }
+
+ T operator++(int)
+ {
+ Iterator tmp(*this);
+ operator++();
+ return tmp;
+ }
+
+ T &operator*() { return *static_cast<T *>(node->info); }
+
+ bool operator!=(const typename List<T>::iterator &rhs)
+ {
+ return node != rhs.node;
+ }
+
+ private:
+ list_node *node{&end_of_list};
+ };
};
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 2fdfdb1c420..cac6f42ded7 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -54,6 +54,7 @@
#include "sql_audit.h"
#include "sql_sequence.h"
#include "tztime.h"
+#include <algorithm>
#ifdef __WIN__
@@ -3017,28 +3018,25 @@ CHARSET_INFO* get_sql_field_charset(Column_definition *sql_field,
void promote_first_timestamp_column(List<Create_field> *column_definitions)
{
- List_iterator_fast<Create_field> it(*column_definitions);
- Create_field *column_definition;
-
- while ((column_definition= it++) != NULL)
+ for (Create_field &column_definition : *column_definitions)
{
- if (column_definition->is_timestamp_type() || // TIMESTAMP
- column_definition->unireg_check == Field::TIMESTAMP_OLD_FIELD) // Legacy
+ if (column_definition.is_timestamp_type() || // TIMESTAMP
+ column_definition.unireg_check == Field::TIMESTAMP_OLD_FIELD) // Legacy
{
- DBUG_PRINT("info", ("field-ptr:%p", column_definition->field));
- if ((column_definition->flags & NOT_NULL_FLAG) != 0 && // NOT NULL,
- column_definition->default_value == NULL && // no constant default,
- column_definition->unireg_check == Field::NONE && // no function default
- column_definition->vcol_info == NULL &&
- column_definition->period == NULL &&
- !(column_definition->flags & VERS_SYSTEM_FIELD)) // column isn't generated
+ DBUG_PRINT("info", ("field-ptr:%p", column_definition.field));
+ if ((column_definition.flags & NOT_NULL_FLAG) != 0 && // NOT NULL,
+ column_definition.default_value == NULL && // no constant default,
+ column_definition.unireg_check == Field::NONE && // no function default
+ column_definition.vcol_info == NULL &&
+ column_definition.period == NULL &&
+ !(column_definition.flags & VERS_SYSTEM_FIELD)) // column isn't generated
{
DBUG_PRINT("info", ("First TIMESTAMP column '%s' was promoted to "
"DEFAULT CURRENT_TIMESTAMP ON UPDATE "
"CURRENT_TIMESTAMP",
- column_definition->field_name.str
+ column_definition.field_name.str
));
- column_definition->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
+ column_definition.unireg_check= Field::TIMESTAMP_DNUN_FIELD;
}
return;
}
@@ -3066,21 +3064,17 @@ static void check_duplicate_key(THD *thd, Key *key, KEY *key_info,
if (!key->key_create_info.check_for_duplicate_indexes || key->generated)
return;
- List_iterator_fast<Key> key_list_iterator(*key_list);
- List_iterator_fast<Key_part_spec> key_column_iterator(key->columns);
- Key *k;
-
- while ((k= key_list_iterator++))
+ for (const Key &k : *key_list)
{
// Looking for a similar key...
- if (k == key)
+ if (&k == key)
break;
- if (k->generated ||
- (key->type != k->type) ||
- (key->key_create_info.algorithm != k->key_create_info.algorithm) ||
- (key->columns.elements != k->columns.elements))
+ if (k.generated ||
+ (key->type != k.type) ||
+ (key->key_create_info.algorithm != k.key_create_info.algorithm) ||
+ (key->columns.elements != k.columns.elements))
{
// Keys are different.
continue;
@@ -3091,31 +3085,16 @@ static void check_duplicate_key(THD *thd, Key *key, KEY *key_info,
Check that the keys have identical columns in the same order.
*/
- List_iterator_fast<Key_part_spec> k_column_iterator(k->columns);
- uint i;
- key_column_iterator.rewind();
-
- for (i= 0; i < key->columns.elements; ++i)
- {
- Key_part_spec *c1= key_column_iterator++;
- Key_part_spec *c2= k_column_iterator++;
-
- DBUG_ASSERT(c1 && c2);
-
- if (lex_string_cmp(system_charset_info,
- &c1->field_name, &c2->field_name) ||
- (c1->length != c2->length))
- break;
- }
-
- // Report a warning if we have two identical keys.
-
- if (i == key->columns.elements)
+ if (std::equal(key->columns.begin(), key->columns.end(), k.columns.begin(),
+ [](const Key_part_spec &a, const Key_part_spec &b) {
+ return !lex_string_cmp(system_charset_info, &a.field_name,
+ &b.field_name) &&
+ a.length == b.length;
+ }))
{
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
- ER_DUP_INDEX, ER_THD(thd, ER_DUP_INDEX),
- key_info->name.str);
- break;
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_DUP_INDEX,
+ ER_THD(thd, ER_DUP_INDEX), key_info->name.str);
+ return;
}
}
}