mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 11:01:52 +01:00
branches/5.1: Change the InnoDB autoinc type to ulint64. For this added a
new typedef to univ.i (ib_ulonglong). Added checks for overflow and removed the assertion where it crashed previously, since the type has now changed to unsigned, it doesn't make sense to check for < 0. Added new tests, to check for overflow, for the different INT types supported for both signed and unsigned. Fixes Bug# 34335
This commit is contained in:
parent
1e130ba621
commit
b657301e96
10 changed files with 218 additions and 28 deletions
|
@ -429,7 +429,7 @@ void
|
|||
dict_table_autoinc_initialize(
|
||||
/*==========================*/
|
||||
dict_table_t* table, /* in: table */
|
||||
ib_longlong value) /* in: next value to assign to a row */
|
||||
ib_ulonglong value) /* in: next value to assign to a row */
|
||||
{
|
||||
ut_ad(mutex_own(&table->autoinc_mutex));
|
||||
|
||||
|
@ -441,7 +441,7 @@ dict_table_autoinc_initialize(
|
|||
Reads the next autoinc value (== autoinc counter value), 0 if not yet
|
||||
initialized. */
|
||||
|
||||
ib_longlong
|
||||
ib_ulonglong
|
||||
dict_table_autoinc_read(
|
||||
/*====================*/
|
||||
/* out: value for a new row, or 0 */
|
||||
|
@ -470,7 +470,7 @@ dict_table_autoinc_update(
|
|||
/*======================*/
|
||||
|
||||
dict_table_t* table, /* in: table */
|
||||
ib_longlong value) /* in: value which was assigned to a row */
|
||||
ib_ulonglong value) /* in: value which was assigned to a row */
|
||||
{
|
||||
if (table->autoinc_inited && value > table->autoinc) {
|
||||
|
||||
|
|
|
@ -3549,7 +3549,19 @@ no_commit:
|
|||
if (auto_inc > prebuilt->last_value) {
|
||||
set_max_autoinc:
|
||||
ut_a(prebuilt->table->autoinc_increment > 0);
|
||||
auto_inc += prebuilt->table->autoinc_increment;
|
||||
|
||||
ulonglong have;
|
||||
ulonglong need;
|
||||
|
||||
/* Check for overflow conditions. */
|
||||
need = prebuilt->table->autoinc_increment;
|
||||
have = ~0x0ULL - auto_inc;
|
||||
|
||||
if (have < need) {
|
||||
need = have;
|
||||
}
|
||||
|
||||
auto_inc += need;
|
||||
|
||||
err = innobase_set_max_autoinc(auto_inc);
|
||||
|
||||
|
@ -5867,7 +5879,7 @@ ha_innobase::info(
|
|||
}
|
||||
|
||||
if (flag & HA_STATUS_AUTO && table->found_next_number_field) {
|
||||
longlong auto_inc;
|
||||
ulonglong auto_inc;
|
||||
int ret;
|
||||
|
||||
/* The following function call can the first time fail in
|
||||
|
@ -7218,9 +7230,9 @@ ha_innobase::innobase_read_and_init_auto_inc(
|
|||
/*=========================================*/
|
||||
/* out: 0 or generic MySQL
|
||||
error code */
|
||||
longlong* value) /* out: the autoinc value */
|
||||
ulonglong* value) /* out: the autoinc value */
|
||||
{
|
||||
longlong auto_inc;
|
||||
ulonglong auto_inc;
|
||||
ibool stmt_start;
|
||||
int mysql_error = 0;
|
||||
dict_table_t* innodb_table = prebuilt->table;
|
||||
|
@ -7271,7 +7283,9 @@ ha_innobase::innobase_read_and_init_auto_inc(
|
|||
index, autoinc_col_name, &auto_inc);
|
||||
|
||||
if (error == DB_SUCCESS) {
|
||||
++auto_inc;
|
||||
if (auto_inc < ~0x0ULL) {
|
||||
++auto_inc;
|
||||
}
|
||||
dict_table_autoinc_initialize(innodb_table, auto_inc);
|
||||
} else {
|
||||
ut_print_timestamp(stderr);
|
||||
|
@ -7324,14 +7338,14 @@ ha_innobase::innobase_get_auto_increment(
|
|||
error = innobase_autoinc_lock();
|
||||
|
||||
if (error == DB_SUCCESS) {
|
||||
ib_longlong autoinc;
|
||||
ulonglong autoinc;
|
||||
|
||||
/* Determine the first value of the interval */
|
||||
autoinc = dict_table_autoinc_read(prebuilt->table);
|
||||
|
||||
/* We need to initialize the AUTO-INC value, for
|
||||
that we release all locks.*/
|
||||
if (autoinc <= 0) {
|
||||
if (autoinc == 0) {
|
||||
trx_t* trx;
|
||||
|
||||
trx = prebuilt->trx;
|
||||
|
@ -7350,14 +7364,11 @@ ha_innobase::innobase_get_auto_increment(
|
|||
mysql_error = innobase_read_and_init_auto_inc(
|
||||
&autoinc);
|
||||
|
||||
if (!mysql_error) {
|
||||
/* Should have read the proper value */
|
||||
ut_a(autoinc > 0);
|
||||
} else {
|
||||
if (mysql_error) {
|
||||
error = DB_ERROR;
|
||||
}
|
||||
} else {
|
||||
*value = (ulonglong) autoinc;
|
||||
*value = autoinc;
|
||||
}
|
||||
/* A deadlock error during normal processing is OK
|
||||
and can be ignored. */
|
||||
|
@ -7442,10 +7453,19 @@ ha_innobase::get_auto_increment(
|
|||
/* With old style AUTOINC locking we only update the table's
|
||||
AUTOINC counter after attempting to insert the row. */
|
||||
if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
|
||||
ulonglong have;
|
||||
ulonglong need;
|
||||
|
||||
/* Check for overflow conditions. */
|
||||
need = *nb_reserved_values * increment;
|
||||
have = ~0x0ULL - *first_value;
|
||||
|
||||
if (have < need) {
|
||||
need = have;
|
||||
}
|
||||
|
||||
/* Compute the last value in the interval */
|
||||
prebuilt->last_value = *first_value +
|
||||
(*nb_reserved_values * increment);
|
||||
prebuilt->last_value = *first_value + need;
|
||||
|
||||
ut_a(prebuilt->last_value >= *first_value);
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ class ha_innobase: public handler
|
|||
int update_thd(THD* thd);
|
||||
int change_active_index(uint keynr);
|
||||
int general_fetch(uchar* buf, uint direction, uint match_mode);
|
||||
int innobase_read_and_init_auto_inc(longlong* ret);
|
||||
int innobase_read_and_init_auto_inc(ulonglong* ret);
|
||||
ulong innobase_autoinc_lock();
|
||||
ulong innobase_set_max_autoinc(ulonglong auto_inc);
|
||||
ulong innobase_reset_autoinc(ulonglong auto_inc);
|
||||
|
|
|
@ -185,12 +185,12 @@ void
|
|||
dict_table_autoinc_initialize(
|
||||
/*==========================*/
|
||||
dict_table_t* table, /* in: table */
|
||||
ib_longlong value); /* in: next value to assign to a row */
|
||||
ib_ulonglong value); /* in: next value to assign to a row */
|
||||
/************************************************************************
|
||||
Reads the next autoinc value (== autoinc counter value), 0 if not yet
|
||||
initialized. */
|
||||
|
||||
ib_longlong
|
||||
ib_ulonglong
|
||||
dict_table_autoinc_read(
|
||||
/*====================*/
|
||||
/* out: value for a new row, or 0 */
|
||||
|
@ -204,7 +204,7 @@ dict_table_autoinc_update(
|
|||
/*======================*/
|
||||
|
||||
dict_table_t* table, /* in: table */
|
||||
ib_longlong value); /* in: value which was assigned to a row */
|
||||
ib_ulonglong value); /* in: value which was assigned to a row */
|
||||
/************************************************************************
|
||||
Release the autoinc lock.*/
|
||||
|
||||
|
|
|
@ -409,7 +409,7 @@ struct dict_table_struct{
|
|||
/* TRUE if the autoinc counter has been
|
||||
inited; MySQL gets the init value by executing
|
||||
SELECT MAX(auto inc column) */
|
||||
ib_longlong autoinc;/* autoinc counter value to give to the
|
||||
ib_ulonglong autoinc;/* autoinc counter value to give to the
|
||||
next inserted row */
|
||||
|
||||
ib_longlong autoinc_increment;
|
||||
|
|
|
@ -181,7 +181,7 @@ row_search_max_autoinc(
|
|||
error code */
|
||||
dict_index_t* index, /* in: index to search */
|
||||
const char* col_name, /* in: autoinc column name */
|
||||
ib_longlong* value); /* out: AUTOINC value read */
|
||||
ib_ulonglong* value); /* out: AUTOINC value read */
|
||||
|
||||
/* A structure for caching column values for prefetched rows */
|
||||
struct sel_buf_struct{
|
||||
|
|
|
@ -212,8 +212,11 @@ typedef long int lint;
|
|||
|
||||
#ifdef __WIN__
|
||||
typedef __int64 ib_longlong;
|
||||
typedef unsigned __int64 ib_ulonglong;
|
||||
#else
|
||||
/* Note: longlong and ulonglong come from MySQL headers. */
|
||||
typedef longlong ib_longlong;
|
||||
typedef ulonglong ib_ulonglong;
|
||||
#endif
|
||||
|
||||
typedef unsigned long long int ullint;
|
||||
|
|
60
mysql-test/innodb-autoinc.result
Normal file
60
mysql-test/innodb-autoinc.result
Normal file
|
@ -0,0 +1,60 @@
|
|||
drop table if exists t1;
|
||||
CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (9223372036854775807, null);
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
Got one of the listed errors
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 TINYINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (127, null);
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
Got one of the listed errors
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 TINYINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (255, null);
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
Got one of the listed errors
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 SMALLINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (32767, null);
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
Got one of the listed errors
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 SMALLINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (65535, null);
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'c1' at row 1
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
Got one of the listed errors
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 MEDIUMINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (8388607, null);
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
Got one of the listed errors
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 MEDIUMINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (16777215, null);
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
Got one of the listed errors
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (2147483647, null);
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
Got one of the listed errors
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (4294967295, null);
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
Got one of the listed errors
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (9223372036854775807, null);
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
Got one of the listed errors
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (18446744073709551615, null);
|
||||
Warnings:
|
||||
Warning 1264 Out of range value for column 'c1' at row 1
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
Got one of the listed errors
|
||||
DROP TABLE t1;
|
107
mysql-test/innodb-autoinc.test
Normal file
107
mysql-test/innodb-autoinc.test
Normal file
|
@ -0,0 +1,107 @@
|
|||
-- source include/have_innodb.inc
|
||||
# embedded server ignores 'delayed', so skip this
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
#
|
||||
# Bug #34335
|
||||
#
|
||||
CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (9223372036854775807, null);
|
||||
-- error ER_DUP_ENTRY,1062
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
## Test AUTOINC overflow
|
||||
##
|
||||
|
||||
# TINYINT
|
||||
CREATE TABLE t1 (c1 TINYINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (127, null);
|
||||
-- error ER_DUP_ENTRY,1062
|
||||
-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (c1 TINYINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (255, null);
|
||||
-- error ER_DUP_ENTRY,1062
|
||||
-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# SMALLINT
|
||||
#
|
||||
CREATE TABLE t1 (c1 SMALLINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (32767, null);
|
||||
-- error ER_DUP_ENTRY,1062
|
||||
-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (c1 SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (65535, null);
|
||||
-- error ER_DUP_ENTRY,1062
|
||||
-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# MEDIUMINT
|
||||
#
|
||||
CREATE TABLE t1 (c1 MEDIUMINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (8388607, null);
|
||||
-- error ER_DUP_ENTRY,1062
|
||||
-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (c1 MEDIUMINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (16777215, null);
|
||||
-- error ER_DUP_ENTRY,1062
|
||||
-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# INT
|
||||
#
|
||||
CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (2147483647, null);
|
||||
-- error ER_DUP_ENTRY,1062
|
||||
-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (c1 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (4294967295, null);
|
||||
-- error ER_DUP_ENTRY,1062
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# BIGINT
|
||||
#
|
||||
CREATE TABLE t1 (c1 BIGINT PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (9223372036854775807, null);
|
||||
-- error ER_DUP_ENTRY,1062
|
||||
-- warning ER_WARN_DATA_OUT_OF_RANGE,1264
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1 (c1 BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, c2 VARCHAR(10)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (18446744073709551615, null);
|
||||
-- error ER_AUTOINC_READ_FAILED,1467
|
||||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
|
@ -4529,7 +4529,7 @@ row_search_check_if_query_cache_permitted(
|
|||
Read the AUTOINC column from the current row. If the value is less than
|
||||
0 and the type is not unsigned then we reset the value to 0. */
|
||||
static
|
||||
ib_longlong
|
||||
ib_ulonglong
|
||||
row_search_autoinc_read_column(
|
||||
/*===========================*/
|
||||
/* out: value read from the column */
|
||||
|
@ -4540,7 +4540,7 @@ row_search_autoinc_read_column(
|
|||
{
|
||||
ulint len;
|
||||
const byte* data;
|
||||
ib_longlong value;
|
||||
ib_ulonglong value;
|
||||
mem_heap_t* heap = NULL;
|
||||
/* Our requirement is that dest should be word aligned. */
|
||||
byte dest[sizeof(value)];
|
||||
|
@ -4567,7 +4567,7 @@ row_search_autoinc_read_column(
|
|||
and that dest is word aligned. */
|
||||
switch (len) {
|
||||
case 8:
|
||||
value = *(ib_longlong*) dest;
|
||||
value = *(ib_ulonglong*) dest;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
|
@ -4595,7 +4595,7 @@ row_search_autoinc_read_column(
|
|||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
if (!unsigned_type && value < 0) {
|
||||
if (!unsigned_type && (ib_longlong) value < 0) {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
|
@ -4634,7 +4634,7 @@ row_search_max_autoinc(
|
|||
column name can't be found in index */
|
||||
dict_index_t* index, /* in: index to search */
|
||||
const char* col_name, /* in: name of autoinc column */
|
||||
ib_longlong* value) /* out: AUTOINC value read */
|
||||
ib_ulonglong* value) /* out: AUTOINC value read */
|
||||
{
|
||||
ulint i;
|
||||
ulint n_cols;
|
||||
|
|
Loading…
Add table
Reference in a new issue