diff -Nru libdbd-pg-perl-3.15.1/Changes libdbd-pg-perl-3.16.0/Changes --- libdbd-pg-perl-3.15.1/Changes 2022-02-14 02:54:04.000000000 +0000 +++ libdbd-pg-perl-3.16.0/Changes 2022-08-08 17:30:58.000000000 +0000 @@ -2,6 +2,24 @@ RT refers to rt.cpan.org +Version 3.16.0 (August 8, 2022) + + - Automatically use 64-bit versions of large object functions when available + [Dagfinn Ilmari Mannsåker, David Christensen] + + - Set UTF8 flag as needed for error messages + [Github user olafgw] + (Github issue #97) + + - In tests, do not assume what the default transaction isolation level will be + [Rene Schickbauer] + (Github issue #94) + + - Make tests smarter about detecting pg_ctl results in different locales + [Greg Sabino Mullane] + (Github issue #95) + + Version 3.15.1 (released February 13, 2022) - Fix missing "use File::Temp" diff -Nru libdbd-pg-perl-3.15.1/dbdimp.c libdbd-pg-perl-3.16.0/dbdimp.c --- libdbd-pg-perl-3.15.1/dbdimp.c 2022-02-13 16:21:46.000000000 +0000 +++ libdbd-pg-perl-3.16.0/dbdimp.c 2022-08-08 16:27:01.000000000 +0000 @@ -35,21 +35,6 @@ #endif -#if PGLIBVERSION < 90300 -unsigned int lo_lseek64(PGconn *conn, int fd, unsigned int offset, int whence); -unsigned int lo_lseek64(PGconn *conn, int fd, unsigned int offset, int whence) { - croak ("Cannot use lo_lseek64 unless compiled against Postgres 9.3 or later"); -} -unsigned int lo_tell64(PGconn *conn, int fd); -unsigned int lo_tell64(PGconn *conn, int fd) { - croak ("Cannot use lo_ltell64 unless compiled against Postgres 9.3 or later"); -} -int lo_truncate64(PGconn *conn, int fd, unsigned int len); -int lo_truncate64(PGconn *conn, int fd, unsigned int len) { - croak ("Cannot use lo_truncate64 unless compiled against Postgres 9.3 or later"); -} -#endif - #ifndef PG_DIAG_SCHEMA_NAME #define PG_DIAG_SCHEMA_NAME 's' #define PG_DIAG_TABLE_NAME 't' @@ -510,7 +495,7 @@ } /* No matter what state we are in, send an empty query to the backend */ - result = PQexec(imp_dbh->conn, "/* DBD::Pg ping test v3.15.1 */"); + result = PQexec(imp_dbh->conn, "/* DBD::Pg ping test v3.16.0 */"); status = PQresultStatus(result); PQclear(result); if (PGRES_FATAL_ERROR == status) { @@ -1146,7 +1131,7 @@ } } else { - val = newSVpv(currph->value,0); + val = newSVpv(currph->value,currph->valuelen); if (!hv_store_ent(pvhv, key, val, 0)) { SvREFCNT_dec(val); } @@ -4526,8 +4511,16 @@ if (TEND_slow) TRC(DBILOGFP, "%sEnd pg_db_error_field (fieldcode: %d)\n", THEADER_slow, fieldcode); - return NULL == PQresultErrorField(imp_dbh->last_result, fieldcode) ? &PL_sv_undef : - sv_2mortal(newSVpv(PQresultErrorField(imp_dbh->last_result, fieldcode), 0)); + char *pq_err_field = PQresultErrorField(imp_dbh->last_result, fieldcode); + if (NULL == pq_err_field) { + return &PL_sv_undef; + } + else { + SV *sv_err_field = newSVpv(pq_err_field, 0); + if (imp_dbh->pg_utf8_flag) + SvUTF8_on(sv_err_field); + return sv_2mortal(sv_err_field); + } } /* end of pg_db_error_field */ @@ -4821,7 +4814,7 @@ dTHX; D_imp_dbh(dbh); - if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_pg_lo_open (mode: %d objectid: %d)\n", + if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_pg_lo_open (mode: %d objectid: %u)\n", THEADER_slow, mode, lobjId); if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) { @@ -4870,8 +4863,8 @@ dTHX; D_imp_dbh(dbh); - if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_read (fd: %d length: %d)\n", - THEADER_slow, fd, (int)len); + if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_read (fd: %d length: %" UVuf ")\n", + THEADER_slow, fd, (UV)len); if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) { croak("Cannot call pg_lo_read when AutoCommit is on"); @@ -4895,8 +4888,8 @@ dTHX; D_imp_dbh(dbh); - if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_write (fd: %d length: %d)\n", - THEADER_slow, fd, (int)len); + if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_write (fd: %d length: %" UVuf ")\n", + THEADER_slow, fd, (UV)len); if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) { croak("Cannot call pg_lo_write when AutoCommit is on"); @@ -4914,13 +4907,13 @@ } /* ================================================================== */ -int pg_db_lo_lseek (SV * dbh, int fd, int offset, int whence) +IV pg_db_lo_lseek (SV * dbh, int fd, IV offset, int whence) { dTHX; D_imp_dbh(dbh); - if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_lseek (fd: %d offset: %d whence: %d)\n", + if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_lseek (fd: %d offset: %" IVdf " whence: %d)\n", THEADER_slow, fd, offset, whence); if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) { @@ -4930,43 +4923,28 @@ if (!pg_db_start_txn(aTHX_ dbh,imp_dbh)) return -1; - if (TLIBPQ_slow) { - TRC(DBILOGFP, "%slo_lseek\n", THEADER_slow); - } - - return lo_lseek(imp_dbh->conn, fd, offset, whence); /* new position, -1 on error */ - -} - - -/* ================================================================== */ -unsigned int pg_db_lo_lseek64 (SV * dbh, int fd, unsigned int offset, int whence) -{ - - dTHX; - D_imp_dbh(dbh); - - if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_lseek64 (fd: %d offset: %d whence: %d)\n", - THEADER_slow, fd, offset, whence); +#ifdef HAS64BITLO + if (imp_dbh->pg_server_version >= 90300) { + if (TLIBPQ_slow) + TRC(DBILOGFP, "%slo_lseek64\n", THEADER_slow); - if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) { - croak("Cannot call pg_lo_lseek64 when AutoCommit is on"); + return lo_lseek64(imp_dbh->conn, fd, offset, whence); /* new position, -1 on error */ } - if (!pg_db_start_txn(aTHX_ dbh,imp_dbh)) - return -1; + if (offset < INT_MIN || offset > INT_MAX) + croak("lo_lseek offset out of range of integer"); +#endif - if (TLIBPQ_slow) { - TRC(DBILOGFP, "%slo_lseek64\n", THEADER_slow); - } + if (TLIBPQ_slow) + TRC(DBILOGFP, "%slo_lseek\n", THEADER_slow); - return lo_lseek64(imp_dbh->conn, fd, offset, whence); /* new position, -1 on error */ + return lo_lseek(imp_dbh->conn, fd, offset, whence); /* new position, -1 on error */ } /* ================================================================== */ -int pg_db_lo_tell (SV * dbh, int fd) +IV pg_db_lo_tell (SV * dbh, int fd) { dTHX; @@ -4981,96 +4959,63 @@ if (!pg_db_start_txn(aTHX_ dbh,imp_dbh)) return -1; - if (TLIBPQ_slow) { +#ifdef HAS64BITLO + if (TLIBPQ_slow) + TRC(DBILOGFP, "%slo_tell64\n", THEADER_slow); + + if (imp_dbh->pg_server_version >= 90300) + return lo_tell64(imp_dbh->conn, fd); /* current position, <0 on error */ +#endif + + if (TLIBPQ_slow) TRC(DBILOGFP, "%slo_tell\n", THEADER_slow); - } return lo_tell(imp_dbh->conn, fd); /* current position, <0 on error */ } /* ================================================================== */ -unsigned int pg_db_lo_tell64 (SV * dbh, int fd) +int pg_db_lo_truncate (SV * dbh, int fd, IV len) { dTHX; D_imp_dbh(dbh); - if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_tell64 (fd: %d)\n", THEADER_slow, fd); + if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_truncate (fd: %d length: %" IVdf ")\n", + THEADER_slow, fd, len); if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) { - croak("Cannot call pg_lo_tell64 when AutoCommit is on"); + croak("Cannot call pg_lo_truncate when AutoCommit is on"); } if (!pg_db_start_txn(aTHX_ dbh,imp_dbh)) return -1; - if (TLIBPQ_slow) { - TRC(DBILOGFP, "%slo_tell64\n", THEADER_slow); - } - - return lo_tell64(imp_dbh->conn, fd); /* current position, <0 on error */ - -} - -/* ================================================================== */ -int pg_db_lo_truncate (SV * dbh, int fd, size_t len) -{ - - dTHX; - D_imp_dbh(dbh); - - if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_truncate (fd: %d length: %d)\n", - THEADER_slow, fd, (int)len); +#ifdef HAS64BITLO + if (TLIBPQ_slow) + TRC(DBILOGFP, "%slo_truncate64\n", THEADER_slow); - if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) { - croak("Cannot call pg_lo_truncate when AutoCommit is on"); - } + if (imp_dbh->pg_server_version >= 90300) + return lo_truncate64(imp_dbh->conn, fd, len); /* 0 success, <0 on error */ - if (!pg_db_start_txn(aTHX_ dbh,imp_dbh)) - return -1; + if (len < INT_MIN || len > INT_MAX) + croak("lo_truncate len out of range of integer"); +#endif - if (TLIBPQ_slow) { + if (TLIBPQ_slow) TRC(DBILOGFP, "%slo_truncate\n", THEADER_slow); - } - return lo_truncate(imp_dbh->conn, fd, len); /* 0 success, <0 on error */ } /* ================================================================== */ -int pg_db_lo_truncate64 (SV * dbh, int fd, unsigned int len) -{ - - dTHX; - D_imp_dbh(dbh); - - if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_truncate64 (fd: %d length: %d)\n", - THEADER_slow, fd, (unsigned int)len); - - if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) { - croak("Cannot call pg_lo_truncate64 when AutoCommit is on"); - } - - if (!pg_db_start_txn(aTHX_ dbh,imp_dbh)) - return -1; - - if (TLIBPQ_slow) { - TRC(DBILOGFP, "%slo_truncate64\n", THEADER_slow); - } - - return lo_truncate64(imp_dbh->conn, fd, len); /* 0 success, <0 on error */ - -} - -/* ================================================================== */ int pg_db_lo_unlink (SV * dbh, unsigned int lobjId) { dTHX; D_imp_dbh(dbh); - if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_unlink (objectid: %d)\n", THEADER_slow, lobjId); + if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_unlink (objectid: %u)\n", THEADER_slow, lobjId); if (DBIc_has(imp_dbh, DBIcf_AutoCommit)) { croak("Cannot call pg_lo_unlink when AutoCommit is on"); @@ -5150,7 +5095,7 @@ dTHX; D_imp_dbh(dbh); - if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_export (objectid: %d filename: %s)\n", + if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_lo_export (objectid: %u filename: %s)\n", THEADER_slow, lobjId, filename); if (!pg_db_start_txn(aTHX_ dbh,imp_dbh)) diff -Nru libdbd-pg-perl-3.15.1/dbdimp.h libdbd-pg-perl-3.16.0/dbdimp.h --- libdbd-pg-perl-3.15.1/dbdimp.h 2022-01-04 18:55:13.000000000 +0000 +++ libdbd-pg-perl-3.16.0/dbdimp.h 2022-08-08 15:46:20.000000000 +0000 @@ -258,17 +258,11 @@ int pg_db_lo_write (SV *dbh, int fd, char *buf, size_t len); -int pg_db_lo_lseek (SV *dbh, int fd, int offset, int whence); +IV pg_db_lo_lseek (SV *dbh, int fd, IV offset, int whence); -unsigned int pg_db_lo_lseek64 (SV *dbh, int fd, unsigned int offset, int whence); +IV pg_db_lo_tell (SV *dbh, int fd); -int pg_db_lo_tell (SV *dbh, int fd); - -unsigned int pg_db_lo_tell64 (SV *dbh, int fd); - -int pg_db_lo_truncate (SV *dbh, int fd, size_t len); - -int pg_db_lo_truncate64 (SV *dbh, int fd, unsigned int len); +int pg_db_lo_truncate (SV *dbh, int fd, IV len); int pg_db_lo_unlink (SV *dbh, unsigned int lobjId); diff -Nru libdbd-pg-perl-3.15.1/debian/changelog libdbd-pg-perl-3.16.0/debian/changelog --- libdbd-pg-perl-3.15.1/debian/changelog 2022-02-17 20:48:06.000000000 +0000 +++ libdbd-pg-perl-3.16.0/debian/changelog 2022-08-10 09:35:27.000000000 +0000 @@ -1,3 +1,9 @@ +libdbd-pg-perl (3.16.0-1) unstable; urgency=medium + + * New upstream version 3.16.0. + + -- Christoph Berg Wed, 10 Aug 2022 11:35:27 +0200 + libdbd-pg-perl (3.15.1-1) unstable; urgency=medium * Import upstream version 3.15.1. diff -Nru libdbd-pg-perl-3.15.1/lib/Bundle/DBD/Pg.pm libdbd-pg-perl-3.16.0/lib/Bundle/DBD/Pg.pm --- libdbd-pg-perl-3.15.1/lib/Bundle/DBD/Pg.pm 2022-02-13 16:21:10.000000000 +0000 +++ libdbd-pg-perl-3.16.0/lib/Bundle/DBD/Pg.pm 2022-08-08 16:18:07.000000000 +0000 @@ -5,7 +5,7 @@ use warnings; use 5.008001; -our $VERSION = '3.15.1'; +our $VERSION = '3.16.0'; 1; diff -Nru libdbd-pg-perl-3.15.1/Makefile.PL libdbd-pg-perl-3.16.0/Makefile.PL --- libdbd-pg-perl-3.15.1/Makefile.PL 2022-02-13 16:21:26.000000000 +0000 +++ libdbd-pg-perl-3.16.0/Makefile.PL 2022-08-08 16:17:20.000000000 +0000 @@ -5,7 +5,7 @@ use 5.008001; ## No version.pm for this one, as the prereqs are not loaded yet. -my $VERSION = '3.15.1'; +my $VERSION = '3.16.0'; ## App::Info is stored inside t/lib ## Create a proper path so we can use it below @@ -183,6 +183,9 @@ } my $defines = " -DPGLIBVERSION=$serverversion -DPGDEFPORT=$defaultport"; +if ($Config{ivsize} >= 8 && $serverversion >= 90300) { + $defines .= ' -DHAS64BITLO'; +} my $comp_opts = $Config{q{ccflags}} . $defines; if ($ENV{DBDPG_GCCDEBUG}) { diff -Nru libdbd-pg-perl-3.15.1/MANIFEST.SKIP libdbd-pg-perl-3.16.0/MANIFEST.SKIP --- libdbd-pg-perl-3.15.1/MANIFEST.SKIP 2021-01-10 17:00:07.000000000 +0000 +++ libdbd-pg-perl-3.16.0/MANIFEST.SKIP 2022-08-08 15:46:10.000000000 +0000 @@ -2,7 +2,6 @@ ^Build$ ^Makefile$ ^Makefile.old$ -^MANIFEST\.SKIP$ README.testdatabase ^Pg.c$ ^Pg.bs$ diff -Nru libdbd-pg-perl-3.15.1/META.yml libdbd-pg-perl-3.16.0/META.yml --- libdbd-pg-perl-3.15.1/META.yml 2022-02-13 16:21:22.000000000 +0000 +++ libdbd-pg-perl-3.16.0/META.yml 2022-08-08 16:17:40.000000000 +0000 @@ -1,6 +1,6 @@ --- #YAML:1.0 name : DBD-Pg -version : 3.15.1 +version : 3.16.0 abstract : DBI PostgreSQL interface author: - Greg Sabino Mullane @@ -30,10 +30,10 @@ provides: DBD::Pg: file : Pg.pm - version : 3.15.1 + version : 3.16.0 Bundle::DBD::Pg: file : lib/Bundle/DBD/Pg.pm - version : 3.15.1 + version : 3.16.0 keywords: - Postgres diff -Nru libdbd-pg-perl-3.15.1/.perlcriticrc libdbd-pg-perl-3.16.0/.perlcriticrc --- libdbd-pg-perl-3.15.1/.perlcriticrc 2021-05-24 14:44:20.000000000 +0000 +++ libdbd-pg-perl-3.16.0/.perlcriticrc 2022-08-08 15:46:10.000000000 +0000 @@ -28,6 +28,10 @@ [-CodeLayout::RequireUseUTF8] [-CodeLayout::TabIndentSpaceAlign] [-CognitiveComplexity::ProhibitExcessCognitiveComplexity] +[-Community::Each] +[-Community::EmptyReturn] +[-Community::PackageMatchesFilename] +[-Community::WhileDiamondDefaultAssignment] [-Compatibility::PodMinimumVersion] [-ControlStructures::ProhibitCascadingIfElse] [-ControlStructures::ProhibitCStyleForLoops] diff -Nru libdbd-pg-perl-3.15.1/Pg.pm libdbd-pg-perl-3.16.0/Pg.pm --- libdbd-pg-perl-3.15.1/Pg.pm 2022-02-13 16:21:39.000000000 +0000 +++ libdbd-pg-perl-3.16.0/Pg.pm 2022-08-08 16:37:32.000000000 +0000 @@ -16,7 +16,7 @@ { package DBD::Pg; - use version; our $VERSION = qv('3.15.1'); + use version; our $VERSION = qv('3.16.0'); use DBI 1.614 (); use Exporter (); @@ -137,7 +137,7 @@ $class .= '::dr'; ## Work around for issue found in https://rt.cpan.org/Ticket/Display.html?id=83057 - my $realversion = qv('3.15.1'); + my $realversion = qv('3.16.0'); $drh = DBI::_new_drh($class, { 'Name' => 'Pg', @@ -1698,7 +1698,7 @@ =head1 VERSION -This documents version 3.15.1 of the DBD::Pg module +This documents version 3.16.0 of the DBD::Pg module =head1 DESCRIPTION @@ -2089,9 +2089,9 @@ =item pg_lo_lseek64 - $loc = $dbh->pg_lo_lseek64($lobj_fd, $offset, $whence); - -Same as pg_lo_lseek, but can handle much larger offsets and returned values. Requires Postgres 9.3 or greater. +Backwards compatible alias for L. Since DBD::Pg 3.16, that +method handles 64-bit offsets if supported by the Perl and PostgreSQL versions +in use. =item pg_lo_tell @@ -2102,9 +2102,9 @@ =item pg_lo_tell64 - $loc = $dbh->pg_lo_tell64($lobj_fd); - -Same as pg_lo_tell, but can return much larger values. Requires Postgres 9.3 or greater. +Backwards compatible alias for L. Since DBD::Pg 3.16, that +method handles 64-bit offsets if supported by the Perl and PostgreSQL versions +in use. =item pg_lo_truncate @@ -2115,9 +2115,9 @@ =item pg_lo_truncate64 - $loc = $dbh->pg_lo_truncate64($lobj_fd, $len); - -Same as pg_lo_truncate, but can handle much larger lengths. Requires Postgres 9.3 or greater. +Backwards compatible alias L. Since DBD::Pg 3.16, that +method handles 64-bit offsets if supported by the Perl and PostgreSQL versions +in use. =item pg_lo_close @@ -2788,7 +2788,7 @@ The C method determines if there is a working connection to an active database server. It does this by sending a small query to the server, currently -B<'DBD::Pg ping test v3.15.1'>. It returns 0 (false) if the connection is not valid, +B<'DBD::Pg ping test v3.16.0'>. It returns 0 (false) if the connection is not valid, otherwise it returns a positive number (true). The value returned indicates the current state: @@ -4199,14 +4199,14 @@ print "Result: $result\n"; my $info = $sth->fetchall_arrayref(); -Without asynchronous queries, the above script would take about 8 seconds to run: five seconds waiting -for the execute to finish, then three for the check_on_the_kids() function to return. With asynchronous -queries, the script takes about 6 seconds to run, and gets in two iterations of check_on_the_kids in +Without asynchronous queries, the above script would take about 8 seconds to run: five seconds waiting +for the execute to finish, then three for the check_on_the_kids() function to return. With asynchronous +queries, the script takes about 6 seconds to run, and gets in two iterations of check_on_the_kids in the process. -Here's an example showing the ability to cancel a long-running query. Imagine two slave databases in -different geographic locations over a slow network. You need information as quickly as possible, so -you query both at once. When you get an answer, you tell the other one to stop working on your query, +Here's an example showing the ability to cancel a long-running query. Imagine two replica databases in +different geographic locations over a slow network. You need information as quickly as possible, so +you query both at once. When you get an answer, you tell the other one to stop working on your query, as you don't need it anymore. use strict; @@ -4214,13 +4214,13 @@ use Time::HiRes 'sleep'; use DBD::Pg ':async'; - my $dbhslave1 = DBI->connect('dbi:Pg:dbname=postgres;host=slave1', 'postgres', '', {AutoCommit=>0,RaiseError=>1}); - my $dbhslave2 = DBI->connect('dbi:Pg:dbname=postgres;host=slave2', 'postgres', '', {AutoCommit=>0,RaiseError=>1}); + my $dbhrep1 = DBI->connect('dbi:Pg:dbname=postgres;host=replica1', 'postgres', '', {AutoCommit=>0,RaiseError=>1}); + my $dbhrep2 = DBI->connect('dbi:Pg:dbname=postgres;host=replica2', 'postgres', '', {AutoCommit=>0,RaiseError=>1}); $SQL = "SELECT count(*) FROM largetable WHERE flavor='blueberry'"; - my $sth1 = $dbhslave1->prepare($SQL, {pg_async => PG_ASYNC}); - my $sth2 = $dbhslave2->prepare($SQL, {pg_async => PG_ASYNC}); + my $sth1 = $dbhrep1->prepare($SQL, {pg_async => PG_ASYNC}); + my $sth2 = $dbhrep2->prepare($SQL, {pg_async => PG_ASYNC}); $sth1->execute(); $sth2->execute(); @@ -4296,12 +4296,15 @@ Used to retrieve data from a table after the server has been put into a COPY OUT mode by calling "COPY tablename TO STDOUT". Data is always returned -one data row at a time. The first argument to pg_getcopydata -is the variable into which the data will be stored (this variable should not -be undefined, or it may throw a warning, although it may be a reference). The -pg_getcopydata method returns a number greater than 1 indicating the new size of -the variable, or a -1 when the COPY has finished. Once a -1 has been returned, no -other action is necessary, as COPY mode will have already terminated. Example: +one data row at a time. Note that the server will add a newline to +each returned row. + +The first argument to pg_getcopydata is the variable into which the data will +be stored (this variable should not be undefined, or it may throw a warning, +although it may be a reference). The pg_getcopydata method returns a number +greater than 1 indicating the new size of the variable, or a -1 when the +COPY has finished. Once a -1 has been returned, no other action is necessary, +as COPY mode will have already terminated. Example: $dbh->do("COPY mytable TO STDOUT"); my @data; @@ -4377,6 +4380,10 @@ C<< $dbh->pg_lo* >> methods. Please note that access to a large object, even read-only large objects, must be put into a transaction. +If DBD::Pg is compiled against and connected to PostgreSQL 9.3 or newer, and +your Perl has 64-bit integers, it will use the 64-bit variants of the seek, +tell and truncate methods. + =head2 Cursors Although PostgreSQL supports cursors, they have not been used in the current diff -Nru libdbd-pg-perl-3.15.1/Pg.xs libdbd-pg-perl-3.16.0/Pg.xs --- libdbd-pg-perl-3.15.1/Pg.xs 2022-02-13 16:18:51.000000000 +0000 +++ libdbd-pg-perl-3.16.0/Pg.xs 2022-08-08 16:16:09.000000000 +0000 @@ -533,54 +533,33 @@ pg_lo_lseek(dbh, fd, offset, whence) SV * dbh int fd - int offset + IV offset int whence + ALIAS: + pg_lo_lseek64 = 1 CODE: - const int ret = pg_db_lo_lseek(dbh, fd, offset, whence); + const IV ret = pg_db_lo_lseek(dbh, fd, offset, whence); ST(0) = (ret >= 0) ? sv_2mortal(newSViv(ret)) : &PL_sv_undef; void -pg_lo_lseek64(dbh, fd, offset, whence) - SV * dbh - int fd - unsigned int offset - int whence - CODE: - const unsigned int ret = pg_db_lo_lseek64(dbh, fd, offset, whence); - ST(0) = (ret >= 0) ? sv_2mortal(newSVuv(ret)) : &PL_sv_undef; - -void pg_lo_tell(dbh, fd) SV * dbh int fd + ALIAS: + pg_lo_tell64 = 1 CODE: - const int ret = pg_db_lo_tell(dbh, fd); + const IV ret = pg_db_lo_tell(dbh, fd); ST(0) = (ret >= 0) ? sv_2mortal(newSViv(ret)) : &PL_sv_undef; void -pg_lo_tell64(dbh, fd) - SV * dbh - int fd - CODE: - const unsigned int ret = pg_db_lo_tell64(dbh, fd); - ST(0) = (ret >= 0) ? sv_2mortal(newSVuv(ret)) : &PL_sv_undef; - -void pg_lo_truncate(dbh, fd, len) SV * dbh int fd - size_t len - CODE: - const int ret = pg_db_lo_truncate(dbh, fd, len); - ST(0) = (ret >= 0) ? sv_2mortal(newSViv(ret)) : &PL_sv_undef; - -void -pg_lo_truncate64(dbh, fd, len) - SV * dbh - int fd - unsigned int len + UV len + ALIAS: + pg_lo_truncate64 = 1 CODE: - const int ret = pg_db_lo_truncate64(dbh, fd, len); + const IV ret = pg_db_lo_truncate(dbh, fd, len); ST(0) = (ret >= 0) ? sv_2mortal(newSViv(ret)) : &PL_sv_undef; void diff -Nru libdbd-pg-perl-3.15.1/README libdbd-pg-perl-3.16.0/README --- libdbd-pg-perl-3.15.1/README 2022-02-13 16:21:51.000000000 +0000 +++ libdbd-pg-perl-3.16.0/README 2022-08-08 16:18:25.000000000 +0000 @@ -6,7 +6,7 @@ DESCRIPTION: ------------ -This is version 3.15.1 of DBD::Pg, the Perl interface to Postgres using DBI. +This is version 3.16.0 of DBD::Pg, the Perl interface to Postgres using DBI. The web site for this interface, and the latest version, can be found at: http://search.cpan.org/dist/DBD-Pg/ diff -Nru libdbd-pg-perl-3.15.1/README.dev libdbd-pg-perl-3.16.0/README.dev --- libdbd-pg-perl-3.15.1/README.dev 2022-02-14 14:28:02.000000000 +0000 +++ libdbd-pg-perl-3.16.0/README.dev 2022-08-08 15:46:10.000000000 +0000 @@ -640,7 +640,7 @@ release tarball. Make sure there is nothing important here. * Update the SIGNATURE file with Module::Signature (e.g. make signature) -You may need to add this your login script: export GPG_TTY=$(tt) +You may need to add this your login script: export GPG_TTY=$(tty) * Run "make disttest". This unpacks the tarball, then runs "make" and "make test" on it. You may also want to remove the directory it creates later by using "make realclean" diff -Nru libdbd-pg-perl-3.15.1/SIGNATURE libdbd-pg-perl-3.16.0/SIGNATURE --- libdbd-pg-perl-3.15.1/SIGNATURE 2022-02-14 14:28:29.000000000 +0000 +++ libdbd-pg-perl-3.16.0/SIGNATURE 2022-08-08 17:37:35.000000000 +0000 @@ -15,35 +15,35 @@ Hash: RIPEMD160 SHA256 e4c6f4cdc9560a09492f196fc9a180867fab12742d7d05052d9842b395c6a9eb .dir-locals.el -SHA256 e23f1fcd188734118fec21c5c5525307568b67a0ba97308956f0dc7d0ad969a9 .perlcriticrc +SHA256 6955483d3b06de252f0ad63f79e8b9e2db548ba9f2d35e374208f11783adec48 .perlcriticrc SHA256 56479e9cf7c00a72bc5458593463a5a6e5481f74f3a4be5ef94129e01c3e2f91 CONTRIBUTING.md -SHA256 88c5779a39642272a8d6a9121160c2f2af7ef61cb735296d7059136362a6b9e8 Changes +SHA256 52298b1ec25ad14694136449526233a34b3e79343e59c971354919bcffa5356b Changes SHA256 d52a34724b2e3c40ffa2b3b378b574b9e3db27bc3132c88e0be3675f93f378a5 LICENSES/artistic.txt SHA256 ab15fd526bd8dd18a9e77ebc139656bf4d33e97fc7238cd11bf60e2b9b8666c6 LICENSES/gpl-2.0.txt SHA256 e15fb8180cca35de2c3de6854e5cf23152a7733dfa89640825ae13f6f83b0e72 MANIFEST -SHA256 f41d8891a80fa4f3fbf1c96fc745a2c8ecc0497045a9ad55daea54d5ffcb4683 MANIFEST.SKIP -SHA256 019a9651599b817d3d7158fbc22d5def79c7501fb78168db896a150f4a7e450e META.yml -SHA256 11cb552865555c28060ae56d42e61603b9d4bbc325a264b00d296fa21fa660b8 Makefile.PL +SHA256 0d4dfe54c01254ecc426b4c863fe7b018222c493b3779a6fa0f351d45c7edc62 MANIFEST.SKIP +SHA256 c74c3d87d3127ccb6013a6e8f2de95ca2dffd9b71127a5f91e934cfa53a74077 META.yml +SHA256 9b35a9daba06d2aa0485e0f7ade788855ca0701f26412b61ff101195b00d8445 Makefile.PL SHA256 2328fcf8d7f8bfa302c0a33849f962c954cd4a84f5f8e3eb10ed39dc109d6e48 Pg.h -SHA256 860d878e9d20c0a464502ac5aac612b35c43943c2ab263a1245ea731f8317f05 Pg.pm -SHA256 91affbe168f26f401ad0b04f8eb1055dea0e4a8ab6d4b2db6a01e2b2758e0d20 Pg.xs -SHA256 82caf782daa342e891599c74e7025ca274c9d3dabe8477dd9522c6ae85503e63 README -SHA256 427ef64029a0a92757f317d53deab7bcf290a2ec0618ba49ea95269117ee04cf README.dev +SHA256 798bafdb47421047031ce1213877d3f51247cfc218198e2177384f91b2ec7955 Pg.pm +SHA256 4016ca9499117caf522a68b1e2941bea4d7337b90e2f6b5e084645883531c8ae Pg.xs +SHA256 a4e3d9700906180f748a496d5f5c18b7657ab6e38a48b2d81a2531cf2f5c1644 README +SHA256 1da8295c86767f603fca161ded7849a5e15dc1bae7cc4f9210c990b533d80b79 README.dev SHA256 a1d224603fe3a343ba0a0f40086065c81d57fbebc734b5382b0d359da16bdd94 README.win32 SHA256 f449097b5796005dffa234e0bcf03863ebe89cb5c573cb50211081d790de2009 TODO -SHA256 6102c51f8a33f159cfd0b1739ec4edfdcd3bd978ed4e4d98958be64cd6c076a2 dbdimp.c -SHA256 a3ee09fd22f33f9c341ddb86a6656c32de637fc789795dc6aa2fc58675729e4d dbdimp.h +SHA256 82486872136a95c961035b17c8cbe2c41b4a181a6f4b959afa2d28fd324d8929 dbdimp.c +SHA256 75727d16a4ffcc313ab7efaf0ef4e68ee4c71601f75ab9dcfdff8d22202cf641 dbdimp.h SHA256 9e53f7f41aaaf1b540e2784756ef6f16f61b63df0d9956483aded3c49b6e0f48 dbivport.h -SHA256 452f5ef35954fa38d4199cf21bc98db912641330fdd9eee8146823eaaa31588c lib/Bundle/DBD/Pg.pm +SHA256 d85b062ca2ff284ff808d30873007e79d5d87dbf77099a0001c342c7dad7a393 lib/Bundle/DBD/Pg.pm SHA256 7e204ad6b4b5eef61a39038666d3524af7a02c53e09ad5a22bf3ca69610b8072 quote.c SHA256 1ee43f02036bbb68c151903c2718c483ed223aff6cc93fb1408a9158adad9136 quote.h SHA256 49950c2c882018916ef89b59a1707b732064eb3bb6acb6a350111e1dc81000b8 t/00_signature.t SHA256 4a95e025f903ed2d6a0aa4470f46f075d4692b9a21bd1d316ead19fb9cabd2dd t/00basic.t -SHA256 60aebe62caa74ce46b15833361c587c23f889869beb72f12fda984ec2a359cb2 t/01connect.t +SHA256 19c34e8f25985d5fca96fe49bb3bbc89981a6499962b846af2601755e2cd4f59 t/01connect.t SHA256 50ce2e03b34dfc5e45c0af8f4078825b1ed449d201f165d8d05453762110ae72 t/01constants.t -SHA256 4a57102776fa991abbdf52427f14b2200b0de9415495f625bbb4a89b3f9c99c0 t/02attribs.t -SHA256 2c8ae070dcc5bd2b716be9094011de898ae79cc6df72fbea19672bce16f9afd9 t/03dbmethod.t -SHA256 f6769b211e07e4bdeaf6e8b70c91dc2568758a92011f34d1315f9ee73478a82e t/03smethod.t +SHA256 089cf8dd34a415438f90a78282116a90585f65e4a6978460f8fc2eecc3e253bc t/02attribs.t +SHA256 85068dd6ee1578da1a57e950ba57889ddbb041a2fffbeb68e1d78a36dc095255 t/03dbmethod.t +SHA256 db32515a2955990ef8a937e7586f06c409622fb3f7d1bb8508a857929a008710 t/03smethod.t SHA256 a3767a1b6e9adf62ec73f9d38b8bca151eb2fd872d42c2f77aeaef72178b1c56 t/04misc.t SHA256 d30d52695492fbcb2d051c48d0d3afb621b0d5b29d876208b5fd79c5bc50b3fa t/06bytea.t SHA256 f172234f057e485a8d5838db6986dbda18f4fe81fcf9ad0885728b8aec31b852 t/07copy.t @@ -54,7 +54,7 @@ SHA256 982a438ec73b0428c263ed4608d82fd466a1668cfd4095c69d93ae002486368c t/20savepoints.t SHA256 6bdf1b5d0bdc049bf8ff8a66d36fc41dfaea2d15e8550dc7e19ce152aa73c918 t/30unicode.t SHA256 16b874ee36dcedc566b6c9b4c8142173e3a6babc660721939756d8a0a7d697f2 t/99cleanup.t -SHA256 029ef8e8a47a47639f9fcf4036fa14c7dd924d60a171ac9af888364d722577f8 t/dbdpg_test_setup.pl +SHA256 56f45cc6f3c2c40e8ef77841fa6ea793f68f9d23477c41bdedc1b445e5f7e359 t/dbdpg_test_setup.pl SHA256 3f53191613dc10d2d30414f7e6e31a3b3486d91fe07ee77d24ea3d6f2eb61bb6 t/lib/App/Info.pm SHA256 8faf2c2b3ff952ff0721c04ac8e04ec143939592b0d55a135ea15d310144f576 t/lib/App/Info/Handler.pm SHA256 e3c5a92afea9c568bf9534a0f13e84864bce0899d2d96857bdaba2c2c565d6e8 t/lib/App/Info/Handler/Print.pm @@ -69,7 +69,7 @@ SHA256 4628f92764bdb3e2b04bda7f30fc497231fbbf80dfd24cc09ee3df2e6d6d4387 win32.mak -----BEGIN PGP SIGNATURE----- -iF0EAREDAB0WIQQlKd9quPeUB+lERbS8m5BnFJZKyAUCYgpnDAAKCRC8m5BnFJZK -yPMOAJ91G76O7kasaMwvD5G7XHTH9FgM3wCffwhvDrcovyTuWcitYsn1FpVYv1w= -=0xT6 +iF0EAREDAB0WIQQlKd9quPeUB+lERbS8m5BnFJZKyAUCYvFJzgAKCRC8m5BnFJZK +yALcAJ93175EngM5L1L/HJP2fr4W7EY9NQCeMebKj1lROUmANMxu3Sv9aufCsnc= +=6/2P -----END PGP SIGNATURE----- diff -Nru libdbd-pg-perl-3.15.1/t/01connect.t libdbd-pg-perl-3.16.0/t/01connect.t --- libdbd-pg-perl-3.15.1/t/01connect.t 2021-05-24 14:44:20.000000000 +0000 +++ libdbd-pg-perl-3.16.0/t/01connect.t 2022-08-08 15:46:10.000000000 +0000 @@ -24,7 +24,7 @@ if (! defined $dbh or $connerror) { plan skip_all => 'Connection to database failed, cannot continue testing'; } -plan tests => 15; +plan tests => 16; pass ('Established a connection to the database'); @@ -108,6 +108,18 @@ ok (ref $ldbh, $t); $ldbh->disconnect(); + SKIP: { + if ($pglibversion < 100000) { + skip ('Multiple host names requies libpq >= 10', 1); + } + $t=q{Connect with multiple host names works}; + $testdsn =~ s/host=/host=foo.invalid,/; + $ldbh = DBI->connect($testdsn, $testuser, $ENV{DBI_PASS}, + {RaiseError => 1, PrintError => 0, AutoCommit => 0}); + ok (ref $ldbh, $t); + $ldbh->do('select 1'); + $ldbh->disconnect(); + } if ($ENV{DBI_DSN} =~ /$alias\s*=\s*\"/) { skip ('DBI_DSN already contains quoted database, no need for explicit test', 1); } diff -Nru libdbd-pg-perl-3.15.1/t/02attribs.t libdbd-pg-perl-3.16.0/t/02attribs.t --- libdbd-pg-perl-3.15.1/t/02attribs.t 2021-05-20 14:46:42.000000000 +0000 +++ libdbd-pg-perl-3.16.0/t/02attribs.t 2022-08-08 15:46:10.000000000 +0000 @@ -18,7 +18,7 @@ if (! $dbh) { plan skip_all => 'Connection to database failed, cannot continue testing'; } -plan tests => 284; +plan tests => 285; isnt ($dbh, undef, 'Connect to database for handle attributes testing'); @@ -856,6 +856,14 @@ $attrib = $sth->{ParamValues}; is_deeply ($attrib, $expected, $t); +$t='Statement handle attribute "ParamValues" works with NULL-embedded strings'; +my $tvalue = "aaa\000bbb"; # binary data with \0 +$sth = $dbh->prepare('INSERT INTO dbd_pg_test (id, val, pname) VALUES (?, ?, "")'); +$sth->bind_param(1, 1234); +$sth->bind_param(2, $tvalue, {pg_type => PG_BYTEA}); +$attrib = $sth->{ParamValues}; +is ($attrib->{2}, $tvalue); + # # Test of the statement handle attribute "ParamTypes" # diff -Nru libdbd-pg-perl-3.15.1/t/03dbmethod.t libdbd-pg-perl-3.16.0/t/03dbmethod.t --- libdbd-pg-perl-3.15.1/t/03dbmethod.t 2021-05-24 14:44:20.000000000 +0000 +++ libdbd-pg-perl-3.16.0/t/03dbmethod.t 2022-08-08 16:40:56.000000000 +0000 @@ -17,8 +17,10 @@ use lib 'blib/lib', 'blib/arch', 't'; use Data::Dumper; use Test::More; +use Config; use DBI ':sql_types'; use DBD::Pg ':pg_types'; +use Fcntl ':seek'; require 'dbdpg_test_setup.pl'; select(($|=1,select(STDERR),$|=1)[1]); @@ -26,7 +28,6 @@ if (! $dbh) { plan skip_all => 'Connection to database failed, cannot continue testing'; } -plan tests => 646; my $superuser = is_super(); @@ -283,7 +284,7 @@ if ($pgversion < 80300) { $dbh->do("DROP TABLE $schema2.$table2"); $dbh->do("DROP SEQUENCE $schema2.$sequence2"); - skip ('Cannot test sequence rename on pre-8.3 servers', 2); + skip ('Cannot test sequence rename on pre-8.3 servers', 1); } $dbh->do("ALTER SEQUENCE $schema2.$sequence2 RENAME TO $sequence3"); $dbh->commit(); @@ -304,7 +305,7 @@ } SKIP: { - skip('Cannot test GENERATED AS IDENTITY columns on pre-10 servers', 4) + skip('Cannot test GENERATED AS IDENTITY columns on pre-10 servers', 1) if $pgversion < 100000; for my $WHEN ('BY DEFAULT', 'ALWAYS') { @@ -621,7 +622,7 @@ $t='DB handle method "get_info" returns expected result for SQL_DEFAULT_TXN_ISOLATION'; $result = $dbh->get_info('SQL_DEFAULT_TXN_ISOLATION'); -is ($result, '2', $t); +ok (($result==2 or $result==8), $t); $t='DB handle method "get_info" returns correct string for SQL_DATA_SOURCE_READ_ONLY when "on"'; $dbh->do(q{SET transaction_read_only = 'on'}); @@ -731,7 +732,7 @@ SKIP: { if ($pgversion < 90300) { - skip ('Cannot test table_info for materialized views unless database if 9.3 or higher', 3); + skip ('Cannot test table_info for materialized views unless database if 9.3 or higher', 1); } $sth = $dbh->table_info(undef,undef,undef,'MATERIALIZED VIEW'); @@ -756,11 +757,11 @@ SKIP: { if ($pgversion < 90100) { - skip ('Cannot test table_info for foreign tables unless database is 9.1 or higher', 3); + skip ('Cannot test table_info for foreign tables unless database is 9.1 or higher', 1); } ## We can check for finer-grained access in more recent versions, but this is good enough: - $superuser or skip ('Cannot test foreign tables unless a superuser', 3); + $superuser or skip ('Cannot test foreign tables unless a superuser', 1); $sth = $dbh->table_info(undef,undef,undef,'FOREIGN TABLE'); my $total_ftables = $sth->rows(); @@ -986,7 +987,7 @@ SKIP: { if ($pgversion < 80300) { - skip ('DB handle method column_info attribute "pg_enum_values" requires at least Postgres 8.3', 2); + skip ('DB handle method column_info attribute "pg_enum_values" requires at least Postgres 8.3', 1); } my @enumvalues = qw( foo bar baz buz ); @@ -1912,26 +1913,29 @@ isnt ($object, -1, $t); $t='DB handle method "pg_lo_lseek" works when writing'; -$result = $dbh->pg_lo_lseek($handle, 0, 0); +$result = $dbh->pg_lo_lseek($handle, 0, SEEK_SET); is ($result, 0, $t); isnt ($object, -1, $t); -SKIP: { - if ($pgversion < 90300 or $pglibversion < 90300) { - skip 'Cannot test 64-bit version of largeobject functions unless Postgres is 9.3 or higher', 2; - } - $t='DB handle method "pg_lo_lseek64" works when writing'; - $result = $dbh->pg_lo_lseek64($handle, 0, 0); - is ($result, 0, $t); - isnt ($object, -1, $t); -} - $t='DB handle method "pg_lo_write" works'; my $buf = 'tangelo mulberry passionfruit raspberry plantain' x 500; $result = $dbh->pg_lo_write($handle, $buf, length($buf)); is ($result, length($buf), $t); cmp_ok ($object, '>', 0, $t); +$t='DB handle method "pg_lo_tell" works when writing'; +$result = $dbh->pg_lo_tell($handle); +is ($result, length($buf), $t); + +$t='DB handle method "pg_lo_lseek(SEEK_END)" works when writing'; +$result = $dbh->pg_lo_lseek($handle, 0, SEEK_END); +is ($result, length($buf), $t); +isnt ($object, -1, $t); + +$t='DB handle method "pg_lo_tell" works after seek when writing'; +$result = $dbh->pg_lo_tell($handle); +is ($result, length($buf), $t); + $t='DB handle method "pg_lo_close" works after write'; $result = $dbh->pg_lo_close($handle); ok ($result, $t); @@ -1942,34 +1946,40 @@ like ($handle, qr/^[0-9]+$/o, $t); cmp_ok ($handle, 'eq', 0, $t); -$t='DB handle method "pg_lo_lseek" works when reading'; -$result = $dbh->pg_lo_lseek($handle, 11, 0); +$t='DB handle method "pg_lo_lseek(SEEK_SET)" works when reading'; +$result = $dbh->pg_lo_lseek($handle, 11, SEEK_SET); is ($result, 11, $t); -SKIP: { - if ($pgversion < 90300 or $pglibversion < 90300) { - skip 'Cannot test 64-bit version of largeobject functions unless Postgres is 9.3 or higher', 1; - } - $t='DB handle method "pg_lo_lseek64" works when reading'; - $result = $dbh->pg_lo_lseek($handle, 11, 0); - is ($result, 11, $t); -} +$t='DB handle method "pg_lo_tell" works'; +my $tell_result = $dbh->pg_lo_tell($handle); +is ($tell_result, $result, $t); + +$t='DB handle method "pg_lo_lseek(SEEK_CUR)" forward works when reading'; +$result = $dbh->pg_lo_lseek($handle, 11, SEEK_CUR); +is ($result, 22, $t); $t='DB handle method "pg_lo_tell" works'; -$result = $dbh->pg_lo_tell($handle); -is ($result, 11, $t); +$tell_result = $dbh->pg_lo_tell($handle); +is ($tell_result, $result, $t); -SKIP: { - if ($pgversion < 90300 or $pglibversion < 90300) { - skip 'Cannot test 64-bit version of largeobject functions unless Postgres is 9.3 or higher', 1; - } - $t='DB handle method "pg_lo_tell64" works'; - $result = $dbh->pg_lo_tell64($handle); - is ($result, 11, $t); -} +$t='DB handle method "pg_lo_lseek(SEEK_CUR)" backward works when reading'; +$result = $dbh->pg_lo_lseek($handle, -10, SEEK_CUR); +is ($result, 12, $t); + +$t='DB handle method "pg_lo_tell" works'; +$tell_result = $dbh->pg_lo_tell($handle); +is ($tell_result, $result, $t); + +$t='DB handle method "pg_lo_lseek(SEEK_END)" works when reading'; +$result = $dbh->pg_lo_lseek($handle, -11, SEEK_END); +is ($result, length($buf)-11, $t); + +$t='DB handle method "pg_lo_tell" works'; +$tell_result = $dbh->pg_lo_tell($handle); +is ($tell_result, $result, $t); $t='DB handle method "pg_lo_read" reads back the same data that was written'; -$dbh->pg_lo_lseek($handle, 0, 0); +$dbh->pg_lo_lseek($handle, 0, SEEK_SET); my ($buf2,$data) = ('',''); while ($dbh->pg_lo_read($handle, $data, 513)) { $buf2 .= $data; @@ -1984,7 +1994,7 @@ SKIP: { if ($pglibversion < 80300 or $pgversion < 80300) { - skip ('Postgres version 8.3 or greater needed for pg_lo_truncate tests', 4); + skip ('Postgres version 8.3 or greater needed for pg_lo_truncate tests', 1); } $t='DB handle method "pg_lo_truncate" fails if opened in read mode only'; @@ -1999,25 +2009,52 @@ is ($result, 0, $t); $t='DB handle method "pg_lo_truncate" truncates to expected size'; - $dbh->pg_lo_lseek($handle, 0, 0); + $dbh->pg_lo_lseek($handle, 0, SEEK_SET); ($buf2,$data) = ('',''); while ($dbh->pg_lo_read($handle, $data, 100)) { $buf2 .= $data; } is (length($buf2), 44, $t); + $t='DB handle method "pg_lo_truncate(INT_MAX)" works'; + my $INT_MAX = (1<<31)-1; + $result = $dbh->pg_lo_truncate($handle, $INT_MAX); + is ($result, 0, $t); + + $t='DB handle method "pg_lo_seek(SEEK_END)" after "pg_lo_truncate(INT_MAX)" works'; + $result = $dbh->pg_lo_lseek($handle, 0, SEEK_END); + is ($result, $INT_MAX, $t); + + $t='DB handle method "pg_lo_tell" after "pg_lo_truncate(INT_MAX)" works'; + $result = $dbh->pg_lo_tell($handle); + is ($result, $INT_MAX, $t); + SKIP: { - if ($pgversion < 90300 or $pglibversion < 90300) { - skip 'Cannot test 64-bit version of largeobject functions unless Postgres is 9.3 or higher', 1; + if ($Config{ivsize} < 8 or $pgversion < 90300 or $pglibversion < 90300) { + skip 'Cannot test 64-bit offsets for largeobject functions without 64-bit integers and Postgres 9.3 or higher', 1; } - $t='DB handle method "pg_lo_truncate64" truncates to expected size'; - $dbh->pg_lo_lseek($handle, 0, 0); - $result = $dbh->pg_lo_truncate64($handle, 22); - ($buf2,$data) = ('',''); - while ($dbh->pg_lo_read($handle, $data, 100)) { - $buf2 .= $data; - } - is (length($buf2), 22, $t); + + # large objects are stored in chunks of BLOCKSZ/4 with an + # integer chunk number column. only chunks with data in them + # are stored, so this doesn't actually require 4TiB of space + my $BLOCK_SIZE = $dbh->selectrow_array('show block_size'); + my $LO_MAX = $INT_MAX * $BLOCK_SIZE / 4; + + $t='DB handle method "pg_lo_truncate(LO_MAX) works'; + $result = $dbh->pg_lo_truncate($handle, $LO_MAX); + is ($result, 0, $t); + + $t='DB handle method "pg_lo_seek(SEEK_END)" after "pg_lo_truncate(LO_MAX) works'; + $result = $dbh->pg_lo_lseek($handle, 0, SEEK_END); + is ($result, $LO_MAX, $t); + + $t='DB handle method "pg_lo_tell" after "pg_lo_truncate(LO_MAX)" works'; + $result = $dbh->pg_lo_tell($handle); + is ($result, $LO_MAX, $t); + + $t='DB handle method "pg_lo_lseek(SEEK_END)" to start works'; + $result = $dbh->pg_lo_lseek($handle, -$LO_MAX, SEEK_END); + is ($result, 0, $t); } } @@ -2032,14 +2069,14 @@ SKIP: { - $superuser or skip ('Cannot run largeobject tests unless run as Postgres superuser', 40); + $superuser or skip ('Cannot run largeobject tests unless run as Postgres superuser', 1); SKIP: { eval { require File::Temp; }; - $@ and skip ('Must have File::Temp to test pg_lo_import* and pg_lo_export', 13); + $@ and skip ('Must have File::Temp to test pg_lo_import* and pg_lo_export', 1); $t='DB handle method "pg_lo_import" works'; my ($fh,$filename) = File::Temp::tmpnam(); @@ -2057,10 +2094,10 @@ SKIP: { if ($pglibversion < 80400) { - skip ('Cannot test pg_lo_import_with_oid unless compiled against 8.4 or better server', 5); + skip ('Cannot test pg_lo_import_with_oid unless compiled against 8.4 or better server', 1); } if ($pgversion < 80100) { - skip ('Cannot test pg_lo_import_with_oid against old versions of Postgres', 5); + skip ('Cannot test pg_lo_import_with_oid against old versions of Postgres', 1); } $t='DB handle method "pg_lo_import_with_oid" works with high number'; @@ -2070,7 +2107,7 @@ my $thandle; SKIP: { - skip ('Known bug: pg_log_import_with_oid throws an error. See RT #90448', 3); + skip ('Known bug: pg_log_import_with_oid throws an error. See RT #90448', 1); $thandle = $dbh->pg_lo_import_with_oid($filename, $highnumber); is ($thandle, $highnumber, $t); @@ -2147,21 +2184,10 @@ $t='DB handle method "pg_lo_lseek" fails with AutoCommit on'; eval { - $dbh->pg_lo_lseek($handle, 0, 0); + $dbh->pg_lo_lseek($handle, 0, SEEK_SET); }; like ($@, qr{pg_lo_lseek when AutoCommit is on}, $t); - SKIP: { - if ($pgversion < 90300 or $pglibversion < 90300) { - skip 'Cannot test 64-bit version of largeobject functions unless Postgres is 9.3 or higher', 1; - } - $t='DB handle method "pg_lo_lseek64" fails with AutoCommit on'; - eval { - $dbh->pg_lo_lseek64($handle, 0, 0); - }; - like ($@, qr{pg_lo_lseek64 when AutoCommit is on}, $t); - } - $t='DB handle method "pg_lo_write" fails with AutoCommit on'; $buf = 'tangelo mulberry passionfruit raspberry plantain' x 500; eval { @@ -2181,17 +2207,6 @@ }; like ($@, qr{pg_lo_tell when AutoCommit is on}, $t); - SKIP: { - if ($pgversion < 90300 or $pglibversion < 90300) { - skip 'Cannot test 64-bit version of largeobject functions unless Postgres is 9.3 or higher', 1; - } - $t='DB handle method "pg_lo_tell64" fails with AutoCommit on'; - eval { - $dbh->pg_lo_tell64($handle); - }; - like ($@, qr{pg_lo_tell64 when AutoCommit is on}, $t); - } - $t='DB handle method "pg_lo_unlink" fails with AutoCommit on'; eval { $dbh->pg_lo_unlink($object); @@ -2204,7 +2219,7 @@ eval { require File::Temp; }; - $@ and skip ('Must have File::Temp to test pg_lo_import and pg_lo_export', 17); + $@ and skip ('Must have File::Temp to test pg_lo_import and pg_lo_export', 1); $t='DB handle method "pg_lo_import" works (AutoCommit on)'; my ($fh,$filename) = File::Temp::tmpnam(); @@ -2342,7 +2357,7 @@ $t='DB handle method "pg_notifies" returns correct string length for recycled var'; if ($pgversion < 90000) { - skip ('Cannot test notification payloads on pre-9.0 servers', 4); + skip ('Cannot test notification payloads on pre-9.0 servers', 1); } $dbh->do("LISTEN abc$notify_name"); @@ -2392,7 +2407,7 @@ SKIP: { if ($DBI::VERSION < 1.54) { - skip ('DBI must be at least version 1.54 to test private_attribute_info', 2); + skip ('DBI must be at least version 1.54 to test private_attribute_info', 1); } $t='DB handle method "private_attribute_info" returns at least one record'; @@ -2434,7 +2449,7 @@ SKIP: { if ($pgversion < 80300) { - skip ('Cannot test pg_ping via COPY on pre-8.3 servers', 20); + skip ('Cannot test pg_ping via COPY on pre-8.3 servers', 1); } for my $type (qw/ ping pg_ping /) { @@ -2484,7 +2499,7 @@ SKIP: { - skip 'Cannot safely reopen sockets on Win32', 2 if $^O =~ /Win32/; + skip 'Cannot safely reopen sockets on Win32', 1 if $^O =~ /Win32/; $val = $type eq 'ping' ? 0 : -3; $t=qq{DB handle method "$type" returns $val after a lost network connection (outside transaction)}; @@ -2517,6 +2532,7 @@ is ($dbh->pg_type_info(123), 12, $t); $dbh->{PrintError} = 0; +done_testing(); exit; diff -Nru libdbd-pg-perl-3.15.1/t/03smethod.t libdbd-pg-perl-3.16.0/t/03smethod.t --- libdbd-pg-perl-3.15.1/t/03smethod.t 2021-05-24 14:44:20.000000000 +0000 +++ libdbd-pg-perl-3.16.0/t/03smethod.t 2022-08-08 15:46:10.000000000 +0000 @@ -22,7 +22,7 @@ if (! $dbh) { plan skip_all => 'Connection to database failed, cannot continue testing'; } -plan tests => 150; +plan tests => 152; isnt ($dbh, undef, 'Connect to database for statement handle method testing'); @@ -918,9 +918,26 @@ }; is ($@, q{}, $t); - $t='Statement handle method "last_insert_id" returns correct value for an inheriteda table'; + $t='Statement handle method "last_insert_id" returns correct value for an inherited table'; is ($result, 2, $t); + my $doublename1 = q{dbdpg_test_table""full-o'quotes}; + my $doublename2 = q{dbdpg_test_table"full-o'quotes}; + + $dbh->do("CREATE TABLE $schema.\"$doublename1\" (id SERIAL primary key)"); + $sth = $dbh->prepare("INSERT INTO \"$doublename1\" DEFAULT VALUES"); + $sth->execute(); + + $t='Statement handle method "last_insert_id" works for table name containing double quotes'; + $result = ''; + eval { + $result = $sth->last_insert_id(undef,undef,$doublename2,undef); + }; + is ($@, q{}, $t); + + $t='Statement handle method "last_insert_id" returns correct value for table name containing double quotes'; + is ($result, 1, $t); + } diff -Nru libdbd-pg-perl-3.15.1/t/dbdpg_test_setup.pl libdbd-pg-perl-3.16.0/t/dbdpg_test_setup.pl --- libdbd-pg-perl-3.15.1/t/dbdpg_test_setup.pl 2021-05-31 14:52:48.000000000 +0000 +++ libdbd-pg-perl-3.16.0/t/dbdpg_test_setup.pl 2022-08-08 16:59:54.000000000 +0000 @@ -585,7 +585,7 @@ }; my $err = $@; $su and chdir $olddir; - if ($err or $info !~ /\w/) { + if ($err or $info !~ /\.\.\./) { $@ = "Could not startup new database ($COM) ($err) ($info)"; last GETHANDLE; ## Fail - startup failed }