pike.git
/
lib
/
modules
/
Sql.pmod
/
pgsql_util.pmod
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:423:
final int _state; final int _fetchlimit; private int alltext; final int _forcetext; final string _portalname; private int rowsreceived; private int inflight; private int portalbuffersize;
-
private Stdio.Buffer prepbuffer;
-
private Thread.Condition prepbufferready;
-
private Thread.Mutex prepbuffermux;
+
private Thread.Mutex closemux; private Thread.Queue datarows; private array(mapping(string:mixed)) datarowdesc;
-
+
private array(int) datarowtypes; // cached types from datarowdesc
private string statuscmdcomplete; private int bytesreceived; final int _synctransact; final Thread.Condition _ddescribe; final Thread.Mutex _ddescribemux; final Thread.MutexKey _unnamedportalkey,_unnamedstatementkey; final array _params; final string _query; final string _preparedname; final mapping(string:mixed) _tprepared;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:450:
private string _sprintf(int type, void|mapping flags) { string res=UNDEFINED; switch(type) { case 'O': res=sprintf("sql_result state: %d numrows: %d eof: %d inflight: %d\n" "query: %O\n" "fd: %O portalname: %O datarows: %d" " laststatus: %s\n", _state,rowsreceived,eoffound,inflight, _query,c?->socket?->query_fd(),
-
_portalname,
datarowdesc
&&sizeof(
datarowdesc
),
+
_portalname,
datarowtypes
&&sizeof(
datarowtypes
),
statuscmdcomplete||(_unnamedstatementkey?"*parsing*":"")); break; } return res; } protected void create(object _pgsqlsess,conxion _c,string query, int _portalbuffersize,int alltyped,array params,int forcetext) { pgsqlsess = _pgsqlsess; cr = (c = _c)->i; _query = query; datarows = Thread.Queue(); _ddescribe=Thread.Condition(); _ddescribemux=Thread.Mutex(); closemux=Thread.Mutex();
-
prepbufferready=Thread.Condition();
-
prepbuffermux=Thread.Mutex();
+
portalbuffersize=_portalbuffersize; alltext = !alltyped; _params = params; _forcetext = forcetext; _state = PORTALINIT; } //! Returns the command-complete status for this query. //! //! @seealso
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:512:
final void _storetiming() { if(_tprepared) { _tprepared.trun=gethrtime()-_tprepared.trunstart; m_delete(_tprepared,"trunstart"); _tprepared = UNDEFINED; } } private void waitfordescribe() { Thread.MutexKey lock=_ddescribemux->lock();
-
if(!
datarowdesc
)
+
if(!
datarowtypes
)
_ddescribe->wait(lock); lock=0; } //! @seealso //! @[Sql.sql_result()->num_fields()] int num_fields() {
-
if(!
datarowdesc
)
+
if(!
datarowtypes
)
waitfordescribe(); trydelayederror();
-
return sizeof(
datarowdesc
);
+
return sizeof(
datarowtypes
);
} //! @seealso //! @[Sql.sql_result()->num_rows()] int num_rows() { trydelayederror(); return rowsreceived; } private inline void trydelayederror() {
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:548:
//! @seealso //! @[Sql.sql_result()->eof()] int eof() { trydelayederror(); return eoffound; } //! @seealso //! @[Sql.sql_result()->fetch_fields()] array(mapping(string:mixed)) fetch_fields() {
-
if(!
datarowdesc
)
+
if(!
datarowtypes
)
waitfordescribe(); trydelayederror(); return datarowdesc+({}); } #ifdef PG_DEBUG final int #else final void #endif _decodedata(int msglen,string cenc) { _storetiming(); string serror; bytesreceived+=msglen; int cols=cr->read_int16(); array a=allocate(cols,!alltext&&Val.null); #ifdef PG_DEBUG msglen-=2+4*cols; #endif
-
foreach(
datarowdesc
;int i;
mapping
m
) {
+
foreach(
datarowtypes
;int i;
int
typ
) {
int collen=cr->read_sint(4); if(collen>0) { #ifdef PG_DEBUG msglen-=collen; #endif mixed value;
-
switch(
int
typ
=m.type
) {
+
switch(typ) {
case FLOAT4OID: #if SIZEOF_FLOAT>=8 case FLOAT8OID: #endif if(!alltext) { value=(float)cr->read(collen); break; } default:value=cr->read(collen); break;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:640:
_processdataready(a); if(serror) error(serror); #ifdef PG_DEBUG return msglen; #endif } final void _setrowdesc(array(mapping(string:mixed)) drowdesc) { Thread.MutexKey lock=_ddescribemux->lock();
-
datarowdesc=drowdesc;
+
datarowtypes=map(
datarowdesc=drowdesc
,lambda(mapping m){return m.type
;
});
_ddescribe->broadcast(); lock=0; } final void _preparebind(array dtoid) { array(string|int) paramValues=_params?_params[2]:({}); if(sizeof(dtoid)!=sizeof(paramValues)) SUSERERROR("Invalid number of bindings, expected %d, got %d\n", sizeof(dtoid),sizeof(paramValues));
-
Thread.MutexKey lock=
prepbuffermux
->lock();
+
Thread.MutexKey lock=
_ddescribemux
->lock();
if(!_portalname) { _portalname=(_unnamedportalkey=pgsqlsess._unnamedportalmux->trylock(1)) ? "" : PORTALPREFIX #ifdef PG_DEBUG +(string)(c->socket->query_fd())+"_" #endif +int2hex(pgsqlsess._pportalcount++); lock=0; #ifdef PG_DEBUGMORE PD("ParamValues to bind: %O\n",paramValues);
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:781:
break; case OIDOID: case INT4OID: plugbuffer->add_int32(4)->add_int32((int)value); break; case INT2OID: plugbuffer->add_int32(2)->add_int16((int)value); break; } }
-
if(
_tprepared
)
-
if(_tprepared
.datarowdesc)
-
gotdatarowdesc(plugbuffer);
-
else if(
dontcacheprefix->match(_query))
// Don't cache FETCH/COPY
+
if(
!datarowtypes
)
{
+
if(_tprepared
&&
dontcacheprefix->match(_query))
m_delete(pgsqlsess->_prepareds,_query),_tprepared=0;
-
if(prepbufferready)
{
-
lock=prepbuffermux->lock
();
-
prepbuffer=plugbuffer;
-
if(prepbufferready)
-
prepbufferready->signal();
+
waitfordescribe
();
}
-
}
-
lock=0;
-
}
-
-
final void _processrowdesc(array(mapping(string:mixed)) datarowdesc) {
-
_setrowdesc(datarowdesc);
-
if(_
tprepared)
-
_tprepared.datarowdesc=datarowdesc;
-
if(prepbufferready)
-
Thread.Thread(gotdatarowdesc); // Do not use callout, it deadlocks
-
}
-
-
private void gotdatarowdesc(void|Stdio.Buffer plugbuffer) {
-
Thread.MutexKey lock=prepbuffermux->lock();
-
if(!plugbuffer) {
-
if(!prepbuffer && prepbufferready)
-
prepbufferready->wait(lock);
-
plugbuffer=prepbuffer;
-
prepbuffer=0; // Free memory when plugbuffer leaves scope
-
}
-
if(!prepbufferready || _
state>=CLOSING)
+
if(_state>=CLOSING)
lock=_unnamedstatementkey=0; else {
-
prepbufferready->signal();
-
prepbufferready=0; // Make sure we do this exactly once
-
lock=0;
-
plugbuffer->add_int16(sizeof(
datarowdesc
));
-
if(sizeof(
datarowdesc
))
-
foreach(
datarowdesc
;;
mapping
col
)
-
plugbuffer->add_int16(oidformat(
col.type
));
+
plugbuffer->add_int16(sizeof(
datarowtypes
));
+
if(sizeof(
datarowtypes
))
+
foreach(
datarowtypes
;;
int
typ
)
+
plugbuffer->add_int16(oidformat(
typ
));
else if(commitprefix->match(_query)) {
-
+
lock=pgsqlsess->_shortmux->lock(); if(pgsqlsess->_portalsinflight) { pgsqlsess->_waittocommit++; PD("Commit waiting for portals to finish\n"); pgsqlsess->_readyforcommit->wait(lock); pgsqlsess->_waittocommit--; }
-
lock=0;
+
}
-
+
lock=0;
PD("Bind portal %O statement %O\n",_portalname,_preparedname); _fetchlimit=pgsqlsess->_fetchlimit; _openportal(); conxion bindbuffer=c->start(1); _unnamedstatementkey=0; bindbuffer->add_int8('B')->add_hstring(plugbuffer,4,4); if(!_tprepared && sizeof(_preparedname)) closestatement(bindbuffer,_preparedname); _sendexecute(_fetchlimit && !(cachealways[_query] || sizeof(_query)>=MINPREPARELENGTH && execfetchlimit->match(_query)) && _fetchlimit,bindbuffer); }
-
+
} else
+
lock=0;
}
-
+
final void _processrowdesc(array(mapping(string:mixed)) datarowdesc) {
+
_setrowdesc(datarowdesc);
+
if(_tprepared)
+
_tprepared.datarowdesc=datarowdesc;
+
}
+
final void _openportal() { pgsqlsess->_portalsinflight++; Thread.MutexKey lock=closemux->lock(); _state=BOUND; lock=0; statuscmdcomplete=UNDEFINED; } final void _purgeportal() { _unnamedportalkey=_unnamedstatementkey=0;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:939:
_sendexecute(_fetchlimit); else if(!_fetchlimit) PD("<%O _fetchlimit %d, inflight %d, skip execute\n", _portalname,_fetchlimit,inflight); lock=0; } } private void releaseconditions() { pgsqlsess=0;
-
Thread.MutexKey lock;
-
if(
prepbufferready) {
-
lock=prepbuffermux->lock();
-
if(prepbufferready)
-
prepbufferready->signal();
-
}
-
if(
!
datarowdesc
) {
-
lock=_ddescribemux->lock();
-
datarowdesc=({});
+
if(
!datarowtypes
) {
+
Thread.MutexKey
lock=_ddescribemux->lock();
+
datarowtypes=
datarowdesc=({});
_ddescribe->broadcast();
-
}
+
lock=0; }
-
+
}
final void _releasesession(void|string statusccomplete) { if(statusccomplete && !statuscmdcomplete) statuscmdcomplete=statusccomplete; inflight=0; conxion plugbuffer=c->start(1); plugbuffer->sendcmd(_closeportal(plugbuffer)); _state=CLOSED; datarows->write(1); // Signal EOF releaseconditions();