Skip to content

Commit 45e8bd8

Browse files
committed
Properly invalidate statement attributes in mariadb_st_more_results()
All attributes are invalid after trying to move to the next result.
1 parent 6e5b0b1 commit 45e8bd8

File tree

2 files changed

+51
-27
lines changed

2 files changed

+51
-27
lines changed

dbdimp.c

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4128,9 +4128,34 @@ bool mariadb_st_more_results(SV* sth, imp_sth_t* imp_sth)
41284128
imp_sth->result= NULL;
41294129
}
41304130

4131+
imp_sth->done_desc = FALSE;
41314132
imp_sth->currow = 0;
41324133
imp_sth->row_num = 0;
41334134

4135+
/* clear NUM_OF_FIELDS attribute */
4136+
DBIc_DBISTATE(imp_sth)->set_attr_k(sth, sv_2mortal(newSVpvs("NUM_OF_FIELDS")), 0, sv_2mortal(newSViv(0)));
4137+
4138+
/* delete cached handle attributes */
4139+
/* XXX should be driven by a list to ease maintenance */
4140+
(void)hv_deletes((HV*)SvRV(sth), "NAME", G_DISCARD);
4141+
(void)hv_deletes((HV*)SvRV(sth), "NULLABLE", G_DISCARD);
4142+
(void)hv_deletes((HV*)SvRV(sth), "NUM_OF_FIELDS", G_DISCARD);
4143+
(void)hv_deletes((HV*)SvRV(sth), "PRECISION", G_DISCARD);
4144+
(void)hv_deletes((HV*)SvRV(sth), "SCALE", G_DISCARD);
4145+
(void)hv_deletes((HV*)SvRV(sth), "TYPE", G_DISCARD);
4146+
(void)hv_deletes((HV*)SvRV(sth), "mariadb_insertid", G_DISCARD);
4147+
(void)hv_deletes((HV*)SvRV(sth), "mariadb_is_auto_increment", G_DISCARD);
4148+
(void)hv_deletes((HV*)SvRV(sth), "mariadb_is_blob", G_DISCARD);
4149+
(void)hv_deletes((HV*)SvRV(sth), "mariadb_is_key", G_DISCARD);
4150+
(void)hv_deletes((HV*)SvRV(sth), "mariadb_is_num", G_DISCARD);
4151+
(void)hv_deletes((HV*)SvRV(sth), "mariadb_is_pri_key", G_DISCARD);
4152+
(void)hv_deletes((HV*)SvRV(sth), "mariadb_length", G_DISCARD);
4153+
(void)hv_deletes((HV*)SvRV(sth), "mariadb_max_length", G_DISCARD);
4154+
(void)hv_deletes((HV*)SvRV(sth), "mariadb_table", G_DISCARD);
4155+
(void)hv_deletes((HV*)SvRV(sth), "mariadb_type", G_DISCARD);
4156+
(void)hv_deletes((HV*)SvRV(sth), "mariadb_type_name", G_DISCARD);
4157+
(void)hv_deletes((HV*)SvRV(sth), "mariadb_warning_count", G_DISCARD);
4158+
41344159
if (DBIc_ACTIVE(imp_sth))
41354160
DBIc_ACTIVE_off(imp_sth);
41364161

@@ -4178,45 +4203,19 @@ bool mariadb_st_more_results(SV* sth, imp_sth_t* imp_sth)
41784203
imp_sth->row_num = mysql_affected_rows(imp_dbh->pmysql);
41794204

