summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
authorSergey Glukhov <sergey.glukhov@oracle.com>2010-12-13 15:11:16 +0300
committerSergey Glukhov <sergey.glukhov@oracle.com>2010-12-13 15:11:16 +0300
commite52e64ac35670a7359b16bff5c0073aa13d3abc3 (patch)
treea593fa4030c4a1f54c1869a03d249138e310744c /sql/handler.cc
parent8394b6a2713ff0823448aa62eea1251bfb2f9e03 (diff)
parent1faf910eeb4e8f40253bf34b634af5332f367dc5 (diff)
downloadmariadb-git-e52e64ac35670a7359b16bff5c0073aa13d3abc3.tar.gz
5.1-bugteam->5.5-bugteam merge
Diffstat (limited to 'sql/handler.cc')
-rw-r--r--sql/handler.cc30
1 files changed, 22 insertions, 8 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index 38b57c16ee0..069422a7245 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -2209,7 +2209,8 @@ int handler::read_first_row(uchar * buf, uint primary_key)
computes the lowest number
- strictly greater than "nr"
- of the form: auto_increment_offset + N * auto_increment_increment
-
+ If overflow happened then return MAX_ULONGLONG value as an
+ indication of overflow.
In most cases increment= offset= 1, in which case we get:
@verbatim 1,2,3,4,5,... @endverbatim
If increment=10 and offset=5 and previous number is 1, we get:
@@ -2218,13 +2219,23 @@ int handler::read_first_row(uchar * buf, uint primary_key)
inline ulonglong
compute_next_insert_id(ulonglong nr,struct system_variables *variables)
{
+ const ulonglong save_nr= nr;
+
if (variables->auto_increment_increment == 1)
- return (nr+1); // optimization of the formula below
- nr= (((nr+ variables->auto_increment_increment -
- variables->auto_increment_offset)) /
- (ulonglong) variables->auto_increment_increment);
- return (nr* (ulonglong) variables->auto_increment_increment +
- variables->auto_increment_offset);
+ nr= nr + 1; // optimization of the formula below
+ else
+ {
+ nr= (((nr+ variables->auto_increment_increment -
+ variables->auto_increment_offset)) /
+ (ulonglong) variables->auto_increment_increment);
+ nr= (nr* (ulonglong) variables->auto_increment_increment +
+ variables->auto_increment_offset);
+ }
+
+ if (unlikely(nr <= save_nr))
+ return ULONGLONG_MAX;
+
+ return nr;
}
@@ -2435,7 +2446,7 @@ int handler::update_auto_increment()
variables->auto_increment_increment,
nb_desired_values, &nr,
&nb_reserved_values);
- if (nr == ~(ulonglong) 0)
+ if (nr == ULONGLONG_MAX)
DBUG_RETURN(HA_ERR_AUTOINC_READ_FAILED); // Mark failure
/*
@@ -2466,6 +2477,9 @@ int handler::update_auto_increment()
}
}
+ if (unlikely(nr == ULONGLONG_MAX))
+ DBUG_RETURN(HA_ERR_AUTOINC_ERANGE);
+
DBUG_PRINT("info",("auto_increment: %lu", (ulong) nr));
if (unlikely(table->next_number_field->store((longlong) nr, TRUE)))