Hi,
I've tracked down a segfault in DBD::Pg 2.6.1, and I've got a patch.
Version: DBD-Pg-2.6.1 (also had problem with DBD-Pg-2.1.3)
Other versions: Perl-5.8.8, DBI-1.602
System: CentOS release 5 (Final), Linux centos5.drh.net 2.6.18-8.el5
With this perl code:
>>>
$dbh->do(q[ COPY ( SELECT * FROM table_with_no_rows ) TO
STDOUT WITH DELIMITER ',' ]);
my $data;
my $last = 0;
while ( ! $last )
{
$last = $dbh->pg_getcopydata($data) == -1;
# do stuff.
}
<<<
I got a segfault from pg_getcopydata when the query returned no rows.
It worked fine when the query did return rows.
Here's the info from gdb on the segfault:
>>>
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1208076608 (LWP 24340)]
0x00f8bb56 in pg_db_getcopydata (dbh=0x8ca9534, dataline=0x8de7320,
async=0) at dbdimp.c:3672
3672 SvCUR_set(dataline, 0);
(gdb) p dataline
$1 = (SV *) 0x8de7320
(gdb) p *dataline
$2 = {sv_any = 0x0, sv_refcnt = 1, sv_flags = 1280}
<<<
Here's the patch:
>>>
--- DBD-Pg-2.6.1.orig/dbdimp.c 2008-04-22 12:56:32.000000000 -0500
+++ DBD-Pg-2.6.1/dbdimp.c 2008-04-30 05:03:22.000000000 -0500
@@ -3664,7 +3664,7 @@
else if (-1 == copystatus) {
PGresult * result;
ExecStatusType status;
- SvCUR_set(dataline, 0);
+ sv_setpv(dataline, "");
imp_dbh->copystate=0;
TRACE_PQGETRESULT;
result = PQgetResult(imp_dbh->conn);
<<<
If pg_getcopydata is called and the buffer variable is a freshly
defined variable and copystatus == -1, then the SvCUR_set call
segfaults because there is no string component allocated for this SV,
so the length of the string component can't be set to zero. I changed
to using the sv_setpv() call to just set it to a zero length string.
This fixes the segfault in my case.
I'm not a perl internals expert, so you might want to double check this.
Thanks!
David