2017-06-27
2017-06-27 10:31:31 by Stephen R. van den Berg <srb@cuci.nl>
-
bd47ec9a824621765aaad2cec98cf59d812011f9
(143 lines)
(+96/-47)
[
Show
| Annotate
]
Branch: 8.0
pgsql: Trim in-flight portal stack aware of transactions in progress.
68:
final int _portalsinflight;
final int _statementsinflight;
final int _wasparallelisable;
+ final int _intransaction;
private .pgsql_util.conxion c;
private string cancelsecret;
641: Inside #if defined(PG_DEBUG)
#ifdef PG_DEBUG
PD("Processloop\n");
+ #ifdef PG_DEBUGMORE
+ void showportalstack(string label) {
+ PD(sprintf(">>>>>>>>>>> Portalstack %s: %O\n", label, portal));
+ foreach(qportals->peek_array();;int|.pgsql_util.sql_result qp)
+ PD(" =========== Portal: %O\n",qp);
+ PD("<<<<<<<<<<<<<< Portalstack end\n");
+ };
+ #endif
void showportal(int msgtype) {
if(objectp(portal))
PD("%d<%O %d %c switch portal\n",
658: Inside #if defined(PG_DEBUG)
datarowdebug=0; datarowdebugcount=0;
}
#endif
+ #ifdef PG_DEBUGMORE
+ showportalstack("LOOPTOP");
+ #endif
if(!sizeof(cr)) { // Preliminary check, fast path
Thread.MutexKey lock=cr->fillreadmux->lock();
if(!sizeof(cr)) { // Check for real
826:
msglen-=4;
#endif
break;
- case 'Z':
+ case 'Z': {
backendstatus=cr->read_int8();
#ifdef PG_DEBUG
msglen-=4+1;
PD("ReadyForQuery %c\n",backendstatus);
#endif
- for(;objectp(portal);portal=qportals->read()) {
+ #ifdef PG_DEBUGMORE
+ showportalstack("READYFORQUERY");
+ #endif
+ int keeplooking;
+ do
+ for(keeplooking = 0; objectp(portal); portal = qportals->read()) {
#ifdef PG_DEBUG
showportal(msgtype);
#endif
-
+ if (backendstatus == 'I' && _intransaction
+ && portal->transtype != TRANSEND)
+ keeplooking = 1;
portal->_purgeportal();
}
-
+ while (keeplooking && (portal = qportals->read()));
+ if (backendstatus == 'I')
+ _intransaction = 0;
foreach(qportals->peek_array();;.pgsql_util.sql_result qp) {
if(objectp(qp) && qp._synctransact && qp._synctransact<=portal) {
PD("Checking portal %O %d<=%d\n",
846:
}
}
portal=0;
+ #ifdef PG_DEBUGMORE
+ showportalstack("AFTER READYFORQUERY");
+ #endif
_readyforquerycount--;
if(readyforquery_cb)
readyforquery_cb(),readyforquery_cb=0;
destruct(waitforauthready);
break;
-
+ }
case '1':
#ifdef PG_DEBUG
- PD("ParseComplete\n");
+ PD("ParseComplete portal %O\n", portal);
msglen-=4;
#endif
break;
944: Inside #if defined(PG_DEBUG)
msglen-=4;
PD("%O BindComplete\n",portal._portalname);
#endif
- if(tp=portal._tprepared) {
- int tend=gethrtime();
- int tstart=tp.trun;
- if(tend==tstart)
+ if (tp=portal._tprepared) {
+ int tend = gethrtime();
+ int tstart = tp.trun;
+ if (tend == tstart)
m_delete(_prepareds,portal._query);
else {
tp.hits++;
totalhits++;
- if(!tp.preparedname) {
- if(sizeof(portal._preparedname))
- tp.preparedname=portal._preparedname;
- tstart=tend-tstart;
- if(!tp.tparse || tp.tparse>tstart)
- tp.tparse=tstart;
+ if (!tp.preparedname) {
+ if (sizeof(portal._preparedname)) {
+ PD("Finalising stored statement %s\n", portal._preparedname);
+ tp.preparedname = portal._preparedname;
}
- tp.trunstart=tend;
+ tstart = tend - tstart;
+ if (!tp.tparse || tp.tparse>tstart)
+ tp.tparse = tstart;
}
-
+ tp.trunstart = tend;
}
-
+ }
break;
}
case 'D':
971: Inside #if defined(PG_DEBUG)
PD("%O DataRow %d bytes\n",portal._portalname,msglen);
#endif
datarowdebugcount++;
- if(!datarowdebug)
- datarowdebug=sprintf(
+ if (!datarowdebug)
+ datarowdebug = sprintf(
"%O DataRow %d bytes",portal._portalname,msglen);
#endif
#ifdef PG_DEBUG
1003:
#else
cr->consume(1);
#endif
+ #ifdef PG_DEBUGMORE
+ showportalstack("COMMANDCOMPLETE");
+ #endif
portal->_releasesession(s);
portal=0;
break;
1012: Inside #if defined(PG_DEBUG)
PD("EmptyQueryResponse %O\n",portal._portalname);
msglen-=4;
#endif
+ #ifdef PG_DEBUGMORE
+ showportalstack("EMPTYQUERYRESPONSE");
+ #endif
portal->_releasesession();
portal=0;
break;
1042:
portal=0;
break;
case 'E': {
- if (_portalsinflight <= 1 && !_readyforquerycount)
+ #ifdef PG_DEBUGMORE
+ showportalstack("ERRORRESPONSE");
+ #endif
+ if (!_portalsinflight && !_readyforquerycount)
sendsync();
PD("%O ErrorResponse %O\n",
objectp(portal)&&(portal._portalname||portal._preparedname),
1081:
switch(msgresponse.S) {
case "PANIC":werror(a2nls(lastmessage));
}
- case "25P02": // Preserve last error message
- USERERROR(a2nls(lastmessage));
+ case "25P02": // Preserve last error message
+ USERERROR(a2nls(lastmessage)); // Implicitly closed portal
}
break;
}
1179:
or=this;
if(!or._delayederror)
or._delayederror=err;
+ #ifdef PG_DEBUGMORE
+ showportalstack("THROWN");
+ #endif
if(objectp(portal))
portal->_releasesession();
portal=0;
1876:
ERROR("Querystring %O contains invalid literal nul-characters\n",q);
mapping(string:mixed) tp;
int tstart;
+ /*
+ * FIXME What happens with regards to this detection when presented with
+ * multistatement text-queries?
+ */
+ int transtype = .pgsql_util.transendprefix->match(q) ? TRANSEND
+ : .pgsql_util.transbeginprefix->match(q) ? TRANSBEGIN : NOTRANS;
if(!forcetext && forcecache==1
|| forcecache!=0
- && (sizeof(q)>=MINPREPARELENGTH || .pgsql_util.cachealways[q])) {
+ && (sizeof(q)>=MINPREPARELENGTH || transtype != NOTRANS)) {
object plugbuffer;
while(catch(plugbuffer=c->start()))
reconnect();
1926:
} else // sql_result autoassigns to portal
tp=UNDEFINED;
.pgsql_util.sql_result portal;
- portal=.pgsql_util.sql_result(this,c,q,
- portalbuffersize, _alltyped, from, forcetext, timeout, syncparse);
+ portal=.pgsql_util.sql_result(this,c,q, portalbuffersize, _alltyped, from,
+ forcetext, timeout, syncparse, transtype);
portal._tprepared=tp;
#ifdef PG_STATS
portalsopened++;
1965:
->add(PGFLUSH)
#endif
;
- }
+ } else
+ PD("Using prepared statement for %O\n", q);
portal._preparedname=preparedname;
if(!tp || !tp.datatypeoid) {
PD("Describe statement %O\n",preparedname);