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
cf39abbb
Commit
cf39abbb
authored
Nov 30, 2007
by
kaa@polly.(none)
Browse files
Options
Browse Files
Download
Plain Diff
Merge polly.(none):/home/kaa/src/opt/bug9481/my50-bug9481
into polly.(none):/home/kaa/src/opt/mysql-5.0-opt
parents
3bd26b47
24c9d864
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
224 additions
and
9 deletions
+224
-9
sql/sql_class.h
sql/sql_class.h
+2
-1
sql/sql_insert.cc
sql/sql_insert.cc
+40
-8
tests/mysql_client_test.c
tests/mysql_client_test.c
+182
-0
No files found.
sql/sql_class.h
View file @
cf39abbb
...
@@ -2048,7 +2048,8 @@ class select_insert :public select_result_interceptor {
...
@@ -2048,7 +2048,8 @@ class select_insert :public select_result_interceptor {
TABLE_LIST
*
table_list
;
TABLE_LIST
*
table_list
;
TABLE
*
table
;
TABLE
*
table
;
List
<
Item
>
*
fields
;
List
<
Item
>
*
fields
;
ulonglong
last_insert_id
;
ulonglong
autoinc_value_of_last_inserted_row
;
// not autogenerated
ulonglong
autoinc_value_of_first_inserted_row
;
// autogenerated
COPY_INFO
info
;
COPY_INFO
info
;
bool
insert_into_view
;
bool
insert_into_view
;
select_insert
(
TABLE_LIST
*
table_list_par
,
select_insert
(
TABLE_LIST
*
table_list_par
,
...
...
sql/sql_insert.cc
View file @
cf39abbb
...
@@ -2644,7 +2644,8 @@ select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par,
...
@@ -2644,7 +2644,8 @@ select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par,
enum_duplicates
duplic
,
enum_duplicates
duplic
,
bool
ignore_check_option_errors
)
bool
ignore_check_option_errors
)
:
table_list
(
table_list_par
),
table
(
table_par
),
fields
(
fields_par
),
:
table_list
(
table_list_par
),
table
(
table_par
),
fields
(
fields_par
),
last_insert_id
(
0
),
autoinc_value_of_last_inserted_row
(
0
),
autoinc_value_of_first_inserted_row
(
0
),
insert_into_view
(
table_list_par
&&
table_list_par
->
view
!=
0
)
insert_into_view
(
table_list_par
&&
table_list_par
->
view
!=
0
)
{
{
bzero
((
char
*
)
&
info
,
sizeof
(
info
));
bzero
((
char
*
)
&
info
,
sizeof
(
info
));
...
@@ -2897,15 +2898,25 @@ bool select_insert::send_data(List<Item> &values)
...
@@ -2897,15 +2898,25 @@ bool select_insert::send_data(List<Item> &values)
}
}
if
(
table
->
next_number_field
)
if
(
table
->
next_number_field
)
{
{
/*
If no value has been autogenerated so far, we need to remember the
value we just saw, we may need to send it to client in the end.
*/
if
(
!
thd
->
insert_id_used
)
autoinc_value_of_last_inserted_row
=
table
->
next_number_field
->
val_int
();
/*
/*
Clear auto-increment field for the next record, if triggers are used
Clear auto-increment field for the next record, if triggers are used
we will clear it twice, but this should be cheap.
we will clear it twice, but this should be cheap.
*/
*/
table
->
next_number_field
->
reset
();
table
->
next_number_field
->
reset
();
if
(
!
last_insert_id
&&
thd
->
insert_id_used
)
if
(
!
autoinc_value_of_last_inserted_row
&&
thd
->
insert_id_used
)
last_insert_id
=
thd
->
last_insert_id
;
autoinc_value_of_last_inserted_row
=
thd
->
last_insert_id
;
}
}
}
}
if
(
thd
->
insert_id_used
&&
!
autoinc_value_of_first_inserted_row
)
autoinc_value_of_first_inserted_row
=
thd
->
last_insert_id
;
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
}
}
...
@@ -2934,6 +2945,7 @@ bool select_insert::send_eof()
...
@@ -2934,6 +2945,7 @@ bool select_insert::send_eof()
{
{
int
error
,
error2
;
int
error
,
error2
;
bool
changed
,
transactional_table
=
table
->
file
->
has_transactions
();
bool
changed
,
transactional_table
=
table
->
file
->
has_transactions
();
ulonglong
id
;
DBUG_ENTER
(
"select_insert::send_eof"
);
DBUG_ENTER
(
"select_insert::send_eof"
);
error
=
(
!
thd
->
prelocked_mode
)
?
table
->
file
->
end_bulk_insert
()
:
0
;
error
=
(
!
thd
->
prelocked_mode
)
?
table
->
file
->
end_bulk_insert
()
:
0
;
...
@@ -2954,8 +2966,17 @@ bool select_insert::send_eof()
...
@@ -2954,8 +2966,17 @@ bool select_insert::send_eof()
DBUG_ASSERT
(
transactional_table
||
!
changed
||
DBUG_ASSERT
(
transactional_table
||
!
changed
||
thd
->
transaction
.
stmt
.
modified_non_trans_table
);
thd
->
transaction
.
stmt
.
modified_non_trans_table
);
if
(
last_insert_id
)
// For binary log
thd
->
insert_id
(
info
.
copied
?
last_insert_id
:
0
);
// For binary log
if
(
autoinc_value_of_last_inserted_row
)
{
if
(
info
.
copied
)
thd
->
insert_id
(
autoinc_value_of_last_inserted_row
);
else
{
autoinc_value_of_first_inserted_row
=
0
;
thd
->
insert_id
(
0
);
}
}
/* Write to binlog before commiting transaction */
/* Write to binlog before commiting transaction */
if
(
mysql_bin_log
.
is_open
())
if
(
mysql_bin_log
.
is_open
())
{
{
...
@@ -2982,7 +3003,9 @@ bool select_insert::send_eof()
...
@@ -2982,7 +3003,9 @@ bool select_insert::send_eof()
thd
->
row_count_func
=
info
.
copied
+
info
.
deleted
+
thd
->
row_count_func
=
info
.
copied
+
info
.
deleted
+
((
thd
->
client_capabilities
&
CLIENT_FOUND_ROWS
)
?
((
thd
->
client_capabilities
&
CLIENT_FOUND_ROWS
)
?
info
.
touched
:
info
.
updated
);
info
.
touched
:
info
.
updated
);
::
send_ok
(
thd
,
(
ulong
)
thd
->
row_count_func
,
last_insert_id
,
buff
);
id
=
autoinc_value_of_first_inserted_row
>
0
?
autoinc_value_of_first_inserted_row
:
thd
->
last_insert_id
;
::
send_ok
(
thd
,
(
ulong
)
thd
->
row_count_func
,
id
,
buff
);
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
@@ -3011,8 +3034,17 @@ void select_insert::abort()
...
@@ -3011,8 +3034,17 @@ void select_insert::abort()
if
((
changed
=
info
.
copied
||
info
.
deleted
||
info
.
updated
)
&&
if
((
changed
=
info
.
copied
||
info
.
deleted
||
info
.
updated
)
&&
!
transactional_table
)
!
transactional_table
)
{
{
if
(
last_insert_id
)
// For binary log
thd
->
insert_id
(
last_insert_id
);
// For binary log
if
(
autoinc_value_of_last_inserted_row
)
{
if
(
info
.
copied
)
thd
->
insert_id
(
autoinc_value_of_last_inserted_row
);
else
{
autoinc_value_of_first_inserted_row
=
0
;
thd
->
insert_id
(
0
);
}
}
if
(
mysql_bin_log
.
is_open
())
if
(
mysql_bin_log
.
is_open
())
{
{
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
Query_log_event
qinfo
(
thd
,
thd
->
query
,
thd
->
query_length
,
...
...
tests/mysql_client_test.c
View file @
cf39abbb
...
@@ -15199,6 +15199,187 @@ static void test_bug14169()
...
@@ -15199,6 +15199,187 @@ static void test_bug14169()
}
}
/*
Test that mysql_insert_id() behaves as documented in our manual
*/
static
void
test_mysql_insert_id
()
{
my_ulonglong
res
;
int
rc
;
myheader
(
"test_mysql_insert_id"
);
rc
=
mysql_query
(
mysql
,
"drop table if exists t1"
);
myquery
(
rc
);
/* table without auto_increment column */
rc
=
mysql_query
(
mysql
,
"create table t1 (f1 int, f2 varchar(255), key(f1))"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"insert into t1 values (1,'a')"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
0
);
rc
=
mysql_query
(
mysql
,
"insert into t1 values (null,'b')"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
0
);
rc
=
mysql_query
(
mysql
,
"insert into t1 select 5,'c'"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
0
);
rc
=
mysql_query
(
mysql
,
"insert into t1 select null,'d'"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
0
);
rc
=
mysql_query
(
mysql
,
"insert into t1 values (null,last_insert_id(300))"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
300
);
rc
=
mysql_query
(
mysql
,
"insert into t1 select null,last_insert_id(400)"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
/*
Behaviour change: old code used to return 0; but 400 is consistent
with INSERT VALUES, and the manual's section of mysql_insert_id() does not
say INSERT SELECT should be different.
*/
DIE_UNLESS
(
res
==
400
);
/* table with auto_increment column */
rc
=
mysql_query
(
mysql
,
"create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"insert into t2 values (1,'a')"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
1
);
/* this should not influence next INSERT if it doesn't have auto_inc */
rc
=
mysql_query
(
mysql
,
"insert into t1 values (10,'e')"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
0
);
rc
=
mysql_query
(
mysql
,
"insert into t2 values (null,'b')"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
2
);
rc
=
mysql_query
(
mysql
,
"insert into t2 select 5,'c'"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
/*
Manual says that for multirow insert this should have been 5, but does not
say for INSERT SELECT. This is a behaviour change: old code used to return
0. We try to be consistent with INSERT VALUES.
*/
DIE_UNLESS
(
res
==
5
);
rc
=
mysql_query
(
mysql
,
"insert into t2 select null,'d'"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
6
);
/* with more than one row */
rc
=
mysql_query
(
mysql
,
"insert into t2 values (10,'a'),(11,'b')"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
11
);
rc
=
mysql_query
(
mysql
,
"insert into t2 select 12,'a' union select 13,'b'"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
/*
Manual says that for multirow insert this should have been 13, but does
not say for INSERT SELECT. This is a behaviour change: old code used to
return 0. We try to be consistent with INSERT VALUES.
*/
DIE_UNLESS
(
res
==
13
);
rc
=
mysql_query
(
mysql
,
"insert into t2 values (null,'a'),(null,'b')"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
14
);
rc
=
mysql_query
(
mysql
,
"insert into t2 select null,'a' union select null,'b'"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
16
);
rc
=
mysql_query
(
mysql
,
"insert into t2 select 12,'a' union select 13,'b'"
);
myquery_r
(
rc
);
rc
=
mysql_query
(
mysql
,
"insert ignore into t2 select 12,'a' union select 13,'b'"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
0
);
rc
=
mysql_query
(
mysql
,
"insert into t2 values (12,'a'),(13,'b')"
);
myquery_r
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
0
);
rc
=
mysql_query
(
mysql
,
"insert ignore into t2 values (12,'a'),(13,'b')"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
0
);
/* mixing autogenerated and explicit values */
rc
=
mysql_query
(
mysql
,
"insert into t2 values (null,'e'),(12,'a'),(13,'b')"
);
myquery_r
(
rc
);
rc
=
mysql_query
(
mysql
,
"insert into t2 values (null,'e'),(12,'a'),(13,'b'),(25,'g')"
);
myquery_r
(
rc
);
rc
=
mysql_query
(
mysql
,
"insert into t2 values (null,last_insert_id(300))"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
/*
according to the manual, this might be 20 or 300, but it looks like
auto_increment column takes priority over last_insert_id().
*/
DIE_UNLESS
(
res
==
20
);
/* If first autogenerated number fails and 2nd works: */
rc
=
mysql_query
(
mysql
,
"drop table t2"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"create table t2 (f1 int not null primary key "
"auto_increment, f2 varchar(255), unique (f2))"
);
myquery
(
rc
);
rc
=
mysql_query
(
mysql
,
"insert into t2 values (null,'e')"
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
1
);
rc
=
mysql_query
(
mysql
,
"insert ignore into t2 values (null,'e'),(null,'a'),(null,'e')"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
2
);
/* If autogenerated fails and explicit works: */
rc
=
mysql_query
(
mysql
,
"insert ignore into t2 values (null,'e'),(12,'c'),(null,'d')"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
3
);
/* UPDATE may update mysql_insert_id() if it uses LAST_INSERT_ID(#) */
rc
=
mysql_query
(
mysql
,
"update t2 set f1=14 where f1=12"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
0
);
rc
=
mysql_query
(
mysql
,
"update t2 set f1=NULL where f1=14"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
0
);
rc
=
mysql_query
(
mysql
,
"update t2 set f2=last_insert_id(372) where f1=0"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
372
);
/* check that LAST_INSERT_ID() does not update mysql_insert_id(): */
rc
=
mysql_query
(
mysql
,
"insert into t2 values (null,'g')"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
15
);
rc
=
mysql_query
(
mysql
,
"update t2 set f2=(@li:=last_insert_id()) where f1=15"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
0
);
/*
Behaviour change: now if ON DUPLICATE KEY UPDATE updates a row,
mysql_insert_id() returns the id of the row, instead of not being
affected.
*/
rc
=
mysql_query
(
mysql
,
"insert into t2 values (null,@li) on duplicate key "
"update f2=concat('we updated ',f2)"
);
myquery
(
rc
);
res
=
mysql_insert_id
(
mysql
);
DIE_UNLESS
(
res
==
15
);
rc
=
mysql_query
(
mysql
,
"drop table t1,t2"
);
myquery
(
rc
);
}
/*
/*
Bug#20152: mysql_stmt_execute() writes to MYSQL_TYPE_DATE buffer
Bug#20152: mysql_stmt_execute() writes to MYSQL_TYPE_DATE buffer
*/
*/
...
@@ -16237,6 +16418,7 @@ static struct my_tests_st my_tests[]= {
...
@@ -16237,6 +16418,7 @@ static struct my_tests_st my_tests[]= {
{
"test_bug17667"
,
test_bug17667
},
{
"test_bug17667"
,
test_bug17667
},
{
"test_bug19671"
,
test_bug19671
},
{
"test_bug19671"
,
test_bug19671
},
{
"test_bug15752"
,
test_bug15752
},
{
"test_bug15752"
,
test_bug15752
},
{
"test_mysql_insert_id"
,
test_mysql_insert_id
},
{
"test_bug21206"
,
test_bug21206
},
{
"test_bug21206"
,
test_bug21206
},
{
"test_bug21726"
,
test_bug21726
},
{
"test_bug21726"
,
test_bug21726
},
{
"test_bug15518"
,
test_bug15518
},
{
"test_bug15518"
,
test_bug15518
},
...
...
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