Hello community, here is the log from the commit of package perl-DBD-Pg for openSUSE:Factory checked in at 2020-06-23 21:02:55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-DBD-Pg (Old) and /work/SRC/openSUSE:Factory/.perl-DBD-Pg.new.2956 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-DBD-Pg" Tue Jun 23 21:02:55 2020 rev:51 rq:815870 version:3.13.0 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-DBD-Pg/perl-DBD-Pg.changes 2020-06-14 18:13:22.806454942 +0200 +++ /work/SRC/openSUSE:Factory/.perl-DBD-Pg.new.2956/perl-DBD-Pg.changes 2020-06-23 21:03:21.749604111 +0200 @@ -1,0 +2,21 @@ +Thu Jun 18 03:07:43 UTC 2020 - Tina Müller <[email protected]> + +- updated to 3.13.0 + see /usr/share/doc/packages/perl-DBD-Pg/Changes + + Version 3.13.0 (released June 17, 2020) + - Redo the "last_result" internals in dbdimp.c, which + fixes a memory leak. + [Greg Sabino Mullane] + (RT ticket #132812) + - Fix regression in Perl length() for returned query results + [Jon Jensen] + (Github issue #72) + - Make $sth->finish() do a little less. Notably, even + after calling finish(), pg_error_field will still work + on the last action performed. + [Greg Sabino Mullane] + - Tweak tests so Windows boxes pass + [Greg Sabino Mullane] + +------------------------------------------------------------------- Old: ---- DBD-Pg-3.12.3.tar.gz New: ---- DBD-Pg-3.13.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-DBD-Pg.spec ++++++ --- /var/tmp/diff_new_pack.NGeqdM/_old 2020-06-23 21:03:22.349606041 +0200 +++ /var/tmp/diff_new_pack.NGeqdM/_new 2020-06-23 21:03:22.349606041 +0200 @@ -17,7 +17,7 @@ Name: perl-DBD-Pg -Version: 3.12.3 +Version: 3.13.0 Release: 0 %define cpan_name DBD-Pg Summary: PostgreSQL database driver for the DBI module @@ -33,6 +33,7 @@ BuildRequires: perl(Test::More) >= 0.88 BuildRequires: perl(version) Requires: perl(DBI) >= 1.614 +Requires: perl(Test::More) >= 0.88 Requires: perl(version) Recommends: perl(Module::Signature) >= 0.50 %{perl_requires} ++++++ DBD-Pg-3.12.3.tar.gz -> DBD-Pg-3.13.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/DBD-Pg-3.12.3/Changes new/DBD-Pg-3.13.0/Changes --- old/DBD-Pg-3.12.3/Changes 2020-06-05 19:15:13.000000000 +0200 +++ new/DBD-Pg-3.13.0/Changes 2020-06-17 17:43:59.000000000 +0200 @@ -2,6 +2,26 @@ RT refers to rt.cpan.org +Version 3.13.0 (released June 17, 2020) + + - Redo the "last_result" internals in dbdimp.c, which + fixes a memory leak. + [Greg Sabino Mullane] + (RT ticket #132812) + + - Fix regression in Perl length() for returned query results + [Jon Jensen] + (Github issue #72) + + - Make $sth->finish() do a little less. Notably, even + after calling finish(), pg_error_field will still work + on the last action performed. + [Greg Sabino Mullane] + + - Tweak tests so Windows boxes pass + [Greg Sabino Mullane] + + Version 3.12.3 (released June 5, 2020) - Prevent DBI from flipping AutoCommit to 'on' after a failed commit @@ -1258,7 +1278,7 @@ Version 2.8.0 (released June 1, 2008) - - Added in payload strings for LISTEN/NOTIFY in 8.4 via $dbh->pg_notifies() + - Added in payload strings for LISTEN/NOTIFY in 9.0 via $dbh->pg_notifies() [Greg Sabino Mullane] - Fixed problem preventing some pg_type bind_arrays from working diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/DBD-Pg-3.12.3/META.yml new/DBD-Pg-3.13.0/META.yml --- old/DBD-Pg-3.12.3/META.yml 2020-06-05 03:46:22.000000000 +0200 +++ new/DBD-Pg-3.13.0/META.yml 2020-06-17 17:35:45.000000000 +0200 @@ -1,6 +1,6 @@ --- #YAML:1.0 name : DBD-Pg -version : 3.12.3 +version : 3.13.0 abstract : DBI PostgreSQL interface author: - Greg Sabino Mullane <[email protected]> @@ -30,10 +30,10 @@ provides: DBD::Pg: file : Pg.pm - version : 3.12.3 + version : 3.13.0 Bundle::DBD::Pg: file : lib/Bundle/DBD/Pg.pm - version : 3.12.3 + version : 3.13.0 keywords: - Postgres diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/DBD-Pg-3.12.3/Makefile.PL new/DBD-Pg-3.13.0/Makefile.PL --- old/DBD-Pg-3.12.3/Makefile.PL 2020-06-05 03:46:26.000000000 +0200 +++ new/DBD-Pg-3.13.0/Makefile.PL 2020-06-17 17:35:51.000000000 +0200 @@ -5,7 +5,7 @@ use 5.008001; ## No version.pm for this one, as the prereqs are not loaded yet. -my $VERSION = '3.12.3'; +my $VERSION = '3.13.0'; ## App::Info is stored inside t/lib ## Create a proper path so we can use it below diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/DBD-Pg-3.12.3/Pg.pm new/DBD-Pg-3.13.0/Pg.pm --- old/DBD-Pg-3.12.3/Pg.pm 2020-06-05 03:46:12.000000000 +0200 +++ new/DBD-Pg-3.13.0/Pg.pm 2020-06-17 17:35:41.000000000 +0200 @@ -16,7 +16,7 @@ { package DBD::Pg; - use version; our $VERSION = qv('3.12.3'); + use version; our $VERSION = qv('3.13.0'); use DBI (); use DynaLoader (); @@ -1688,7 +1688,7 @@ =head1 VERSION -This documents version 3.12.3 of the DBD::Pg module +This documents version 3.13.0 of the DBD::Pg module =head1 DESCRIPTION @@ -2760,7 +2760,7 @@ The C<ping> 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.12.3'>. It returns 0 (false) if the connection is not valid, +B<'DBD::Pg ping test v3.13.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: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/DBD-Pg-3.12.3/README new/DBD-Pg-3.13.0/README --- old/DBD-Pg-3.12.3/README 2020-06-05 03:45:56.000000000 +0200 +++ new/DBD-Pg-3.13.0/README 2020-06-17 17:35:37.000000000 +0200 @@ -1,3 +1,4 @@ + DBD::Pg is Copyright (C) 1994-2020, Greg Sabino Mullane DBD::Pg -- the DBI PostgreSQL interface for Perl @@ -5,7 +6,7 @@ DESCRIPTION: ------------ -This is version 3.12.3 of DBD::Pg, the Perl interface to Postgres using DBI. +This is version 3.13.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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/DBD-Pg-3.12.3/SIGNATURE new/DBD-Pg-3.13.0/SIGNATURE --- old/DBD-Pg-3.12.3/SIGNATURE 2020-06-05 19:55:56.000000000 +0200 +++ new/DBD-Pg-3.13.0/SIGNATURE 2020-06-17 17:44:56.000000000 +0200 @@ -17,39 +17,39 @@ SHA256 e4c6f4cdc9560a09492f196fc9a180867fab12742d7d05052d9842b395c6a9eb .dir-locals.el SHA256 4c92448e25229b74a54f864675f34376e8464727ad5cb82ac312d5db7f68605c .perlcriticrc SHA256 e8d3a038d88fb019bb96983f0c52125f86a4c3465466a20612bf4958ace70ed5 CONTRIBUTING.md -SHA256 825fd8eea6498d477597af7d2ff5f9198ddcedbb1c38919d309e107ce1723217 Changes +SHA256 50129e0ff87a6c4c95b1778fdbc30ce0b4f7d67c9a9b6f316096b05c20688559 Changes SHA256 d52a34724b2e3c40ffa2b3b378b574b9e3db27bc3132c88e0be3675f93f378a5 LICENSES/artistic.txt SHA256 ab15fd526bd8dd18a9e77ebc139656bf4d33e97fc7238cd11bf60e2b9b8666c6 LICENSES/gpl-2.0.txt SHA256 e15fb8180cca35de2c3de6854e5cf23152a7733dfa89640825ae13f6f83b0e72 MANIFEST SHA256 d5def2a47197a203318a580bed42169dca47516c6d91d3880317a3043af07f9b MANIFEST.SKIP -SHA256 4ac1e4f243aa3d4479f0ef8633b59f4e45c34ae7afc1d58ab09786e0629afe3c META.yml -SHA256 edc7a2eb5c07fa63d51f969fcd6eb875ceb4800596f93de0019f84d7fb8423ca Makefile.PL +SHA256 2ccd3468d310a9f5c269b8b8801ea0d6fb461c65e78d8f1ce0340ff73a6976a6 META.yml +SHA256 26b2f1942ac67c8f4d89b3c4680ab806eb57b27efea1217894ae47b3f8ef3e6c Makefile.PL SHA256 d7d68c574b9469375f92aaf0bfd0e539f635a45da869f91390fdc401b1ccaefb Pg.h -SHA256 3e90f76416eb0df1932ca6635fb7cb5ac46e7a36c4beed2a4251876d68e264ee Pg.pm +SHA256 912590d04ec1fac14d6ba8d1470042debf9e37272e20f00b68d22e2ce3f4e577 Pg.pm SHA256 4612dd9d174645987df03a87e0d3428e9f06f645ec6355939b15dcb3c77fea63 Pg.xs -SHA256 f8e9a155f8d84cb783614e39bc7d661356e6f6bf399a12c38cc6cd87852a049b README +SHA256 0288efbefb23e95b7b8c5fcd3d32a446c706a08a0a57586e1c495f18843d50f8 README SHA256 de3bff4d51a68d250f37440e73c0e5046ba1afcf25cbf248b6bd106d5455e728 README.dev SHA256 a1d224603fe3a343ba0a0f40086065c81d57fbebc734b5382b0d359da16bdd94 README.win32 SHA256 ce798149ee5bf517fb76d6a652c3e4619bfda6ed706df068f2d0fd1f05ed259c TODO -SHA256 131e15b9a9d077b23cb289cdb941b8d5e0ccb43a2777cf40824234bd9c00477d dbdimp.c -SHA256 477e40202cc74bf3574359666b322b384a62da77051dc0043665186cf760ae3f dbdimp.h +SHA256 2b79d430a29a5d49d3d58d461917ac1b77d3375448e4e5f0fae5b04440412d7a dbdimp.c +SHA256 fbc6f3b524f43902670a467ed85e10e49fc2d53228b7a6d0073cc69c6f67ab46 dbdimp.h SHA256 9e53f7f41aaaf1b540e2784756ef6f16f61b63df0d9956483aded3c49b6e0f48 dbivport.h -SHA256 9dd177798437b0111dd9d813ca09a3665274f67d22e091c6f1bf14f1a8383347 lib/Bundle/DBD/Pg.pm +SHA256 bdbbb77c28bd70681ff243b9c3a52ee3886f3d033fb85209797c3099a0cb9187 lib/Bundle/DBD/Pg.pm SHA256 c945a57d774dc5bb789f2af67892c749f8c4d42b75967c9aab4bc436ed635a90 quote.c SHA256 1ee43f02036bbb68c151903c2718c483ed223aff6cc93fb1408a9158adad9136 quote.h SHA256 49950c2c882018916ef89b59a1707b732064eb3bb6acb6a350111e1dc81000b8 t/00_signature.t SHA256 c24d7dff9bc9d93ddb69b2de7c7137d0e5dfa32f2f77d8f73554d85620373005 t/00basic.t SHA256 a2328a9b98b5c53a82703ce1ca573e00161733cc7fdb517b73ef7f31ed4e2c02 t/01connect.t SHA256 f951d8057ddab944964529a4e5a586b2fd8d75b44d865865bf5a68d042b7ce27 t/01constants.t -SHA256 68e9b2f4e7905a43516fe2e719f4de4f13327a2157b12dd24ce0372d7a885c23 t/02attribs.t -SHA256 fee2b39e9d3ed7e164bd2489c872dd2f3855bd931a500c6d8f9a393f944ce9ae t/03dbmethod.t -SHA256 717a453088e5755dbfcd7fc895c80b692e187d7e95c22b8ac62719908804725a t/03smethod.t +SHA256 24199a3cb1769708a5dc044742720b7d9cf732455bbd756d7b302165e462cb7a t/02attribs.t +SHA256 d89c84f036a355187aa1019fdb3f3351ec60fa2ec168e40414434051b518199f t/03dbmethod.t +SHA256 f4419203cbe74574354384e5d6366fca94d9a84e4972ee552e2b0e512fae40e5 t/03smethod.t SHA256 9ddbdab7db536fa94376a602edbbf076c872d57bab3596ebf685c678739e4c6b t/04misc.t SHA256 be40368efe0cf7232c428fcbecee54acef88c5d5c6e27a146371ed1f854f3674 t/06bytea.t SHA256 7e583fe6aedf5632a489048c35df35bc97463ae2b06e700be6790184a3e86295 t/07copy.t SHA256 3743261fef1e22b9596ddebb8b89a77e1e1f20f7bc11d1bc972e3497b6955766 t/08async.t -SHA256 46fdb11c225980f3d3014817d76998f931ce573e942cd3b4199ee9fb4608d5d5 t/09arrays.t -SHA256 b367ea4db95c4823b9cdecdb15451f11f24d3ba18c6a44d90dc7cc1e8e180551 t/10_pg_error_field.t +SHA256 b256a91cb02aebbc1861981bab505efdbf50511ac4221e9b8b635b7beac58d18 t/09arrays.t +SHA256 ec0b791376009ce051b23e67f561b1e970b39590a08597ab911fc9c58f6c79ac t/10_pg_error_field.t SHA256 f334807ff27f884a628b2d50278c523691bc539b7b46e966f6d41cfd2befb8f1 t/12placeholders.t SHA256 17a3a92837e3c081b5c1f3dec3bf52ab84b572d0539ead7badb4ab567bbc616d t/20savepoints.t SHA256 7e9c2118d1dc670d5ac350ab89e5f36510399699494af5874fb8716bc4bd4cd5 t/30unicode.t @@ -69,7 +69,7 @@ SHA256 4628f92764bdb3e2b04bda7f30fc497231fbbf80dfd24cc09ee3df2e6d6d4387 win32.mak -----BEGIN PGP SIGNATURE----- -iF0EAREDAB0WIQQlKd9quPeUB+lERbS8m5BnFJZKyAUCXtqHLAAKCRC8m5BnFJZK -yJE3AKDjEKDUzIA+zI+m/7z+B7yKCQ8U+gCglLLXY5CM6FM90mLBBIdSXNiuEsQ= -=6jY5 +iF0EAREDAB0WIQQlKd9quPeUB+lERbS8m5BnFJZKyAUCXuo6eAAKCRC8m5BnFJZK +yChmAKDZ4nOD5WIp2XE7Hx7ZMwgt1P6zCgCgwUu61zBPfFERtK50C8JAvIy24r8= +=PT7L -----END PGP SIGNATURE----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/DBD-Pg-3.12.3/dbdimp.c new/DBD-Pg-3.13.0/dbdimp.c --- old/DBD-Pg-3.12.3/dbdimp.c 2020-06-05 04:19:45.000000000 +0200 +++ new/DBD-Pg-3.13.0/dbdimp.c 2020-06-17 17:35:08.000000000 +0200 @@ -17,6 +17,8 @@ #define atoll(X) _atoi64(X) #endif +#define DEBUG_LAST_RESULT 0 + #define sword signed int #define sb2 signed short #define ub2 unsigned short @@ -238,7 +240,7 @@ imp_dbh->pg_enable_utf8 = -1; - imp_dbh->prepare_now = DBDPG_FALSE; + imp_dbh->prepare_now = DBDPG_FALSE; imp_dbh->done_begin = DBDPG_FALSE; imp_dbh->dollaronly = DBDPG_FALSE; imp_dbh->nocolons = DBDPG_FALSE; @@ -254,8 +256,8 @@ imp_dbh->pg_errorlevel = 1; /* Default */ imp_dbh->async_status = 0; imp_dbh->async_sth = NULL; - imp_dbh->last_result = NULL; /* NULL or the last PGresult returned by something */ - imp_dbh->sth_result_owner = 0; + imp_dbh->last_result = NULL; /* NULL or the last PGresult returned by a database or statement handle */ + imp_dbh->result_clearable = DBDPG_TRUE; /* Tell DBI that we should call destroy when the handle dies */ DBIc_IMPSET_on(imp_dbh); @@ -367,16 +369,19 @@ if (TSQL) TRC(DBILOGFP, "%s;\n\n", sql); - /* If we are clear to free the last result, do so now in anticipation of replacement below */ - if (0 == imp_dbh->sth_result_owner && NULL != imp_dbh->last_result) { + /* Free the last_result as needed, as we are about to replace it */ + if (imp_dbh->last_result && imp_dbh->result_clearable) { TRACE_PQCLEAR; +#if DEBUG_LAST_RESULT + fprintf(stderr, "CLEAR last_result of %ld at line %d of %s\n", (long int)imp_dbh->last_result,__LINE__,__func__); +#endif PQclear(imp_dbh->last_result); imp_dbh->last_result = NULL; } TRACE_PQEXEC; imp_dbh->last_result = PQexec(imp_dbh->conn, sql); - imp_dbh->sth_result_owner = 0; + imp_dbh->result_clearable = DBDPG_TRUE; status = _sqlstate(aTHX_ imp_dbh, imp_dbh->last_result); if (TEND_slow) TRC(DBILOGFP, "%sEnd _result\n", THEADER_slow); @@ -494,7 +499,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.12.3 */"); + result = PQexec(imp_dbh->conn, "/* DBD::Pg ping test v3.13.0 */"); status = PQresultStatus(result); PQclear(result); if (PGRES_FATAL_ERROR == status) { @@ -681,7 +686,7 @@ (void)dbd_db_disconnect(dbh, imp_dbh); if (NULL != imp_dbh->async_sth) { /* Just in case */ - if (NULL != imp_dbh->async_sth->result) { + if (imp_dbh->async_sth->result) { TRACE_PQCLEAR; PQclear(imp_dbh->async_sth->result); imp_dbh->async_sth->result = NULL; @@ -689,9 +694,12 @@ imp_dbh->async_sth = NULL; } - /* Free the last result if needed, and nobody has claimed ownership */ - if (0 == imp_dbh->sth_result_owner && NULL != imp_dbh->last_result) { + /* Free the last_result as needed */ + if (imp_dbh->last_result && imp_dbh->result_clearable) { TRACE_PQCLEAR; +#if DEBUG_LAST_RESULT + fprintf(stderr, "CLEAR last_result of %ld at line %d of %s\n", (long int)imp_dbh->last_result,__LINE__,__func__); +#endif PQclear(imp_dbh->last_result); imp_dbh->last_result = NULL; } @@ -2298,7 +2306,6 @@ seg_t * currseg; ph_t * currph; long power_of_ten; - bool same_result; if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_st_prepare_statement\n", THEADER_slow); @@ -2362,24 +2369,31 @@ if (TSQL) TRC(DBILOGFP, "PREPARE %s AS %s;\n\n", imp_sth->prepare_name, statement); - /* If the last result is unclaimed, or if it belongs to us, free as needed */ - same_result = imp_dbh->last_result == imp_sth->result ? 1 : 0; - if ((0 == imp_dbh->sth_result_owner || (long int)imp_sth == imp_dbh->sth_result_owner) - && NULL != imp_dbh->last_result) { + /* Free the last_result as needed, even if happens to be owned by us */ + if (imp_dbh->last_result && imp_dbh->result_clearable) { TRACE_PQCLEAR; +#if DEBUG_LAST_RESULT + fprintf(stderr, "CLEAR last_result of %ld at line %d of %s\n", (long int)imp_dbh->last_result,__LINE__,__func__); +#endif PQclear(imp_dbh->last_result); imp_dbh->last_result = NULL; } - /* If the above wasn't our result, free that too */ - if (!same_result && NULL != imp_sth->result) { + if (imp_sth->result) { + TRACE_PQCLEAR; +#if DEBUG_LAST_RESULT + fprintf(stderr, "CLEAR sth->result of %ld at line %d of %s\n", (long int)imp_sth->result,__LINE__,__func__); +#endif PQclear(imp_sth->result); imp_sth->result = NULL; } TRACE_PQPREPARE; - imp_dbh->last_result = imp_sth->result = PQprepare(imp_dbh->conn, imp_sth->prepare_name, statement, params, imp_sth->PQoids); - imp_dbh->sth_result_owner = (long int)imp_sth; + imp_dbh->last_result = imp_sth->result + = PQprepare( + imp_dbh->conn, imp_sth->prepare_name, statement, params, imp_sth->PQoids + ); + imp_dbh->result_clearable = DBDPG_FALSE; status = _sqlstate(aTHX_ imp_dbh, imp_sth->result); if (TRACE6_slow) TRC(DBILOGFP, "%sUsing PQprepare: %s\n", THEADER_slow, statement); @@ -3076,15 +3090,20 @@ if (TSQL) TRC(DBILOGFP, "%s;\n\n", sql); - /* Free the last result if needed, and nobody has claimed ownership */ - if (0 == imp_dbh->sth_result_owner && NULL != imp_dbh->last_result) { + + /* Free the last_result as needed, as we are about to replace it */ + if (imp_dbh->last_result && imp_dbh->result_clearable) { TRACE_PQCLEAR; +#if DEBUG_LAST_RESULT + fprintf(stderr, "CLEAR last_result of %ld at line %d of %s\n", (long int)imp_dbh->last_result,__LINE__,__func__); +#endif PQclear(imp_dbh->last_result); imp_dbh->last_result = NULL; } + TRACE_PQEXEC; imp_dbh->last_result = PQexec(imp_dbh->conn, sql); - imp_dbh->sth_result_owner = 0; + imp_dbh->result_clearable = DBDPG_TRUE; status = _sqlstate(aTHX_ imp_dbh, imp_dbh->last_result); imp_dbh->copystate = 0; /* Assume not in copy mode until told otherwise */ @@ -3180,7 +3199,6 @@ long ret = -2; PQExecType pqtype = PQTYPE_UNKNOWN; long power_of_ten; - bool same_result; if (TSTART_slow) TRC(DBILOGFP, "%sBegin dbd_st_execute\n", THEADER_slow); @@ -3398,24 +3416,28 @@ } else { - /* If the last result is unclaimed, or if it belongs to us, free as needed */ - same_result = imp_dbh->last_result == imp_sth->result ? 1 : 0; - if ((0 == imp_dbh->sth_result_owner || (long int)imp_sth == imp_dbh->sth_result_owner) - && NULL != imp_dbh->last_result) { + /* Free the last_result as needed, even if happens to be owned by us */ + if (imp_dbh->last_result && imp_dbh->result_clearable) { TRACE_PQCLEAR; +#if DEBUG_LAST_RESULT + fprintf(stderr, "CLEAR last_result of %ld at line %d of %s\n", (long int)imp_dbh->last_result,__LINE__,__func__); +#endif PQclear(imp_dbh->last_result); imp_dbh->last_result = NULL; } - /* If the above wasn't our result, free that too */ - if (!same_result && NULL != imp_sth->result) { + if (imp_sth->result) { TRACE_PQCLEAR; +#if DEBUG_LAST_RESULT + fprintf(stderr, "CLEAR sth->result of %ld at line %d of %s\n", (long int)imp_sth->result,__LINE__,__func__); +#endif PQclear(imp_sth->result); imp_sth->result = NULL; } TRACE_PQEXEC; - imp_dbh->last_result = imp_sth->result = PQexec(imp_dbh->conn, statement); - imp_dbh->sth_result_owner = (long int)imp_sth; + imp_dbh->last_result = imp_sth->result + = PQexec(imp_dbh->conn, statement); + imp_dbh->result_clearable = DBDPG_FALSE; } Safefree(statement); @@ -3492,26 +3514,31 @@ } else { - /* If the last result is unclaimed, or if it belongs to us, free as needed */ - same_result = imp_dbh->last_result == imp_sth->result ? 1 : 0; - if ((0 == imp_dbh->sth_result_owner || (long int)imp_sth == imp_dbh->sth_result_owner) - && NULL != imp_dbh->last_result) { + /* Free the last_result as needed, even if happens to be owned by us */ + if (imp_dbh->last_result && imp_dbh->result_clearable) { TRACE_PQCLEAR; +#if DEBUG_LAST_RESULT + fprintf(stderr, "CLEAR last_result of %ld at line %d of %s\n", (long int)imp_dbh->last_result,__LINE__,__func__); +#endif PQclear(imp_dbh->last_result); imp_dbh->last_result = NULL; } - /* If the above wasn't our result, free that too */ - if (!same_result && NULL != imp_sth->result) { + if (imp_sth->result) { TRACE_PQCLEAR; +#if DEBUG_LAST_RESULT + fprintf(stderr, "CLEAR sth->result of %ld at line %d of %s\n", (long int)imp_sth->result,__LINE__,__func__); +#endif PQclear(imp_sth->result); imp_sth->result = NULL; } TRACE_PQEXECPARAMS; - imp_dbh->last_result = imp_sth->result = PQexecParams - (imp_dbh->conn, statement, imp_sth->numphs, - imp_sth->PQoids, imp_sth->PQvals, imp_sth->PQlens, imp_sth->PQfmts, 0); - imp_dbh->sth_result_owner = (long int)imp_sth; + imp_dbh->last_result = imp_sth->result + = PQexecParams( + imp_dbh->conn, statement, imp_sth->numphs, + imp_sth->PQoids, imp_sth->PQvals, imp_sth->PQlens, imp_sth->PQfmts, 0 + ); + imp_dbh->result_clearable = DBDPG_FALSE; } Safefree(statement); @@ -3569,26 +3596,31 @@ } else { - /* If the last result is unclaimed, or if it belongs to us, free as needed */ - same_result = imp_dbh->last_result == imp_sth->result ? 1 : 0; - if ((0 == imp_dbh->sth_result_owner || (long int)imp_sth == imp_dbh->sth_result_owner) - && NULL != imp_dbh->last_result) { + /* Free the last_result as needed, even if happens to be owned by us */ + if (imp_dbh->last_result && imp_dbh->result_clearable) { TRACE_PQCLEAR; +#if DEBUG_LAST_RESULT + fprintf(stderr, "CLEAR last_result of %ld at line %d of %s\n", (long int)imp_dbh->last_result,__LINE__,__func__); +#endif PQclear(imp_dbh->last_result); imp_dbh->last_result = NULL; } - /* If the above wasn't our result, free that too */ - if (!same_result && NULL != imp_sth->result) { + if (imp_sth->result) { TRACE_PQCLEAR; +#if DEBUG_LAST_RESULT + fprintf(stderr, "CLEAR sth->result of %ld at line %d of %s\n", (long int)imp_sth->result,__LINE__,__func__); +#endif PQclear(imp_sth->result); imp_sth->result = NULL; } TRACE_PQEXECPREPARED; - imp_dbh->last_result = imp_sth->result = PQexecPrepared - (imp_dbh->conn, imp_sth->prepare_name, imp_sth->numphs, - imp_sth->PQvals, imp_sth->PQlens, imp_sth->PQfmts, 0); - imp_dbh->sth_result_owner = (long int)imp_sth; + imp_dbh->last_result = imp_sth->result + = PQexecPrepared( + imp_dbh->conn, imp_sth->prepare_name, imp_sth->numphs, + imp_sth->PQvals, imp_sth->PQlens, imp_sth->PQfmts, 0 + ); + imp_dbh->result_clearable = DBDPG_FALSE; } } /* end new-style prepare */ @@ -3628,7 +3660,7 @@ if (TRACE5_slow) TRC(DBILOGFP, "%sStatus was PGRES_COMMAND_OK\n", THEADER_slow); - if (NULL != imp_sth->result) { + if (imp_sth->result) { TRACE_PQCMDSTATUS; cmdStatus = PQcmdStatus(imp_sth->result); if (0 == strncmp(cmdStatus, "INSERT", 6)) { @@ -3827,6 +3859,7 @@ */ else if (!SvROK(sv)) { SvUTF8_on(sv); + SvSETMAGIC(sv); } } } @@ -3893,20 +3926,6 @@ if (TSTART_slow) TRC(DBILOGFP, "%sBegin dbdpg_finish (async: %d)\n", THEADER_slow, imp_dbh->async_status); - if (DBIc_ACTIVE(imp_sth) && imp_sth->result) { - /* If ours is the current 'last_result', let imp_dbh know that it can clear this when it needs to */ - if (imp_dbh->sth_result_owner == (long int)imp_sth) { - imp_dbh->sth_result_owner = 0; - } - else { - /* Ours it not the latest, so fine to clear it right here and now */ - TRACE_PQCLEAR; - PQclear(imp_sth->result); - } - imp_sth->result = NULL; - imp_sth->rows = 0; - } - /* Are we in the middle of an async for this statement handle? */ if (imp_dbh->async_status) { if (imp_sth->async_status) { @@ -4064,14 +4083,28 @@ Safefree(imp_sth->PQfmts); Safefree(imp_sth->PQoids); - /* We do not actually clear this as imp_dbh may need it (e.g. for pg_error_field) */ - imp_sth->result = NULL; - - /* Tell everyone it is okay to recycle last_result if it belongs to us */ - if ( (long int)imp_sth == imp_dbh->sth_result_owner ) { - imp_dbh->sth_result_owner = 0; + /* + If our result is the same as the last_result, we will not free it, but will + cede control over it so that the parent dbh can clear it later. + We do this in case $dbh->pg_error_field() is called + */ + if (imp_sth->result == imp_dbh->last_result) { + imp_dbh->result_clearable = DBDPG_TRUE; + } + else { + if (imp_sth->result) { + /* Nobody else is using this PGresult, so we can clear it */ + TRACE_PQCLEAR; +#if DEBUG_LAST_RESULT + fprintf(stderr, "CLEAR sth->result of %ld at line %d of %s\n", (long int)imp_sth->result,__LINE__,__func__); +#endif + PQclear(imp_sth->result); + } } + /* Regardless of the above, we want to not use this anymore */ + imp_sth->result = NULL; + /* Free all the segments */ currseg = imp_sth->seg; while (NULL != currseg) { @@ -4387,7 +4420,7 @@ int fieldcode = 0; char * startstring = fieldname; - if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_error_field\n", THEADER_slow); + if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_error_field (fieldname=%s)\n", THEADER_slow, fieldname); while (*fieldname) { if (*fieldname >= 'a' && *fieldname <= 'z') @@ -5157,7 +5190,6 @@ ExecStatusType status = PGRES_FATAL_ERROR; long rows = 0; char *cmdStatus = NULL; - bool same_result; if (TSTART_slow) TRC(DBILOGFP, "%sBegin pg_db_result\n", THEADER_slow); @@ -5229,23 +5261,27 @@ } if (NULL != imp_dbh->async_sth) { - same_result = imp_dbh->last_result == imp_dbh->async_sth->result ? 1 : 0; - /* If the last result is unclaimed, or if it belongs to the async handle, free as needed */ - if ((0 == imp_dbh->sth_result_owner || (long int)imp_dbh->async_sth == imp_dbh->sth_result_owner) - && NULL != imp_dbh->last_result) { + /* Free the last_result as needed */ + if (imp_dbh->last_result && imp_dbh->result_clearable) { TRACE_PQCLEAR; +#if DEBUG_LAST_RESULT + fprintf(stderr, "CLEAR last_result of %ld at line %d of %s\n", (long int)imp_dbh->last_result,__LINE__,__func__); +#endif PQclear(imp_dbh->last_result); imp_dbh->last_result = NULL; } /* If the above wasn't the async handle's result, free that too */ - if (!same_result && NULL != imp_dbh->async_sth->result) { + if (imp_dbh->async_sth->result) { TRACE_PQCLEAR; +#if DEBUG_LAST_RESULT + fprintf(stderr, "CLEAR imp_dbh->async_sth->result of %ld at line %d of %s\n", (long int)imp_dbh->async_sth->result,__LINE__,__func__); +#endif PQclear(imp_dbh->async_sth->result); imp_dbh->async_sth->result = NULL; } imp_dbh->last_result = imp_dbh->async_sth->result = result; - imp_dbh->sth_result_owner = (long int)imp_dbh->async_sth; + imp_dbh->result_clearable = DBDPG_FALSE; } else { TRACE_PQCLEAR; @@ -5595,6 +5631,7 @@ int fields = PQnfields(imp_sth->result); AV* result_av = newAV(); av_extend(result_av, fields); + while(fields--){ TRACE_PQFTABLE; int oid = PQftable(imp_sth->result, fields); @@ -5614,18 +5651,12 @@ if (PGRES_TUPLES_OK == status) { TRACE_PQNTUPLES; if (PQntuples(result)!=0) { - TRACE_PQGETLENGTH; int len = PQgetlength(result, 0, 0) + 1; - TRACE_PQGETLENGTH; len += PQgetlength(result, 0, 1) + 1; - TRACE_PQGETLENGTH; len += PQgetlength(result, 0, 2); SV* table_name = newSV(len); - TRACE_PQGETVALUE; char *nsp = PQgetvalue(result, 0, 0); - TRACE_PQGETVALUE; char *tbl = PQgetvalue(result, 0, 1); - TRACE_PQGETVALUE; char *col = PQgetvalue(result, 0, 2); sv_setpvf(table_name, "%s.%s.%s", nsp, tbl, col); if (imp_dbh->pg_utf8_flag) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/DBD-Pg-3.12.3/dbdimp.h new/DBD-Pg-3.13.0/dbdimp.h --- old/DBD-Pg-3.12.3/dbdimp.h 2020-05-27 22:00:25.000000000 +0200 +++ new/DBD-Pg-3.13.0/dbdimp.h 2020-06-17 16:37:06.000000000 +0200 @@ -47,7 +47,7 @@ bool client_encoding_utf8; /* is the client_encoding utf8 last we checked? */ PGresult *last_result; /* PGresult structure from the last executed query (can be from imp_dbh or imp_sth) */ - long sth_result_owner; /* Unique address of the sth that created it the above */ + bool result_clearable; /* Is it alright to call PQclear on last_result? (statements handles set it to false */ imp_sth_t *do_tmp_sth; /* temporary sth to refer inside a do() call */ }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/DBD-Pg-3.12.3/lib/Bundle/DBD/Pg.pm new/DBD-Pg-3.13.0/lib/Bundle/DBD/Pg.pm --- old/DBD-Pg-3.12.3/lib/Bundle/DBD/Pg.pm 2020-06-05 03:45:46.000000000 +0200 +++ new/DBD-Pg-3.13.0/lib/Bundle/DBD/Pg.pm 2020-06-17 17:35:23.000000000 +0200 @@ -5,7 +5,7 @@ use warnings; use 5.008001; -our $VERSION = '3.12.3'; +our $VERSION = '3.13.0'; 1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/DBD-Pg-3.12.3/t/02attribs.t new/DBD-Pg-3.13.0/t/02attribs.t --- old/DBD-Pg-3.12.3/t/02attribs.t 2020-05-18 14:39:17.000000000 +0200 +++ new/DBD-Pg-3.13.0/t/02attribs.t 2020-06-17 16:37:06.000000000 +0200 @@ -18,7 +18,7 @@ if (! $dbh) { plan skip_all => 'Connection to database failed, cannot continue testing'; } -plan tests => 273; +plan tests => 284; isnt ($dbh, undef, 'Connect to database for handle attributes testing'); @@ -526,7 +526,17 @@ $t='Statement handle attribute "NAME" works correctly for SELECT statements'; my $colnames = ['Sheep', 'id']; -is_deeply ($sth->{'NAME'}, $colnames, $t); +my $actual = $sth->{'NAME'}; +is_deeply ($actual, $colnames, $t); + +$t='Statement handle attribute "NAME" returns correct string lengths'; +is (length($actual->[0]), 5, $t); +is (length($actual->[1]), 2, $t); +my $expected_length = 5; +for my $x (@$actual) { + is (length($x), $expected_length, $t); + $expected_length -= 3; +} $t='Statement handle attribute "NAME_lc" works correctly for SELECT statements'; $colnames = ['sheep', 'id']; @@ -574,8 +584,9 @@ $t='Statement handle attribute "NUM_OF_FIELDS" works correctly after finish'; is ($sth->{'NUM_OF_FIELDS'}, 2, $t); -$t='Statement handle attribute "NAME" returns undef after finish'; -is_deeply ($sth->{'NAME'}, undef, $t); +$t='Statement handle attribute "NAME" returns values after finish'; +$colnames = ['Sheep', 'id']; +is_deeply ($sth->{'NAME'}, $colnames, $t); $t='Statement handle attribute "NAME_lc" returns values after finish'; $colnames = ['sheep', 'id']; @@ -597,17 +608,21 @@ $colnames = {'SHEEP' => 0, ID => 1}; is_deeply ($sth->{'NAME_uc_hash'}, $colnames, $t); -$t='Statement handle attribute "TYPE" returns undef after finish'; -is_deeply ($sth->{'TYPE'}, undef, $t); +$t='Statement handle attribute "TYPE" works correctly after finish'; +$colnames = [4, 6]; +is_deeply ($sth->{'TYPE'}, $colnames, $t); $t='Statement handle attribute "PRECISION" works correctly after finish'; -is_deeply ($sth->{'PRECISION'}, undef, $t); +$colnames = [4, 8]; +is_deeply ($sth->{'PRECISION'}, $colnames, $t); $t='Statement handle attribute "SCALE" works correctly after finish'; -is_deeply ($sth->{'SCALE'}, undef, $t); +$colnames = [undef,undef]; +is_deeply ($sth->{'SCALE'}, $colnames, $t); $t='Statement handle attribute "NULLABLE" works correctly after finish'; -is_deeply ($sth->{NULLABLE}, undef, $t); +$colnames = [2,2]; +is_deeply ($sth->{NULLABLE}, $colnames, $t); ## Test UPDATE queries @@ -619,24 +634,20 @@ $t='Statement handle attribute "NAME" returns empty arrayref for updates'; is_deeply ($sth->{'NAME'}, [], $t); -## These cause assertion errors, may be a DBI bug. -## Commenting out for now until we can examine closer -## Please see: http://www.nntp.perl.org/group/perl.cpan.testers/2008/08/msg2012293.html +$t='Statement handle attribute "NAME_lc" returns empty arrayref for updates'; +is_deeply ($sth->{'NAME_lc'}, [], $t); -#$t='Statement handle attribute "NAME_lc" returns empty arrayref for updates'; -#is_deeply ($sth->{'NAME_lc'}, [], $t); +$t='Statement handle attribute "NAME_uc" returns empty arrayref for updates'; +is_deeply ($sth->{'NAME_uc'}, [], $t); -#$t='Statement handle attribute "NAME_uc" returns empty arrayref for updates'; -#is_deeply ($sth->{'NAME_uc'}, [], $t); +$t='Statement handle attribute "NAME_hash" returns empty hashref for updates'; +is_deeply ($sth->{'NAME_hash'}, {}, $t); -#$t='Statement handle attribute "NAME_hash" returns empty hashref for updates'; -#is_deeply ($sth->{'NAME_hash'}, {}, $t); +$t='Statement handle attribute "NAME_uc_hash" returns empty hashref for updates'; +is_deeply ($sth->{'NAME_lc_hash'}, {}, $t); -#$t='Statement handle attribute "NAME_uc_hash" returns empty hashref for updates'; -#is_deeply ($sth->{'NAME_lc_hash'}, {}, $t); - -#$t='Statement handle attribute "NAME_uc_hash" returns empty hashref for updates'; -#is_deeply ($sth->{'NAME_uc_hash'}, {}, $t); +$t='Statement handle attribute "NAME_uc_hash" returns empty hashref for updates'; +is_deeply ($sth->{'NAME_uc_hash'}, {}, $t); $t='Statement handle attribute "TYPE" returns empty arrayref for updates'; is_deeply ($sth->{'TYPE'}, [], $t); @@ -689,10 +700,10 @@ $t='Statement handle attribute "PRECISION" returns correct info for RETURNING updates'; is_deeply ($sth->{'PRECISION'}, [4,6,1], $t); - $t='Statement handle attribute "SCALE" returns correct info for RETURNING updates'; + $t='Statement handle attribute "SCALE3" returns correct info for RETURNING updates'; is_deeply ($sth->{'SCALE'}, [undef,2,undef], $t); - $t='Statement handle attribute "NULLABLE" returns empty arrayref for updates'; + $t='Statement handle attribute "NULLABLE4" returns correct values for updates'; is_deeply ($sth->{'NULLABLE'}, [0,1,1], $t); $dbh->do('UPDATE dbd_pg_test SET id = 1 WHERE id = 99'); @@ -1294,7 +1305,18 @@ is ($dbh->errstr, 'ERRSTR', $t); is ($dbh->err, '42', $t); $dbh->{HandleSetErr} = 0; + +my $x = $dbh->errstr; +$t='Database handle method "errstr" gives correct string length'; +is (length($x), 6, $t); $dbh->rollback(); +eval { + $dbh->do('SELECT 1/0'); +}; +$x = $dbh->errstr; +ok (length($x) > 6, $t); +$dbh->rollback(); + # # Test of the handle attribute "ErrCount" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/DBD-Pg-3.12.3/t/03dbmethod.t new/DBD-Pg-3.13.0/t/03dbmethod.t --- old/DBD-Pg-3.12.3/t/03dbmethod.t 2020-06-05 04:25:20.000000000 +0200 +++ new/DBD-Pg-3.13.0/t/03dbmethod.t 2020-06-17 16:37:06.000000000 +0200 @@ -25,7 +25,7 @@ if (! $dbh) { plan skip_all => 'Connection to database failed, cannot continue testing'; } -plan tests => 594; +plan tests => 600; isnt ($dbh, undef, 'Connect to database for database handle method testing'); @@ -2081,6 +2081,38 @@ $info = $dbh->pg_notifies; is_deeply ($info, [$notify_name, $pid, ''], $t); +$t='DB handle method "pg_notifies" returns correct string length'; +my $name = $info->[0]; +is (length($name), 17, $t); +$dbh->do("NOTIFY $notify_name"); +$dbh->commit(); +$info = $dbh->pg_notifies; +is (length($info->[0]), 17, $t); + +SKIP: { + $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); + } + + $dbh->do("LISTEN abc$notify_name"); + $dbh->do(qq{NOTIFY abc$notify_name, 'Just some simple payload text'}); + $dbh->commit(); + $info = $dbh->pg_notifies; + $name = $info->[0]; + is (length($name), 17+3, $t); + $name = $info->[2]; + is (length($name), 29, $t); + $dbh->do(qq{NOTIFY abc$notify_name, 'A shorter payload'}); + $dbh->commit(); + $info = $dbh->pg_notifies; + is (length($info->[0]), 17+3, $t); + $name = $info->[2]; + is (length($name), 17, $t); +} + + # # Test of the "getfd" database handle method # diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/DBD-Pg-3.12.3/t/03smethod.t new/DBD-Pg-3.13.0/t/03smethod.t --- old/DBD-Pg-3.12.3/t/03smethod.t 2020-05-18 14:39:17.000000000 +0200 +++ new/DBD-Pg-3.13.0/t/03smethod.t 2020-06-17 16:37:06.000000000 +0200 @@ -21,7 +21,7 @@ if (! $dbh) { plan skip_all => 'Connection to database failed, cannot continue testing'; } -plan tests => 128; +plan tests => 136; isnt ($dbh, undef, 'Connect to database for statement handle method testing'); @@ -747,6 +747,26 @@ undef ], $t); +$t=q{2Statement handle method "pg_canonical_names" returns expected values}; +$sth = $dbh->prepare('SELECT id, id AS not_id, id + 1 AS not_a_simple FROM dbd_pg_test LIMIT 1'); +$sth->execute; + +is_deeply ($sth->pg_canonical_names, [ + 'dbd_pg_testschema.dbd_pg_test.id', + 'dbd_pg_testschema.dbd_pg_test.id', + undef +], $t); + +$t=q{3Statement handle method "pg_canonical_names" returns expected values}; +$sth = $dbh->prepare('SELECT id, id AS not_id, id + 1 AS not_a_simple FROM dbd_pg_test LIMIT 1'); +$sth->execute; + +is_deeply ($sth->pg_canonical_names, [ + 'dbd_pg_testschema.dbd_pg_test.id', + 'dbd_pg_testschema.dbd_pg_test.id', + undef +], $t); + # # Test of the statement handle methods "pg_canonical_ids" # @@ -765,6 +785,32 @@ $sth->finish; +# +# Test for regression reported in GitHub issue #72: +# Perl length() returns the wrong value on array elements returned by fetchrow_arrayref() +# + +{ + $t = q{Statement handle fetched strings give correct length()}; + my @strings = qw( + abcdefghij + abcd + abcdefg + abcdefghijklmno + a + abcdefghijklmnopqrstuvwxyz + ); + $SQL = join(q{ UNION ALL }, ('SELECT ?,?') x @strings) . q{ ORDER BY 1}; + $sth = $dbh->prepare($SQL); + my $i = 0; + $sth->execute(map { $i++, $_ } @strings); + while (my $row = $sth->fetchrow_arrayref) { + is(length($row->[1]), length(shift(@strings)), 'Perl length() of returned string'); + } + $sth->finish; +} + + cleanup_database($dbh,'test'); $dbh->rollback(); $dbh->disconnect(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/DBD-Pg-3.12.3/t/09arrays.t new/DBD-Pg-3.13.0/t/09arrays.t --- old/DBD-Pg-3.12.3/t/09arrays.t 2020-05-18 14:39:17.000000000 +0200 +++ new/DBD-Pg-3.13.0/t/09arrays.t 2020-06-17 16:37:06.000000000 +0200 @@ -18,7 +18,7 @@ if (! $dbh) { plan skip_all => 'Connection to database failed, cannot continue testing'; } -plan tests => 203; +plan tests => 206; isnt ($dbh, undef, 'Connect to database for array testing'); @@ -610,7 +610,6 @@ $sth->finish(); } - ## Quick test of empty arrays my $expected = $pgversion >= 80300 ? [[[]]] : [[undef]]; @@ -622,6 +621,13 @@ $result = $dbh->selectall_arrayref(q{SELECT array(SELECT 'empty'::text WHERE 1=0)::text[]}); is_deeply ($result, $expected, $t); +$t=q{String lengths of returned arrays are correct}; +my @numbers = ('one', 'two', 'three'); +$result = $dbh->selectall_arrayref(q{SELECT array['one','two','three']}); +for my $col (@{$result->[0][0]}) { + is (length($col), length(shift @numbers), $t); +} + SKIP: { my $fancytime; eval { require Time::Piece; $fancytime = Time::Piece->localtime;}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/DBD-Pg-3.12.3/t/10_pg_error_field.t new/DBD-Pg-3.13.0/t/10_pg_error_field.t --- old/DBD-Pg-3.12.3/t/10_pg_error_field.t 2020-05-18 14:39:17.000000000 +0200 +++ new/DBD-Pg-3.13.0/t/10_pg_error_field.t 2020-06-17 16:37:06.000000000 +0200 @@ -83,7 +83,7 @@ my $expected = $error[5==$loop ? 3 : $loop-1]; $expected = undef if $expected eq 'undef'; if (defined $expected) { - $expected = ($expected eq 'number') ? qr/^[0-9]+$/ : qr/$expected/; + $expected = ($expected eq 'number') ? qr/^[0-9]+$/ : qr/$expected/i; } $t = "(query $loop) Calling pg_error_field returns expected value for field $field"; my $actual = $dbh->pg_error_field($field);
