pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:20:
#include "pgsql.h"
#define PORTALINIT 0 // Portal states
#define PARSING 1
#define BOUND 2
#define COMMITTED 3
#define COPYINPROGRESS 4
#define CLOSING 5
#define CLOSED 6
#define PURGED 7
- // If this is extended, change the type of _state
+
#define NOERROR 0 // Error states networkparser
#define PROTOCOLERROR 1
#define PROTOCOLUNSUPPORTED 2
#define LOSTERROR "Database connection lost"
//! The instance of the pgsql dedicated backend.
final Pike.Backend local_backend;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:403:
#endif
socket;
private int towrite;
final multiset(Result) runningportals = (<>);
final Thread.Mutex nostash;
final Thread.MutexKey started;
final Thread.Queue stashqueue;
final Thread.Condition stashavail;
final Stdio.Buffer stash;
- /* FIXME actually: int(KEEP..SYNCSEND) stashflushmode
- * but the PikeParser does not approve, and refdoc
- * generation aborts
- */
- final int(0..4) stashflushmode;
+ //! @ignore
+ final int(KEEP..SYNCSEND) stashflushmode;
+ //! @endignore
final Thread.ResourceCount stashcount;
final int synctransact;
#ifdef PG_DEBUGRACE
final mixed nostrack;
#endif
#ifdef PG_DEBUG
final int queueoutidx;
final int queueinidx = -1;
#endif
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:713:
class Result {
inherit __builtin.Sql.Result;
private proxy pgsqlsess;
private int(0..1) eoffound;
private conxion c;
private conxiin cr;
final int(0..1) untolderror;
final mixed delayederror;
- final int(0..7) _state; // FIXME actually: int(PORTALINIT..PURGED)
+ //! @ignore
+ final int(PORTALINIT..PURGED) _state;
+ //! @endignore
final int _fetchlimit;
private int(0..1) alltext;
final int(0..1) _forcetext;
private int syncparse;
private int transtype;
final string _portalname;
private int inflight;
int portalbuffersize;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:913:
case FLOAT8OID:
#endif
if (_forcetext) {
if (!alltext) {
value = (float)cr->read(collen);
break;
}
} else {
[ value ] = cr->sscanf(collen == 4 ? "%4F" : "%8F");
if (alltext)
- value = (string)value;
+ value = sprintf("%.*g", collen == 4 ? 9 : 17, value);
break;
}
default:value = cr->read(collen);
break;
case CHAROID:
value = alltext ? cr->read(1) : cr->read_int8();
break;
case BOOLOID:value = cr->read_int8();
switch (value) {
case 'f':value = 0;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1457:
}
private void releaseconditions() {
_unnamedportalkey = _unnamedstatementkey = 0;
if (!datarowtypes) {
if (_state != PURGED && !delayederror)
delayederror = LOSTERROR;
datarowtypes = emptyarray;
_ddescribe->broadcast();
}
+ if (delayederror && !pgsqlsess.delayederror)
+ pgsqlsess.delayederror = delayederror; // Preserve error upstream
pgsqlsess = 0;
}
final void _releasesession(void|string statusccomplete) {
c->runningportals[this] = 0;
if (statusccomplete && !statuscmdcomplete)
statuscmdcomplete = statusccomplete;
inflight = 0;
conxsess plugbuffer;
if (!catch(plugbuffer = c->start()))
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1549:
if (eoffound)
return 0;
array(array|int) datarow = datarows->try_read_array();
if (!sizeof(datarow)) {
array cid = setuptimeout();
PT(datarow = datarows->read_array());
local_backend->remove_call_out(cid);
}
if (arrayp(datarow[-1]))
return datarow;
+ do datarow = datarow[..<1]; // Swallow EOF mark(s)
+ while (sizeof(datarow) && !arrayp(datarow[-1]));
trydelayederror();
eoffound = 1;
datarows->write(1); // Signal EOF for other threads
- return (datarow = datarow[..<1]);
+ return datarow;
}
//! @param copydata
//! When using COPY FROM STDIN, this method accepts a string or an
//! array of strings to be processed by the COPY command; when sending
//! the amount of data sent per call does not have to hit row or column
//! boundaries.
//!
//! The COPY FROM STDIN sequence needs to be completed by either
//! explicitly or implicitly destroying the result object, or by passing no
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1670:
final mapping(string:mapping(string:mixed)) prepareds = ([]);
final int pportalcount;
final int totalhits;
final int msgsreceived; // Number of protocol messages received
final int bytesreceived; // Number of bytes received
final int warningsdropcount; // Number of uncollected warnings
private int warningscollected;
final int(0..1) invalidatecache;
private Thread.Queue qportals;
final mixed delayederror;
- private function (:void) readyforquery_cb;
+ final function (:void) readyforquery_cb;
final string host;
final int(0..65535) port;
final string database, user, pass;
private Crypto.Hash.SCRAM SASLcontext;
final Thread.Condition waitforauthready;
final Thread.Mutex shortmux;
final int readyforquerycount;
private string _sprintf(int type) {
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1872: Inside #if defined(PG_DEBUG)
void showportal(int msgtype) {
if (objectp(portal))
PD("%d<%O %d %c switch portal\n",
ci->socket->query_fd(), portal._portalname, ++ci->queueinidx, msgtype);
else if (portal>0)
PD("%d<Sync %d %d %c portal\n",
ci->socket->query_fd(), ++ci->queueinidx, portal, msgtype);
};
#endif
int msgisfatal(mapping(string:string) msgresponse) {
- if (!terminating) // Run the callback once per lost connection
- runcallback(backendpid,"_lost","");
- return (has_prefix(msgresponse.C, "53")
+ int isfatal = (has_prefix(msgresponse.C, "53")
|| has_prefix(msgresponse.C, "3D")
|| has_prefix(msgresponse.C, "57P")) && MAGICTERMINATE;
-
+ if (isfatal && !terminating) // Run the callback once per lost connection
+ runcallback(backendpid, "_lost", "");
+ return isfatal;
};
for (;;) {
err = catch {
#ifdef PG_DEBUG
if (!portal && datarowdebug) {
PD("%s rows %d\n", datarowdebug, datarowdebugcount);
datarowdebug = 0; datarowdebugcount = 0;
}
#endif
#ifdef PG_DEBUGMORE
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:2568:
*/
lastmessage = filter(lastmessage, lambda(string val) {
return has_prefix(val, "ERROR ") || has_prefix(val, "FATAL "); });
if (err || (err = catch(errstring = geterror(1))))
werror(describe_backtrace(err));
else if (errstring && sizeof(errstring))
werror("%s\n", errstring); // Add missing terminating newline
}
}
- private void sendsync() {
+ final void sendsync() {
readyforquerycount++;
c->start()->sendcmd(SYNCSEND);
}
private void runcallback(int pid, string condition, string extrainfo) {
array cb;
-
+ if (condition == "_lost")
+ destruct(c);
if ((cb = notifylist[condition] || notifylist[""])
&& (pid != backendpid || sizeof(cb) > 1 && cb[1]))
callout(cb[0], 0, pid, condition, extrainfo, @cb[2..]);
}
private inline void closestatement(
bufcon|conxsess plugbuffer, string oldprep) {
closestatement(plugbuffer, oldprep);
}
};
#pragma deprecation_warnings
//! @class sql_result
//! @deprecated Result
//! @endclass
__deprecated__(program(Result)) sql_result =
(__deprecated__(program(Result)))Result;