From 72edb1c64f95bdf30e4116869d240bd1e4f1f0cb Mon Sep 17 00:00:00 2001 From: "Stephen R. van den Berg" <srb@cuci.nl> Date: Tue, 9 Jun 2020 09:11:34 +0200 Subject: [PATCH] pgsql: Release portals that had background-exceptions during bind. --- lib/modules/Sql.pmod/pgsql.pike | 7 ++++--- lib/modules/Sql.pmod/pgsql_util.pmod | 30 ++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/lib/modules/Sql.pmod/pgsql.pike b/lib/modules/Sql.pmod/pgsql.pike index 0d8e47352d..602fb09b42 100644 --- a/lib/modules/Sql.pmod/pgsql.pike +++ b/lib/modules/Sql.pmod/pgsql.pike @@ -997,9 +997,10 @@ private void startquery(int forcetext, .pgsql_util.sql_result portal, string q, mixed e = catch(portal->_preparebind(tp.datatypeoid)); if (!this) // Already destructed? throw(e); - if (e && !portal.delayederror) { - portal._unnamedstatementkey = 0; // Release early, release often - throw(e); + if (e) { + portal->_purgeportal(); + if (!portal.delayederror) + throw(e); } } if (!proxy.unnamedstatement) diff --git a/lib/modules/Sql.pmod/pgsql_util.pmod b/lib/modules/Sql.pmod/pgsql_util.pmod index 9bf23ab616..9cede304cf 100644 --- a/lib/modules/Sql.pmod/pgsql_util.pmod +++ b/lib/modules/Sql.pmod/pgsql_util.pmod @@ -1970,6 +1970,26 @@ class proxy { procmessage(); } + private void stasherror(int|object portal, mixed err) { + if (stringp(err)) { + if (!objectp(portal)) + portal = this; + if (!portal->delayederror) + portal->delayederror = err; + } + if (objectp(portal)) + portal->_purgeportal(); + } + + private void tryprepbind(sql_result portal, array dtoid) { + mixed err = catch(portal->_preparebind(dtoid)); + if (err) { + stasherror(portal, err); + if (!stringp(err)) + throw(err); + } + } + private void procmessage() { mixed err; int terminating = 0; @@ -2299,7 +2319,7 @@ class proxy { #endif if (portal._tprepared) portal._tprepared.datatypeoid = a; - Thread.Thread(portal->_preparebind, a); + Thread.Thread(tryprepbind, portal, a); break; } case 'T': { @@ -2629,16 +2649,10 @@ class proxy { terminating = 1; err = 0; } else if (stringp(err)) { - sql_result or; - if (!objectp(or = portal)) - or = this; - if (!or.delayederror) - or.delayederror = err; #ifdef PG_DEBUGMORE showportalstack("THROWN"); #endif - if (objectp(portal)) - portal->_releasesession("ERROR"); + stasherror(portal, err); portal = 0; if (!waitforauthready) continue; // Only continue if authentication did not fail -- GitLab