41804205
imp_dbh->insertid = imp_sth->insertid = mysql_insert_id(imp_dbh->pmysql);
4181-
/* No "real" rowset*/
4182-
DBIS->set_attr_k(sth, sv_2mortal(newSVpvs("NUM_OF_FIELDS")), 0,
4183-
sv_2mortal(newSViv(0)));
41844206
return TRUE;
41854207
}
41864208
else
41874209
{
41884210
/* We have a new rowset */
41894211
imp_sth->row_num = mysql_num_rows(imp_sth->result);
41904212

4191-
/* delete cached handle attributes */
4192-
/* XXX should be driven by a list to ease maintenance */
4193-
(void)hv_deletes((HV*)SvRV(sth), "NAME", G_DISCARD);
4194-
(void)hv_deletes((HV*)SvRV(sth), "NULLABLE", G_DISCARD);
4195-
(void)hv_deletes((HV*)SvRV(sth), "NUM_OF_FIELDS", G_DISCARD);
4196-
(void)hv_deletes((HV*)SvRV(sth), "PRECISION", G_DISCARD);
4197-
(void)hv_deletes((HV*)SvRV(sth), "SCALE", G_DISCARD);
4198-
(void)hv_deletes((HV*)SvRV(sth), "TYPE", G_DISCARD);
4199-
(void)hv_deletes((HV*)SvRV(sth), "mariadb_insertid", G_DISCARD);
4200-
(void)hv_deletes((HV*)SvRV(sth), "mariadb_is_auto_increment", G_DISCARD);
4201-
(void)hv_deletes((HV*)SvRV(sth), "mariadb_is_blob", G_DISCARD);
4202-
(void)hv_deletes((HV*)SvRV(sth), "mariadb_is_key", G_DISCARD);
4203-
(void)hv_deletes((HV*)SvRV(sth), "mariadb_is_num", G_DISCARD);
4204-
(void)hv_deletes((HV*)SvRV(sth), "mariadb_is_pri_key", G_DISCARD);
4205-
(void)hv_deletes((HV*)SvRV(sth), "mariadb_length", G_DISCARD);
4206-
(void)hv_deletes((HV*)SvRV(sth), "mariadb_max_length", G_DISCARD);
4207-
(void)hv_deletes((HV*)SvRV(sth), "mariadb_table", G_DISCARD);
4208-
(void)hv_deletes((HV*)SvRV(sth), "mariadb_type", G_DISCARD);
4209-
(void)hv_deletes((HV*)SvRV(sth), "mariadb_type_name", G_DISCARD);
4210-
(void)hv_deletes((HV*)SvRV(sth), "mariadb_warning_count", G_DISCARD);
4211-
42124213
/* Adjust NUM_OF_FIELDS - which also adjusts the row buffer size */
42134214
DBIc_DBISTATE(imp_sth)->set_attr_k(sth, sv_2mortal(newSVpvs("NUM_OF_FIELDS")), 0,
42144215
sv_2mortal(newSVuv(mysql_num_fields(imp_sth->result)))
42154216
);
42164217

42174218
DBIc_ACTIVE_on(imp_sth);
4218-
4219-
imp_sth->done_desc = FALSE;
42204219
}
42214220
imp_dbh->pmysql->net.last_errno= 0;
42224221
return TRUE;

t/76multi_statement.t

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use warnings;
33

44
use Test::More;
55
use DBI;
6+
use DBD::MariaDB;
67
use lib 't', '.';
78
require 'lib.pl';
89
$|= 1;
@@ -13,7 +14,7 @@ my $dbh = DbiTestConnect($test_dsn, $test_user, $test_password,
1314
{ RaiseError => 1, PrintError => 0, AutoCommit => 0,
1415
mariadb_multi_statements => 1 });
1516

16-
plan tests => 51;
17+
plan tests => 73;
1718

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

@@ -96,4 +97,28 @@ $dbh->{mariadb_server_prepare}= 0;
9697
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');
9798
ok($sth->finish());
9899

100+
# Check that statement attributes are correct after calling more_results
101+
ok($dbh->do("CREATE TEMPORARY TABLE dbd_mysql_t76multi3 (name_id1 INT, name_id2 INT)"));
102+
ok($sth = $dbh->prepare("SELECT name_id1 FROM dbd_mysql_t76multi3; INSERT INTO dbd_mysql_t76multi2 VALUES(11); SELECT name_id1, name_id2 FROM dbd_mysql_t76multi3; SYNTAX ERROR"));
103+
ok($sth->execute());
104+
is($sth->{NUM_OF_FIELDS}, 1);
105+
is($sth->{NUM_OF_PARAMS}, 0);
106+
is_deeply($sth->{NAME}, [ 'name_id1' ]);
107+
is_deeply($sth->{mariadb_type}, [ DBD::MariaDB::TYPE_LONG ]);
108+
ok($sth->more_results());
109+
is($sth->{NUM_OF_FIELDS}, 0);
110+
is($sth->{NUM_OF_PARAMS}, 0);
111+
ok(!eval { $sth->{NAME} });
112+
ok(!eval { $sth->{mariadb_type} });
113+
ok($sth->more_results());
114+
is($sth->{NUM_OF_FIELDS}, 2);
115+
is($sth->{NUM_OF_PARAMS}, 0);
116+
is_deeply($sth->{NAME}, [ 'name_id1', 'name_id2' ]);
117+
is_deeply($sth->{mariadb_type}, [ DBD::MariaDB::TYPE_LONG, DBD::MariaDB::TYPE_LONG ]);
118+
ok(!eval { $sth->more_results() });
119+
is($sth->{NUM_OF_FIELDS}, 0);
120+
is($sth->{NUM_OF_PARAMS}, 0);
121+
ok(!eval { $sth->{NAME} });
122+
ok(!eval { $sth->{mariadb_type} });
123+
99124
$dbh->disconnect();

0 commit comments

Comments
 (0)