pike.git / lib / modules / Sql.pmod / pgsql_util.pmod

version» Context lines:

pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:38:       /* Statements matching dontcacheprefix never enter the cache    */   private Regexp dontcacheprefix=iregexp("^\a*(FETCH|COPY)\a");       /* Statements not matching paralleliseprefix will cause the driver    * to stall submission until all previously started statements have    * run to completion    */   private Regexp paralleliseprefix -  =iregexp("^\a*((SELEC|INSER)T|(UPDA|DELE)TE|FETCH)\a"); +  =iregexp("^\a*((SELEC|INSER)T|(UPDA|DELE)TE|(FETC|WIT)H)\a");       /* For statements matching execfetchlimit the resultrows will not be    * fetched in pieces    */   private Regexp execfetchlimit    =iregexp("^\a*((UPDA|DELE)TE|INSERT)\a|\aLIMIT\a+[1-9][; \t\f\r\n]*$");      private Regexp iregexp(string expr) {    Stdio.Buffer ret=Stdio.Buffer();    foreach(expr;;int c)
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:920:    if(_tprepared && dontcacheprefix->match(_query))    m_delete(pgsqlsess->_prepareds,_query),_tprepared=0;    waitfordescribe();    }    if(_state>=CLOSING)    lock=_unnamedstatementkey=0;    else {    plugbuffer->add_int16(sizeof(datarowtypes));    if(sizeof(datarowtypes))    plugbuffer->add_ints(map(datarowtypes,oidformat),2); -  else if (syncparse || !paralleliseprefix->match(_query)) { +  else if (syncparse < 0 && !pgsqlsess->_wasparallelisable +  && pgsqlsess->_portalsinflight > 1) {    lock=pgsqlsess->_shortmux->lock(); -  if(pgsqlsess->_portalsinflight) { +  // Decrement temporarily to account for ourselves +  if(--pgsqlsess->_portalsinflight) {    pgsqlsess->_waittocommit++;    PD("Commit waiting for portals to finish\n");    catch(PT(pgsqlsess->_readyforcommit->wait(lock)));    pgsqlsess->_waittocommit--;    } -  +  // Increment again to account for ourselves +  pgsqlsess->_portalsinflight++;    }    lock=0;    PD("Bind portal %O statement %O\n",_portalname,_preparedname);    _fetchlimit=pgsqlsess->_fetchlimit; -  _openportal(); +  _bindportal();    conxsess bindbuffer = c->start();    _unnamedstatementkey=0;    CHAIN(bindbuffer)->add_int8('B')->add_hstring(plugbuffer, 4, 4);    if(!_tprepared && sizeof(_preparedname))    closestatement(CHAIN(bindbuffer), _preparedname);    _sendexecute(_fetchlimit    && !(cachealways[_query]    || sizeof(_query)>=MINPREPARELENGTH &&    execfetchlimit->match(_query))    && _fetchlimit,bindbuffer);
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:957:       final void _processrowdesc(array(mapping(string:mixed)) datarowdesc,    array(int) datarowtypes) {    _setrowdesc(datarowdesc,datarowtypes);    if(_tprepared) {    _tprepared.datarowdesc=datarowdesc;    _tprepared.datarowtypes=datarowtypes;    }    }    -  final void _openportal() { +  final void _parseportal() { +  Thread.MutexKey lock; +  if (syncparse || syncparse < 0 && pgsqlsess->_wasparallelisable) { +  lock = pgsqlsess->_shortmux->lock(); +  if(pgsqlsess->_portalsinflight) { +  pgsqlsess->_waittocommit++; +  PD("Commit waiting for portals to finish\n"); +  // Do NOT put this in a function, it would require passing a lock +  // variable on the argumentstack to the function, which will cause +  // unpredictable lock release issues due to the extra copy on the stack +  catch(PT(pgsqlsess->_readyforcommit->wait(lock))); +  pgsqlsess->_waittocommit--; +  } +  }    pgsqlsess->_portalsinflight++; -  +  lock = closemux->lock(); +  _state=PARSING; +  lock=0; +  statuscmdcomplete=UNDEFINED; +  pgsqlsess->_wasparallelisable = paralleliseprefix->match(_query); +  } +  +  final void _bindportal() {    Thread.MutexKey lock=closemux->lock();    _state=BOUND;    lock=0; -  statuscmdcomplete=UNDEFINED; +     }       final void _purgeportal() { -  +  PD("Purge portal\n");    datarows->write(1); // Signal EOF    Thread.MutexKey lock=closemux->lock();    _fetchlimit=0; // disables further Executes    switch(_state) {    case COPYINPROGRESS:    case BOUND: -  +  case PARSING:    --pgsqlsess->_portalsinflight;    }    _state=CLOSED;    lock=0;    releaseconditions();    }       final int _closeportal(conxsess cs) {    object plugbuffer = CHAIN(cs);    int retval=KEEP;
pike.git/lib/modules/Sql.pmod/pgsql_util.pmod:1002:    plugbuffer->add("c\0\0\0\4");    case BOUND:    _state=CLOSING;    lock=0;    PD("Close portal %O\n",_portalname);    if(sizeof(_portalname)) {    plugbuffer->add_int8('C')->add_hstring(({'P',_portalname,0}),4,4);    retval=FLUSHSEND;    } else    _unnamedportalkey=0; +  case PARSING: +  _unnamedstatementkey = 0; +  _state = CLOSING; +  lock = 0;    Thread.MutexKey lockc=pgsqlsess->_shortmux->lock();    if(!--pgsqlsess->_portalsinflight) {    if(pgsqlsess->_waittocommit) {    PD("Signal no portals in flight\n");    catch(pgsqlsess->_readyforcommit->signal());    lockc=0;    /*    * stashcount will be non-zero if a parse request has been queued    * before the close was initiated.    * It's a bit of a tricky race, but this check should be sufficient.