Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
b2f5a1ee
Commit
b2f5a1ee
authored
Jul 30, 2006
by
ingo/mydev@chilla.local
Browse files
Options
Browse Files
Download
Plain Diff
Merge chilla.local:/home/mydev/mysql-5.0
into chilla.local:/home/mydev/mysql-5.0-bug20719
parents
50b630ba
1962eaaf
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
424 additions
and
58 deletions
+424
-58
myisam/mi_dynrec.c
myisam/mi_dynrec.c
+130
-29
mysql-test/r/rpl_auto_increment.result
mysql-test/r/rpl_auto_increment.result
+44
-0
mysql-test/r/rpl_insert_id.result
mysql-test/r/rpl_insert_id.result
+65
-0
mysql-test/t/rpl_auto_increment.test
mysql-test/t/rpl_auto_increment.test
+39
-1
mysql-test/t/rpl_insert_id.test
mysql-test/t/rpl_insert_id.test
+63
-0
sql/handler.cc
sql/handler.cc
+72
-13
sql/handler.h
sql/handler.h
+1
-0
sql/sql_base.cc
sql/sql_base.cc
+3
-2
sql/sql_insert.cc
sql/sql_insert.cc
+7
-13
No files found.
myisam/mi_dynrec.c
View file @
b2f5a1ee
...
...
@@ -1130,12 +1130,41 @@ void _my_store_blob_length(byte *pos,uint pack_length,uint length)
}
/* Read record from datafile */
/* Returns 0 if ok, -1 if error */
/*
Read record from datafile.
SYNOPSIS
_mi_read_dynamic_record()
info MI_INFO pointer to table.
filepos From where to read the record.
buf Destination for record.
NOTE
If a write buffer is active, it needs to be flushed if its contents
intersects with the record to read. We always check if the position
of the first byte of the write buffer is lower than the position
past the last byte to read. In theory this is also true if the write
buffer is completely below the read segment. That is, if there is no
intersection. But this case is unusual. We flush anyway. Only if the
first byte in the write buffer is above the last byte to read, we do
not flush.
A dynamic record may need several reads. So this check must be done
before every read. Reading a dynamic record starts with reading the
block header. If the record does not fit into the free space of the
header, the block may be longer than the header. In this case a
second read is necessary. These one or two reads repeat for every
part of the record.
RETURN
0 OK
-1 Error
*/
int
_mi_read_dynamic_record
(
MI_INFO
*
info
,
my_off_t
filepos
,
byte
*
buf
)
{
int
flag
;
int
block_of_record
;
uint
b_type
,
left_length
;
byte
*
to
;
MI_BLOCK_INFO
block_info
;
...
...
@@ -1147,20 +1176,19 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf)
LINT_INIT
(
to
);
LINT_INIT
(
left_length
);
file
=
info
->
dfile
;
block_
info
.
next_filepos
=
filepos
;
/* for easyer loop
*/
flag
=
block_info
.
second_read
=
0
;
block_
of_record
=
0
;
/* First block of record is numbered as zero.
*/
block_info
.
second_read
=
0
;
do
{
/* A corrupted table can have wrong pointers. (Bug# 19835) */
if
(
filepos
==
HA_OFFSET_ERROR
)
goto
panic
;
if
(
info
->
opt_flag
&
WRITE_CACHE_USED
&&
info
->
rec_cache
.
pos_in_file
<
=
block_info
.
next_filepos
&&
info
->
rec_cache
.
pos_in_file
<
filepos
+
MI_BLOCK_INFO_HEADER_LENGTH
&&
flush_io_cache
(
&
info
->
rec_cache
))
goto
err
;
/* A corrupted table can have wrong pointers. (Bug# 19835) */
if
(
block_info
.
next_filepos
==
HA_OFFSET_ERROR
)
goto
panic
;
info
->
rec_cache
.
seek_not_done
=
1
;
if
((
b_type
=
_mi_get_block_info
(
&
block_info
,
file
,
block_info
.
next_filepos
))
if
((
b_type
=
_mi_get_block_info
(
&
block_info
,
file
,
filepos
))
&
(
BLOCK_DELETED
|
BLOCK_ERROR
|
BLOCK_SYNC_ERROR
|
BLOCK_FATAL_ERROR
))
{
...
...
@@ -1168,9 +1196,8 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf)
my_errno
=
HA_ERR_RECORD_DELETED
;
goto
err
;
}
if
(
flag
==
0
)
/* First block */
if
(
block_of_record
++
==
0
)
/* First block */
{
flag
=
1
;
if
(
block_info
.
rec_len
>
(
uint
)
info
->
s
->
base
.
max_pack_length
)
goto
panic
;
if
(
info
->
s
->
base
.
blobs
)
...
...
@@ -1185,11 +1212,35 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf)
}
if
(
left_length
<
block_info
.
data_len
||
!
block_info
.
data_len
)
goto
panic
;
/* Wrong linked record */
if
(
my_pread
(
file
,(
byte
*
)
to
,
block_info
.
data_len
,
block_info
.
filepos
,
MYF
(
MY_NABP
)))
goto
panic
;
left_length
-=
block_info
.
data_len
;
to
+=
block_info
.
data_len
;
/* copy information that is already read */
{
uint
offset
=
(
uint
)
(
block_info
.
filepos
-
filepos
);
uint
prefetch_len
=
(
sizeof
(
block_info
.
header
)
-
offset
);
filepos
+=
sizeof
(
block_info
.
header
);
if
(
prefetch_len
>
block_info
.
data_len
)
prefetch_len
=
block_info
.
data_len
;
if
(
prefetch_len
)
{
memcpy
((
byte
*
)
to
,
block_info
.
header
+
offset
,
prefetch_len
);
block_info
.
data_len
-=
prefetch_len
;
left_length
-=
prefetch_len
;
to
+=
prefetch_len
;
}
}
/* read rest of record from file */
if
(
block_info
.
data_len
)
{
if
(
info
->
opt_flag
&
WRITE_CACHE_USED
&&
info
->
rec_cache
.
pos_in_file
<
filepos
+
block_info
.
data_len
&&
flush_io_cache
(
&
info
->
rec_cache
))
goto
err
;
if
(
my_read
(
file
,
(
byte
*
)
to
,
block_info
.
data_len
,
MYF
(
MY_NABP
)))
goto
panic
;
left_length
-=
block_info
.
data_len
;
to
+=
block_info
.
data_len
;
}
filepos
=
block_info
.
next_filepos
;
}
while
(
left_length
);
info
->
update
|=
HA_STATE_AKTIV
;
/* We have a aktive record */
...
...
@@ -1346,11 +1397,45 @@ err:
}
/*
Read record from datafile.
SYNOPSIS
_mi_read_rnd_dynamic_record()
info MI_INFO pointer to table.
buf Destination for record.
filepos From where to read the record.
skip_deleted_blocks If to repeat reading until a non-deleted
record is found.
NOTE
If a write buffer is active, it needs to be flushed if its contents
intersects with the record to read. We always check if the position
of the first byte of the write buffer is lower than the position
past the last byte to read. In theory this is also true if the write
buffer is completely below the read segment. That is, if there is no
intersection. But this case is unusual. We flush anyway. Only if the
first byte in the write buffer is above the last byte to read, we do
not flush.
A dynamic record may need several reads. So this check must be done
before every read. Reading a dynamic record starts with reading the
block header. If the record does not fit into the free space of the
header, the block may be longer than the header. In this case a
second read is necessary. These one or two reads repeat for every
part of the record.
RETURN
0 OK
!= 0 Error
*/
int
_mi_read_rnd_dynamic_record
(
MI_INFO
*
info
,
byte
*
buf
,
register
my_off_t
filepos
,
my_bool
skip_deleted_blocks
)
{
int
flag
,
info_read
,
save_errno
;
int
block_of_record
,
info_read
,
save_errno
;
uint
left_len
,
b_type
;
byte
*
to
;
MI_BLOCK_INFO
block_info
;
...
...
@@ -1376,7 +1461,8 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
else
info_read
=
1
;
/* memory-keyinfoblock is ok */
flag
=
block_info
.
second_read
=
0
;
block_of_record
=
0
;
/* First block of record is numbered as zero. */
block_info
.
second_read
=
0
;
left_len
=
1
;
do
{
...
...
@@ -1399,15 +1485,15 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
{
if
(
_mi_read_cache
(
&
info
->
rec_cache
,(
byte
*
)
block_info
.
header
,
filepos
,
sizeof
(
block_info
.
header
),
(
!
flag
&&
skip_deleted_blocks
?
READING_NEXT
:
0
)
|
READING_HEADER
))
(
!
block_of_record
&&
skip_deleted_blocks
?
READING_NEXT
:
0
)
|
READING_HEADER
))
goto
panic
;
b_type
=
_mi_get_block_info
(
&
block_info
,
-
1
,
filepos
);
}
else
{
if
(
info
->
opt_flag
&
WRITE_CACHE_USED
&&
info
->
rec_cache
.
pos_in_file
<
=
filepos
&&
info
->
rec_cache
.
pos_in_file
<
filepos
+
MI_BLOCK_INFO_HEADER_LENGTH
&&
flush_io_cache
(
&
info
->
rec_cache
))
DBUG_RETURN
(
my_errno
);
info
->
rec_cache
.
seek_not_done
=
1
;
...
...
@@ -1432,7 +1518,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
}
goto
err
;
}
if
(
flag
==
0
)
/* First block */
if
(
block_of_record
==
0
)
/* First block */
{
if
(
block_info
.
rec_len
>
(
uint
)
share
->
base
.
max_pack_length
)
goto
panic
;
...
...
@@ -1465,7 +1551,7 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
left_len
-=
tmp_length
;
to
+=
tmp_length
;
filepos
+=
tmp_length
;
}
}
}
/* read rest of record from file */
if
(
block_info
.
data_len
)
...
...
@@ -1474,11 +1560,17 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
{
if
(
_mi_read_cache
(
&
info
->
rec_cache
,(
byte
*
)
to
,
filepos
,
block_info
.
data_len
,
(
!
flag
&&
skip_deleted_blocks
)
?
READING_NEXT
:
0
))
(
!
block_of_record
&&
skip_deleted_blocks
)
?
READING_NEXT
:
0
))
goto
panic
;
}
else
{
if
(
info
->
opt_flag
&
WRITE_CACHE_USED
&&
info
->
rec_cache
.
pos_in_file
<
block_info
.
filepos
+
block_info
.
data_len
&&
flush_io_cache
(
&
info
->
rec_cache
))
goto
err
;
/* VOID(my_seek(info->dfile,filepos,MY_SEEK_SET,MYF(0))); */
if
(
my_read
(
info
->
dfile
,(
byte
*
)
to
,
block_info
.
data_len
,
MYF
(
MY_NABP
)))
{
...
...
@@ -1488,10 +1580,14 @@ int _mi_read_rnd_dynamic_record(MI_INFO *info, byte *buf,
}
}
}
if
(
flag
++
==
0
)
/*
Increment block-of-record counter. If it was the first block,
remember the position behind the block for the next call.
*/
if
(
block_of_record
++
==
0
)
{
info
->
nextpos
=
block_info
.
filepos
+
block_info
.
block_len
;
skip_deleted_blocks
=
0
;
info
->
nextpos
=
block_info
.
filepos
+
block_info
.
block_len
;
skip_deleted_blocks
=
0
;
}
left_len
-=
block_info
.
data_len
;
to
+=
block_info
.
data_len
;
...
...
@@ -1523,6 +1619,11 @@ uint _mi_get_block_info(MI_BLOCK_INFO *info, File file, my_off_t filepos)
if
(
file
>=
0
)
{
/*
We do not use my_pread() here because we want to have the file
pointer set to the end of the header after this function.
my_pread() may leave the file pointer untouched.
*/
VOID
(
my_seek
(
file
,
filepos
,
MY_SEEK_SET
,
MYF
(
0
)));
if
(
my_read
(
file
,(
char
*
)
header
,
sizeof
(
info
->
header
),
MYF
(
0
))
!=
sizeof
(
info
->
header
))
...
...
mysql-test/r/rpl_auto_increment.result
View file @
b2f5a1ee
...
...
@@ -183,3 +183,47 @@ a
32
42
drop table t1;
create table t1 (a tinyint not null auto_increment primary key) engine=myisam;
insert into t1 values(103);
set auto_increment_increment=11;
set auto_increment_offset=4;
insert into t1 values(null);
insert into t1 values(null);
insert into t1 values(null);
ERROR 23000: Duplicate entry '125' for key 1
select a, mod(a-@@auto_increment_offset,@@auto_increment_increment) from t1 order by a;
a mod(a-@@auto_increment_offset,@@auto_increment_increment)
103 0
114 0
125 0
create table t2 (a tinyint unsigned not null auto_increment primary key) engine=myisam;
set auto_increment_increment=10;
set auto_increment_offset=1;
set insert_id=1000;
insert into t2 values(null);
Warnings:
Warning 1264 Out of range value adjusted for column 'a' at row 1
select a, mod(a-@@auto_increment_offset,@@auto_increment_increment) from t2 order by a;
a mod(a-@@auto_increment_offset,@@auto_increment_increment)
251 0
create table t3 like t1;
set auto_increment_increment=1000;
set auto_increment_offset=700;
insert into t3 values(null);
Warnings:
Warning 1264 Out of range value adjusted for column 'a' at row 1
select * from t3 order by a;
a
127
select * from t1 order by a;
a
103
114
125
select * from t2 order by a;
a
251
select * from t3 order by a;
a
127
drop table t1,t2,t3;
mysql-test/r/rpl_insert_id.result
View file @
b2f5a1ee
...
...
@@ -132,3 +132,68 @@ id last_id
drop function bug15728;
drop function bug15728_insert;
drop table t1, t2;
create table t1 (n int primary key auto_increment not null,
b int, unique(b));
set sql_log_bin=0;
insert into t1 values(null,100);
replace into t1 values(null,50),(null,100),(null,150);
select * from t1 order by n;
n b
2 50
3 100
4 150
truncate table t1;
set sql_log_bin=1;
insert into t1 values(null,100);
select * from t1 order by n;
n b
1 100
insert into t1 values(null,200),(null,300);
delete from t1 where b <> 100;
select * from t1 order by n;
n b
1 100
replace into t1 values(null,100),(null,350);
select * from t1 order by n;
n b
2 100
3 350
select * from t1 order by n;
n b
2 100
3 350
insert into t1 values (NULL,400),(3,500),(NULL,600) on duplicate key UPDATE n=1000;
select * from t1 order by n;
n b
2 100
4 400
1000 350
1001 600
select * from t1 order by n;
n b
2 100
4 400
1000 350
1001 600
drop table t1;
create table t1 (n int primary key auto_increment not null,
b int, unique(b));
insert into t1 values(null,100);
select * from t1 order by n;
n b
1 100
insert into t1 values(null,200),(null,300);
delete from t1 where b <> 100;
select * from t1 order by n;
n b
1 100
insert into t1 values(null,100),(null,350) on duplicate key update n=2;
select * from t1 order by n;
n b
2 100
3 350
select * from t1 order by n;
n b
2 100
3 350
drop table t1;
mysql-test/t/rpl_auto_increment.test
View file @
b2f5a1ee
...
...
@@ -96,9 +96,47 @@ select * from t1;
sync_slave_with_master
;
select
*
from
t1
;
connection
master
;
# Test for BUG#20524 "auto_increment_* not observed when inserting
# a too large value". When an autogenerated value was bigger than the
# maximum possible value of the field, it was truncated to that max
# possible value, without being "rounded down" to still honour
# auto_increment_* variables.
connection
master
;
drop
table
t1
;
create
table
t1
(
a
tinyint
not
null
auto_increment
primary
key
)
engine
=
myisam
;
insert
into
t1
values
(
103
);
set
auto_increment_increment
=
11
;
set
auto_increment_offset
=
4
;
insert
into
t1
values
(
null
);
insert
into
t1
values
(
null
);
--
error
1062
insert
into
t1
values
(
null
);
select
a
,
mod
(
a
-@@
auto_increment_offset
,
@@
auto_increment_increment
)
from
t1
order
by
a
;
# same but with a larger value
create
table
t2
(
a
tinyint
unsigned
not
null
auto_increment
primary
key
)
engine
=
myisam
;
set
auto_increment_increment
=
10
;
set
auto_increment_offset
=
1
;
set
insert_id
=
1000
;
insert
into
t2
values
(
null
);
select
a
,
mod
(
a
-@@
auto_increment_offset
,
@@
auto_increment_increment
)
from
t2
order
by
a
;
# An offset so big that even first value does not fit
create
table
t3
like
t1
;
set
auto_increment_increment
=
1000
;
set
auto_increment_offset
=
700
;
insert
into
t3
values
(
null
);
select
*
from
t3
order
by
a
;
sync_slave_with_master
;
select
*
from
t1
order
by
a
;
select
*
from
t2
order
by
a
;
select
*
from
t3
order
by
a
;
connection
master
;
drop
table
t1
,
t2
,
t3
;
# End cleanup
sync_slave_with_master
;
mysql-test/t/rpl_insert_id.test
View file @
b2f5a1ee
...
...
@@ -147,6 +147,69 @@ drop function bug15728;
drop
function
bug15728_insert
;
drop
table
t1
,
t2
;
# test of BUG#20188 REPLACE or ON DUPLICATE KEY UPDATE in
# auto_increment breaks binlog
create
table
t1
(
n
int
primary
key
auto_increment
not
null
,
b
int
,
unique
(
b
));
# First, test that we do not call restore_auto_increment() too early
# in write_record():
set
sql_log_bin
=
0
;
insert
into
t1
values
(
null
,
100
);
replace
into
t1
values
(
null
,
50
),(
null
,
100
),(
null
,
150
);
select
*
from
t1
order
by
n
;
truncate
table
t1
;
set
sql_log_bin
=
1
;
insert
into
t1
values
(
null
,
100
);
select
*
from
t1
order
by
n
;
sync_slave_with_master
;
# make slave's table autoinc counter bigger
insert
into
t1
values
(
null
,
200
),(
null
,
300
);
delete
from
t1
where
b
<>
100
;
# check that slave's table content is identical to master
select
*
from
t1
order
by
n
;
# only the auto_inc counter differs.
connection
master
;
replace
into
t1
values
(
null
,
100
),(
null
,
350
);
select
*
from
t1
order
by
n
;
sync_slave_with_master
;
select
*
from
t1
order
by
n
;
# Same test as for REPLACE, but for ON DUPLICATE KEY UPDATE
# We first check that if we update a row using a value larger than the
# table's counter, the counter for next row is bigger than the
# after-value of the updated row.
connection
master
;
insert
into
t1
values
(
NULL
,
400
),(
3
,
500
),(
NULL
,
600
)
on
duplicate
key
UPDATE
n
=
1000
;
select
*
from
t1
order
by
n
;
sync_slave_with_master
;
select
*
from
t1
order
by
n
;
# and now test for the bug:
connection
master
;
drop
table
t1
;
create
table
t1
(
n
int
primary
key
auto_increment
not
null
,
b
int
,
unique
(
b
));
insert
into
t1
values
(
null
,
100
);
select
*
from
t1
order
by
n
;
sync_slave_with_master
;
insert
into
t1
values
(
null
,
200
),(
null
,
300
);
delete
from
t1
where
b
<>
100
;
select
*
from
t1
order
by
n
;
connection
master
;
insert
into
t1
values
(
null
,
100
),(
null
,
350
)
on
duplicate
key
update
n
=
2
;
select
*
from
t1
order
by
n
;
sync_slave_with_master
;
select
*
from
t1
order
by
n
;
connection
master
;
drop
table
t1
;
# End of 5.0 tests
sync_slave_with_master
;
sql/handler.cc
View file @
b2f5a1ee
...
...
@@ -1471,6 +1471,66 @@ next_insert_id(ulonglong nr,struct system_variables *variables)
}
void
handler
::
adjust_next_insert_id_after_explicit_value
(
ulonglong
nr
)
{
/*
If we have set THD::next_insert_id previously and plan to insert an
explicitely-specified value larger than this, we need to increase
THD::next_insert_id to be greater than the explicit value.
*/
THD
*
thd
=
table
->
in_use
;
if
(
thd
->
clear_next_insert_id
&&
(
nr
>=
thd
->
next_insert_id
))
{
if
(
thd
->
variables
.
auto_increment_increment
!=
1
)
nr
=
next_insert_id
(
nr
,
&
thd
->
variables
);
else
nr
++
;
thd
->
next_insert_id
=
nr
;
DBUG_PRINT
(
"info"
,(
"next_insert_id: %lu"
,
(
ulong
)
nr
));
}
}
/*
Computes the largest number X:
- smaller than or equal to "nr"
- of the form: auto_increment_offset + N * auto_increment_increment
where N>=0.
SYNOPSIS
prev_insert_id
nr Number to "round down"
variables variables struct containing auto_increment_increment and
auto_increment_offset
RETURN
The number X if it exists, "nr" otherwise.
*/
inline
ulonglong
prev_insert_id
(
ulonglong
nr
,
struct
system_variables
*
variables
)
{
if
(
unlikely
(
nr
<
variables
->
auto_increment_offset
))
{
/*
There's nothing good we can do here. That is a pathological case, where
the offset is larger than the column's max possible value, i.e. not even
the first sequence value may be inserted. User will receive warning.
*/
DBUG_PRINT
(
"info"
,(
"auto_increment: nr: %lu cannot honour "
"auto_increment_offset: %lu"
,
nr
,
variables
->
auto_increment_offset
));
return
nr
;
}
if
(
variables
->
auto_increment_increment
==
1
)
return
nr
;
// optimization of the formula below
nr
=
(((
nr
-
variables
->
auto_increment_offset
))
/
(
ulonglong
)
variables
->
auto_increment_increment
);
return
(
nr
*
(
ulonglong
)
variables
->
auto_increment_increment
+
variables
->
auto_increment_offset
);
}
/*
Update the auto_increment field if necessary
...
...
@@ -1547,17 +1607,7 @@ bool handler::update_auto_increment()
/* Clear flag for next row */
/* Mark that we didn't generate a new value **/
auto_increment_column_changed
=
0
;
/* Update next_insert_id if we have already generated a value */
if
(
thd
->
clear_next_insert_id
&&
nr
>=
thd
->
next_insert_id
)
{
if
(
variables
->
auto_increment_increment
!=
1
)
nr
=
next_insert_id
(
nr
,
variables
);
else
nr
++
;
thd
->
next_insert_id
=
nr
;
DBUG_PRINT
(
"info"
,(
"next_insert_id: %lu"
,
(
ulong
)
nr
));
}
adjust_next_insert_id_after_explicit_value
(
nr
);
DBUG_RETURN
(
0
);
}
if
(
!
(
nr
=
thd
->
next_insert_id
))
...
...
@@ -1580,10 +1630,19 @@ bool handler::update_auto_increment()
/* Mark that we should clear next_insert_id before next stmt */
thd
->
clear_next_insert_id
=
1
;
if
(
!
table
->
next_number_field
->
store
((
longlong
)
nr
,
TRUE
))
if
(
likely
(
!
table
->
next_number_field
->
store
((
longlong
)
nr
,
TRUE
)
))
thd
->
insert_id
((
ulonglong
)
nr
);
else
thd
->
insert_id
(
table
->
next_number_field
->
val_int
());
{
/*
overflow of the field; we'll use the max value, however we try to
decrease it to honour auto_increment_* variables:
*/
nr
=
prev_insert_id
(
table
->
next_number_field
->
val_int
(),
variables
);
thd
->
insert_id
(
nr
);
if
(
unlikely
(
table
->
next_number_field
->
store
((
longlong
)
nr
,
TRUE
)))
thd
->
insert_id
(
nr
=
table
->
next_number_field
->
val_int
());
}
/*
We can't set next_insert_id if the auto-increment key is not the
...
...
sql/handler.h
View file @
b2f5a1ee
...
...
@@ -564,6 +564,7 @@ public:
{}
virtual
~
handler
(
void
)
{
/* TODO: DBUG_ASSERT(inited == NONE); */
}
int
ha_open
(
const
char
*
name
,
int
mode
,
int
test_if_locked
);
void
adjust_next_insert_id_after_explicit_value
(
ulonglong
nr
);
bool
update_auto_increment
();
virtual
void
print_error
(
int
error
,
myf
errflag
);
virtual
bool
get_error_message
(
int
error
,
String
*
buf
);
...
...
sql/sql_base.cc
View file @
b2f5a1ee
...
...
@@ -624,8 +624,10 @@ void close_temporary_tables(THD *thd)
if
(
!
mysql_bin_log
.
is_open
())
{
for
(
table
=
thd
->
temporary_tables
;
table
;
table
=
table
->
next
)
TABLE
*
next
;
for
(
table
=
thd
->
temporary_tables
;
table
;
table
=
next
)
{
next
=
table
->
next
;
close_temporary
(
table
,
1
);
}
thd
->
temporary_tables
=
0
;
...
...
@@ -648,7 +650,6 @@ void close_temporary_tables(THD *thd)
insertion sort of temp tables by pseudo_thread_id to build ordered list
of sublists of equal pseudo_thread_id
*/
for
(
prev_table
=
thd
->
temporary_tables
,
table
=
prev_table
->
next
;
table
;
prev_table
=
table
,
table
=
table
->
next
)
...
...
sql/sql_insert.cc
View file @
b2f5a1ee
...
...
@@ -992,7 +992,6 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
uint
key_nr
;
if
(
error
!=
HA_WRITE_SKIP
)
goto
err
;
table
->
file
->
restore_auto_increment
();
if
((
int
)
(
key_nr
=
table
->
file
->
get_dup_key
(
error
))
<
0
)
{
error
=
HA_WRITE_SKIP
;
/* Database can't find key */
...
...
@@ -1065,20 +1064,20 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
if
(
res
==
VIEW_CHECK_ERROR
)
goto
before_trg_err
;
if
(
thd
->
clear_next_insert_id
)
{
/* Reset auto-increment cacheing if we do an update */
thd
->
clear_next_insert_id
=
0
;
thd
->
next_insert_id
=
0
;
}
if
((
error
=
table
->
file
->
update_row
(
table
->
record
[
1
],
table
->
record
[
0
])))
{
if
((
error
==
HA_ERR_FOUND_DUPP_KEY
)
&&
info
->
ignore
)
{
table
->
file
->
restore_auto_increment
();
goto
ok_or_after_trg_err
;
}
goto
err
;
}
info
->
updated
++
;
if
(
table
->
next_number_field
)
table
->
file
->
adjust_next_insert_id_after_explicit_value
(
table
->
next_number_field
->
val_int
());
trg_error
=
(
table
->
triggers
&&
table
->
triggers
->
process_triggers
(
thd
,
TRG_EVENT_UPDATE
,
TRG_ACTION_AFTER
,
TRUE
));
...
...
@@ -1107,12 +1106,6 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
table
->
timestamp_field_type
==
TIMESTAMP_AUTO_SET_ON_BOTH
)
&&
(
!
table
->
triggers
||
!
table
->
triggers
->
has_delete_triggers
()))
{
if
(
thd
->
clear_next_insert_id
)
{
/* Reset auto-increment cacheing if we do an update */
thd
->
clear_next_insert_id
=
0
;
thd
->
next_insert_id
=
0
;
}
if
((
error
=
table
->
file
->
update_row
(
table
->
record
[
1
],
table
->
record
[
0
])))
goto
err
;
...
...
@@ -1176,6 +1169,7 @@ err:
table
->
file
->
print_error
(
error
,
MYF
(
0
));
before_trg_err:
table
->
file
->
restore_auto_increment
();
if
(
key
)
my_safe_afree
(
key
,
table
->
s
->
max_unique_length
,
MAX_KEY_LENGTH
);
DBUG_RETURN
(
1
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment