Skip to content

Commit 07598b7

Browse files
committed
Merge pull request #126
Fix $dbh->last_insert_id for async calls and multi result statements
2 parents 849ad97 + c788640 commit 07598b7

File tree

3 files changed

+96
-10
lines changed

3 files changed

+96
-10
lines changed

dbdimp.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2652,6 +2652,7 @@ IV mariadb_db_do6(SV *dbh, imp_dbh_t *imp_dbh, SV *statement_sv, SV *attribs, I3
26522652
mariadb_dr_do_error(dbh, mysql_errno(imp_dbh->pmysql), mysql_error(imp_dbh->pmysql), mysql_sqlstate(imp_dbh->pmysql));
26532653
return -2;
26542654
}
2655+
imp_dbh->insertid = mysql_insert_id(imp_dbh->pmysql);
26552656
}
26562657
if (result)
26572658
{
@@ -4021,6 +4022,7 @@ static bool mariadb_st_free_result_sets(SV *sth, imp_sth_t *imp_sth)
40214022
mysql_sqlstate(imp_dbh->pmysql));
40224023
return FALSE;
40234024
}
4025+
imp_dbh->insertid = imp_sth->insertid = mysql_insert_id(imp_dbh->pmysql);
40244026
}
40254027
}
40264028
if (imp_sth->result)
@@ -6521,16 +6523,20 @@ my_ulonglong mariadb_db_async_result(SV* h, MYSQL_RES** resp)
65216523
*resp= NULL;
65226524
}
65236525
}
6526+
6527+
/* Some MySQL client versions return correct value from mysql_insert_id()
6528+
* function only after non-SELECT operation. So store insert id into dbh
6529+
* cache and later read it only from cache. */
6530+
if (retval != (my_ulonglong)-1 && !*resp)
6531+
dbh->insertid = mysql_insert_id(svsock);
6532+
65246533
if(htype == DBIt_ST) {
65256534
D_imp_sth(h);
65266535
D_imp_dbh_from_sth;
65276536

65286537
if (retval != (my_ulonglong)-1) {
65296538
if(! *resp) {
6530-
/* Some MySQL client versions return correct value from mysql_insert_id()
6531-
* function only after non-SELECT operation. So store insert id into dbh
6532-
* cache and later read it only from cache. */
6533-
imp_dbh->insertid = imp_sth->insertid = mysql_insert_id(svsock);
6539+
imp_sth->insertid = dbh->insertid;
65346540
if(! mysql_more_results(svsock))
65356541
DBIc_ACTIVE_off(imp_sth);
65366542
} else {

t/76multi_statement.t

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ my $dbh = DbiTestConnect($test_dsn, $test_user, $test_password,
1313
{ RaiseError => 1, PrintError => 0, AutoCommit => 0,
1414
mariadb_multi_statements => 1 });
1515

16-
plan tests => 36;
16+
plan tests => 51;
1717

1818
ok (defined $dbh, "Connected to database with multi statement support");
1919

@@ -73,4 +73,27 @@ $dbh->{mariadb_server_prepare}= 0;
7373
ok(not $sth->more_results());
7474
ok($sth->finish());
7575

76+
# Check that $dbh->last_insert_id works after $dbh->do with multi statements
77+
ok($dbh->do("INSERT INTO dbd_mysql_t76multi2 VALUES(3); INSERT INTO dbd_mysql_t76multi2 VALUES(4);"));
78+
is($dbh->last_insert_id(undef, undef, undef, undef), 4, '$dbh->last_insert_id is correct after $dbh->do with multi statements');
79+
80+
# Check that $dbh->last_insert_id works after prepare, execute and finish but without more_results
81+
ok($sth = $dbh->prepare("INSERT INTO dbd_mysql_t76multi2 VALUES(5); INSERT INTO dbd_mysql_t76multi2 VALUES(6);"));
82+
ok($sth->execute());
83+
ok($sth->finish());
84+
is($dbh->last_insert_id(undef, undef, undef, undef), 6, '$dbh->last_insert_id is correct after multi statement prepare, execute and finish');
85+
86+
# Check that $dbh->last_insert_id works after prepare and execute, but without more_results; after preparing new statement
87+
ok($sth = $dbh->prepare("INSERT INTO dbd_mysql_t76multi2 VALUES(7); INSERT INTO dbd_mysql_t76multi2 VALUES(8);"));
88+
ok($sth->execute());
89+
ok($sth = $dbh->prepare("SELECT 1"));
90+
is($dbh->last_insert_id(undef, undef, undef, undef), 8, '$dbh->last_insert_id is correct after multi statement prepare and execute without finish followed by new prepare');
91+
92+
# Check that $dbh->last_insert_id works after prepare and execute, but without more_results; after calling $dbh->do which do not modify last_insert_id
93+
ok($sth = $dbh->prepare("INSERT INTO dbd_mysql_t76multi2 VALUES(9); INSERT INTO dbd_mysql_t76multi2 VALUES(10);"));
94+
ok($sth->execute());
95+
ok($dbh->do("SELECT 1"));
96+
is($dbh->last_insert_id(undef, undef, undef, undef), 10, '$dbh->last_insert_id is correct after multi statement prepare and execute without finish followed by $dbh->do');
97+
ok($sth->finish());
98+
7699
$dbh->disconnect();

t/88async-multi-stmts.t

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@ use lib 't', '.';
99
require 'lib.pl';
1010

1111
my $dbh = DbiTestConnect($test_dsn, $test_user, $test_password,
12-
{ RaiseError => 0, PrintError => 0, AutoCommit => 0 });
13-
plan tests => 8;
12+
{ RaiseError => 0, PrintError => 0, AutoCommit => 0, mariadb_multi_statements => 1 });
13+
plan tests => 45;
1414

1515
$dbh->do(<<SQL);
1616
CREATE TEMPORARY TABLE async_test (
17-
value INTEGER
17+
value INTEGER AUTO_INCREMENT PRIMARY KEY
1818
);
1919
SQL
2020

21-
my $sth0 = $dbh->prepare('INSERT INTO async_test VALUES(0)', { mariadb_async => 1 });
22-
my $sth1 = $dbh->prepare('INSERT INTO async_test VALUES(1)', { mariadb_async => 1 });
21+
my $sth0 = $dbh->prepare('INSERT INTO async_test VALUES(1)', { mariadb_async => 1 });
22+
my $sth1 = $dbh->prepare('INSERT INTO async_test VALUES(2)', { mariadb_async => 1 });
23+
my $sth2 = $dbh->prepare('INSERT INTO async_test VALUES(3); INSERT INTO async_test VALUES(4);', { mariadb_async => 1 });
2324

2425
$sth0->execute;
2526
ok !defined($sth1->mariadb_async_ready);
@@ -32,7 +33,63 @@ ok !$sth1->errstr;
3233
ok defined($sth0->mariadb_async_result);
3334
ok !$sth1->errstr;
3435

36+
is($sth0->last_insert_id(), 1);
37+
is($dbh->last_insert_id(undef, undef, undef, undef), 1);
38+
39+
$sth2->execute;
40+
ok !defined($sth1->mariadb_async_ready);
41+
ok $sth1->err;
42+
ok !defined($sth1->mariadb_async_result);
43+
ok $sth1->err;
44+
45+
is($sth0->last_insert_id(), 1);
46+
is($dbh->last_insert_id(undef, undef, undef, undef), 1);
47+
48+
ok defined($sth2->mariadb_async_ready);
49+
ok !$sth2->err;
50+
51+
is($sth0->last_insert_id(), 1);
52+
is($dbh->last_insert_id(undef, undef, undef, undef), 1);
53+
54+
ok defined($sth2->mariadb_async_result);
55+
ok !$sth2->err;
56+
57+
is($sth0->last_insert_id(), 1);
58+
is($sth2->last_insert_id(), 3);
59+
is($dbh->last_insert_id(undef, undef, undef, undef), 3);
60+
61+
ok $sth2->more_results;
62+
ok defined($sth2->mariadb_async_result);
63+
ok !$sth2->err;
64+
65+
is($sth0->last_insert_id(), 1);
66+
is($sth2->last_insert_id(), 4);
67+
is($dbh->last_insert_id(undef, undef, undef, undef), 4);
68+
69+
ok !$sth2->more_results;
70+
71+
$dbh->do('INSERT INTO async_test VALUES(5)', { mariadb_async => 1 });
72+
73+
is($sth0->last_insert_id(), 1);
74+
is($sth2->last_insert_id(), 4);
75+
is($dbh->last_insert_id(undef, undef, undef, undef), 4);
76+
77+
ok defined($dbh->mariadb_async_ready);
78+
ok !$dbh->err;
79+
80+
is($sth0->last_insert_id(), 1);
81+
is($sth2->last_insert_id(), 4);
82+
is($dbh->last_insert_id(undef, undef, undef, undef), 4);
83+
84+
ok defined($dbh->mariadb_async_result);
85+
ok !$sth2->err;
86+
87+
is($sth0->last_insert_id(), 1);
88+
is($sth2->last_insert_id(), 4);
89+
is($dbh->last_insert_id(undef, undef, undef, undef), 5);
90+
3591
undef $sth0;
3692
undef $sth1;
93+
undef $sth2;
3794

3895
$dbh->disconnect;

0 commit comments

Comments
 (0)