Branch: Tag:

2008-07-27

2008-07-27 15:18:21 by Stephen R. van den Berg <srb@cuci.nl>

PGsql, fix a few typos, proper use of classes, cleanup stackhandling

Rev: lib/modules/Sql.pmod/pgsql.pike:1.13
Rev: lib/modules/Sql.pmod/pgsqls.pike:1.3
Rev: src/modules/_PGsql/PGsql.cmod:1.13
Rev: src/modules/_PGsql/configure.in:1.6

31:   #endif   //#define NO_LOCKING 1 // This breaks the driver, do not enable,    // only for benchmarking mutex performance - #define USEPGsql 1 // Doesn't use Stdio.FILE, but PGassist + #define USEPGsql 1 // Doesn't use Stdio.FILE, but _PGsql      #ifdef USEPGsql   #define UNBUFFEREDIO 1
59:      #define ERROR(X ...) predef::error(X)    - pgsql_result _portal; +    int _nextportal;   int _closesent;   int _fetchlimit=FETCHLIMIT;   private int unnamedportalinuse;   private int portalsinflight;    - private object conn; + object _c;   private string SSauthdata,cancelsecret;   private int backendpid;   private int backendstatus;
111:    "portal %d %O\n%O\n",    user,host,port,database,backendpid,status_commit(),reconnected,    mstate,qstate,pstmtcount,pportalcount, -  _portal&&_portal->query||"", +  _c.portal&&_c.portal->query||"",    lastmessage||"",    msgresponse, -  !!_portal,runtimeparameter,prepareds); +  !!_c.portal,runtimeparameter,prepareds);    break;    }    return res;
211:   //! and how (TCP/IP or UNIX sockets).      string host_info() { -  return sprintf("Via fd:%d over TCP/IP to %s:%d",conn->query_fd(),host,port); +  return sprintf("Via fd:%d over TCP/IP to %s:%d",_c.query_fd(),host,port);   }    - #define SENDCMD(x ...) conn.sendcmd(x) - #define GETBYTE() conn.getbyte() - #define GETSTRING(x) conn.getstring(x) - #define GETINT16() conn.getint16() - #define GETINT32() conn.getint32() - #define FLUSHED conn.flushed -  - #ifdef USEPGsql - #define PEEK(x) conn.bpeek(x) - #else - #define PEEK(x) conn.peek(x) - #endif -  - #define plugstring(x) (sprintf x) -  - #define plugbyte(x) String.int2char(x) -  - inline final private string plugint16(int x) { -  return sprintf("%c%c",x>>8&255,x&255); - } -  - inline final private string plugint32(int x) { -  return sprintf("%c%c%c%c",x>>24&255,x>>16&255,x>>8&255,x&255); - } -  - inline final private string plugint64(int x) { -  return sprintf("%c%c%c%c%c%c%c%c", -  x>>56&255,x>>48&255,x>>40&255,x>>32&255,x>>24&255,x>>16&255,x>>8&255,x&255); - } -  +    class PGassist {       int(-1..1) peek(int timeout) {
264: Inside #if defined(USEPGsql)
  #ifdef USEPGsql    inherit _PGsql.PGsql;   #else +  object portal; +  +  void setportal(void|object newportal) { +  portal=newportal; +  } +  +  inline int(-1..1) bpeek(int timeout) { +  return peek(timeout); +  } +     int flushed;   #endif    -  void create(object pgsqlsess) { +  void create(void|object pgsqlsess) {   #ifdef USEPGsql -  +  if(pgsqlsess)    ::create(pgsqlsess);   #else    flushed=-1;
277: Inside #if undefined(USEPGsql)
     #ifndef USEPGsql    inline final int getbyte() { -  if(!FLUSHED && !PEEK(0)) +  if(!flushed && !bpeek(0))    sendflush();    return getchar();    }
286: Inside #if undefined(USEPGsql)
   if(!zero_type(len)) {    string acc="",res;    do { -  if(!FLUSHED && !PEEK(0)) +  if(!flushed && !bpeek(0))    sendflush(); -  res=conn.read(len,!FLUSHED); +  res=read(len,!flushed);    if(res) {    if(!sizeof(res))    return acc;
300: Inside #if undefined(USEPGsql)
   }    array(int) acc=({});    int c; -  while((c=GETBYTE())>0) +  while((c=getbyte())>0)    acc+=({c});    return `+("",@map(acc,String.int2char));    }       inline final int getint16() { -  int s0=GETBYTE(); -  int r=(s0&0x7f)<<8|GETBYTE(); +  int s0=getbyte(); +  int r=(s0&0x7f)<<8|getbyte();    return s0&0x80 ? r-(1<<15) : r ;    }       inline final int getint32() { -  int r=GETINT16(); -  r=r<<8|GETBYTE(); -  return r<<8|GETBYTE(); +  int r=getint16(); +  r=r<<8|getbyte(); +  return r<<8|getbyte();    }       inline final int getint64() { -  int r=GETINT32(); -  return r<<32|GETINT32()&0xffffffff; +  int r=getint32(); +  return r<<32|getint32()&0xffffffff;    }   #endif    -  +  inline final string plugbyte(int x) { +  return String.int2char(x); +  } +  +  inline final string plugint16(int x) { +  return sprintf("%c%c",x>>8&255,x&255); +  } +  +  inline final string plugint32(int x) { +  return sprintf("%c%c%c%c",x>>24&255,x>>16&255,x>>8&255,x&255); +  } +  +  inline final string plugint64(int x) { +  return sprintf("%c%c%c%c%c%c%c%c",x>>56&255,x>>48&255,x>>40&255,x>>32&255, +  x>>24&255,x>>16&255,x>>8&255,x&255); +  } +     final void sendflush() {    sendcmd(({}),1);    }
334:    else    data+=({FLUSH});    PD("Flush\n"); -  FLUSHED=1; +  flushed=1;    } -  else if(FLUSHED!=-1) -  FLUSHED=0; +  else if(flushed!=-1) +  flushed=0;    return write(data);    }       final void sendterminate() {    PD("Terminate\n"); -  SENDCMD(({"X",plugint32(4)})); +  sendcmd(({"X",plugint32(4)}));    close();    }   }
415:   }   #endif    - final private object getsocket() { + final private object getsocket(void|int nossl) {    object lcon = Stdio.File();    if(!lcon.connect(host,port))    return UNDEFINED;       object fcon;   #if constant(SSL.sslfile) -  if(options->use_ssl || options->force_ssl) { +  if(!nossl && (options->use_ssl || options->force_ssl)) {    PD("SSLRequest\n"); -  lcon.write(({plugint32(8),plugint32(PG_PROTOCOL(1234,5679))})); +  { object c=PGassist(); +  lcon.write(({c.plugint32(8),c.plugint32(PG_PROTOCOL(1234,5679))})); +  }    switch(lcon.read(1)) {    case "S":    SSL.context context = SSL.context();
459:    qstate=cancelpending;    object lcon;    PD("CancelRequest\n"); -  if(!(lcon=getsocket())) +  if(!(lcon=getsocket(1)))    ERROR("Cancel connect failed\n"); -  lcon.write(({plugint32(16),plugint32(PG_PROTOCOL(1234,5678)), -  plugint32(backendpid),cancelsecret})); +  lcon.write(({_c.plugint32(16),_c.plugint32(PG_PROTOCOL(1234,5678)), +  _c.plugint32(backendpid),cancelsecret}));    lcon.close();    }   }
547:    if(mstate!=unauthenticated) {    if(qstate==cancelpending)    qstate=canceled,sendclose(); -  if(FLUSHED && qstate==inquery && !PEEK(0)) { +  if(_c.flushed && qstate==inquery && !_c.bpeek(0)) {    int tcurr=time();    int told=tcurr+timeout; -  while(!PEEK(told-tcurr)) +  while(!_c.bpeek(told-tcurr))    if((tcurr=time())-told>=timeout) {    sendclose();cancelquery();    break;    }    }    } -  int msgtype=GETBYTE(); -  int msglen=GETINT32(); +  int msgtype=_c.getbyte(); +  int msglen=_c.getint32();    enum errortype { noerror=0, protocolerror, protocolunsupported };    errortype errtype=noerror;    switch(msgtype) {    void getcols() { -  int bintext=GETBYTE(); +  int bintext=_c.getbyte();    array a; -  int cols=GETINT16(); +  int cols=_c.getint16();    msglen-=4+1+2+2*cols;    foreach(a=allocate(cols,([]));;mapping m) -  m->type=GETINT16(); -  if(_portal) { +  m->type=_c.getint16(); +  if(_c.portal) { // Discard column info, and make it line oriented    a=({(["type":bintext?BYTEAOID:TEXTOID,"name":"line"])}); -  _portal->_datarowdesc=a; +  _c.portal->_datarowdesc=a;    }    mstate=gotrowdescription;    };
579:    string s;    if(msglen<1)    errtype=protocolerror; -  s=GETSTRING(msglen); +  s=_c.getstring(msglen);    if(s[--msglen])    errtype=protocolerror;    if(!msglen)
599:    { string sendpass;    int authtype;    msglen-=4+4; -  switch(authtype=GETINT32()) { +  switch(authtype=_c.getint32()) {    case 0:PD("Ok\n");    mstate=authenticated;    break;
612:    case 4:PD("CryptPassword\n");    if(msglen<2)    errtype=protocolerror; -  sendpass=GETSTRING(msglen);msglen=0; +  sendpass=_c.getstring(msglen);msglen=0;    errtype=protocolunsupported;    break;    case 5:PD("MD5Password\n");
621:   #if constant(Crypto.MD5.hash)   #define md5hex(x) String.string2hex(Crypto.MD5.hash(x))    sendpass=md5hex(pass+user); -  sendpass="md5"+md5hex(sendpass+GETSTRING(msglen)); +  sendpass="md5"+md5hex(sendpass+_c.getstring(msglen));   #else -  GETSTRING(msglen); +  _c.getstring(msglen);    errtype=protocolunsupported;   #endif    msglen=0;
641:    errtype=protocolunsupported;    if(msglen<1)    errtype=protocolerror; -  SSauthdata=GETSTRING(msglen);msglen=0; +  SSauthdata=_c.getstring(msglen);msglen=0;    break;    default:PD("Unknown Authentication Method %c\n",authtype);    errtype=protocolunsupported;
650:    switch(errtype) {    case noerror:    if(mstate==unauthenticated) -  SENDCMD(({"p",plugint32(4+sizeof(sendpass)+1), +  _c.sendcmd(({"p",_c.plugint32(4+sizeof(sendpass)+1),    sendpass,"\0"}),1);    break;    default:
661:    break;    }    case 'K':PD("BackendKeyData\n"); -  msglen-=4+4;backendpid=GETINT32();cancelsecret=GETSTRING(msglen); +  msglen-=4+4;backendpid=_c.getint32();cancelsecret=_c.getstring(msglen);    msglen=0;    break;    case 'S':PD("ParameterStatus\n");
677:    break;    case 'Z':PD("ReadyForQuery\n");    msglen-=4+1; -  backendstatus=GETBYTE(); +  backendstatus=_c.getbyte();    mstate=readyforquery;    qstate=queryidle;    _closesent=0;
688:    break;    case 't':    PD("ParameterDescription (for %s)\n", -  _portal?_portal->_portalname:"DISCARDED"); +  _c.portal?_c.portal->_portalname:"DISCARDED");    { array a; -  int cols=GETINT16(); +  int cols=_c.getint16();    msglen-=4+2+4*cols;    foreach(a=allocate(cols);int i;) -  a[i]=GETINT32(); +  a[i]=_c.getint32();   #ifdef DEBUGMORE    PD("%O\n",a);   #endif -  if(_portal) -  _portal->_datatypeoid=a; +  if(_c.portal) +  _c.portal->_datatypeoid=a;    mstate=gotparameterdescription;    break;    }    case 'T':    PD("RowDescription (for %s)\n", -  _portal?_portal->_portalname:"DISCARDED"); +  _c.portal?_c.portal->_portalname:"DISCARDED");    msglen-=4+2;    { array a; -  foreach(a=allocate(GETINT16());int i;) { +  foreach(a=allocate(_c.getint16());int i;) {    string s; -  msglen-=sizeof(s=GETSTRING())+1; +  msglen-=sizeof(s=_c.getstring())+1;    mapping(string:mixed) res=(["name":s]);    msglen-=4+2+4+2+4+2; -  res->tableoid=GETINT32()||UNDEFINED; -  res->tablecolattr=GETINT16()||UNDEFINED; -  res->type=GETINT32(); -  { int len=GETINT16(); +  res->tableoid=_c.getint32()||UNDEFINED; +  res->tablecolattr=_c.getint16()||UNDEFINED; +  res->type=_c.getint32(); +  { int len=_c.getint16();    res->length=len>=0?len:"variable";    } -  res->atttypmod=GETINT32();res->formatcode=GETINT16(); +  res->atttypmod=_c.getint32();res->formatcode=_c.getint16();    a[i]=res;    }   #ifdef DEBUGMORE    PD("%O\n",a);   #endif -  if(_portal) -  _portal->_datarowdesc=a; +  if(_c.portal) +  _c.portal->_datarowdesc=a;    mstate=gotrowdescription;    break;    }    case 'n':PD("NoData\n");    msglen-=4; -  _portal->_datarowdesc=({}); +  _c.portal->_datarowdesc=({});    mstate=gotrowdescription;    break;    case '2':PD("BindComplete\n");
740:    break;    case 'D':PD("DataRow\n");    msglen-=4; -  if(_portal) { +  if(_c.portal) {   #ifdef USEPGsql -  conn.decodedatarow(msglen,_portal);msglen=0; +  _c.decodedatarow(msglen);msglen=0;   #else    array a, datarowdesc; -  _portal->_bytesreceived+=msglen; -  datarowdesc=_portal->_datarowdesc; -  int cols=GETINT16(); +  _c.portal->_bytesreceived+=msglen; +  datarowdesc=_c.portal->_datarowdesc; +  int cols=_c.getint16();    a=allocate(cols,UNDEFINED);    msglen-=2+4*cols;    foreach(a;int i;) { -  int collen=GETINT32(); +  int collen=_c.getint32();    if(collen>0) {    msglen-=collen;    mixed value;    switch(datarowdesc[i]->type) { -  default:value=GETSTRING(collen); +  default:value=_c.getstring(collen);    break;    case CHAROID: -  case BOOLOID:value=GETBYTE(); +  case BOOLOID:value=_c.getbyte();    break; -  case INT8OID:value=conn.getint64(); +  case INT8OID:value=_c.getint64();    break; -  case FLOAT4OID:value=(float)GETSTRING(collen); +  case FLOAT4OID:value=(float)_c.getstring(collen);    break; -  case INT2OID:value=GETINT16(); +  case INT2OID:value=_c.getint16();    break;    case OIDOID: -  case INT4OID:value=GETINT32(); +  case INT4OID:value=_c.getint32();    }    a[i]=value;    }
776:    a[i]="";    }    a=({a}); -  _portal->_datarows+=a; -  _portal->_inflight-=sizeof(a); +  _c.portal->_datarows+=a; +  _c.portal->_inflight-=sizeof(a);   #endif    }    else -  GETSTRING(msglen),msglen=0; +  _c.getstring(msglen),msglen=0;    mstate=dataready;    break;    case 's':PD("PortalSuspended\n");
792:    { msglen-=4;    if(msglen<1)    errtype=protocolerror; -  string s=GETSTRING(msglen-1); -  if(_portal) -  _portal->_statuscmdcomplete=s; +  string s=_c.getstring(msglen-1); +  if(_c.portal) +  _c.portal->_statuscmdcomplete=s;    PD("%s\n",s); -  if(GETBYTE()) +  if(_c.getbyte())    errtype=protocolerror;    msglen=0;    mstate=commandcomplete;
814:    msglen-=4;    if(msglen<0)    errtype=protocolerror; -  if(_portal) { -  _portal->_bytesreceived+=msglen; -  _portal->_datarows+=({({GETSTRING(msglen)})}); +  if(_c.portal) { +  _c.portal->_bytesreceived+=msglen; +  _c.portal->_datarows+=({({_c.getstring(msglen)})});    }    msglen=0;    mstate=dataready;    break;    case 'H':PD("CopyOutResponse\n");    getcols(); -  if(_portal) -  _portal->_fetchlimit=0; // disables further Executes +  if(_c.portal) +  _c.portal->_fetchlimit=0; // disables further Executes    break;    case 'G':PD("CopyInResponse\n");    getcols();
839:    case "P0001":    lastmessage=sprintf("%s: %s",msgresponse->S,msgresponse->M);    ERROR(lastmessage -  +"\n"+pinpointerror(_portal->query,msgresponse->P)); +  +"\n"+pinpointerror(_c.portal->query,msgresponse->P));    break;    default:    lastmessage=sprintf("%s %s:%s %s\n (%s:%s:%s)\n%s%s%s%s\n%s",    msgresponse->S,msgresponse->C,msgresponse->P||"",msgresponse->M,    msgresponse->F||"",msgresponse->R||"",msgresponse->L||"",    addnlifpresent(msgresponse->D),addnlifpresent(msgresponse->H), -  pinpointerror(_portal&&_portal->query,msgresponse->P), +  pinpointerror(_c.portal&&_c.portal->query,msgresponse->P),    pinpointerror(msgresponse->q,msgresponse->p),    addnlifpresent(msgresponse->W));    switch(msgresponse->S) {
862:    break;    case 'A':PD("NotificationResponse\n");    { msglen-=4+4; -  int pid=GETINT32(); +  int pid=_c.getint32();    string condition,extrainfo=UNDEFINED;    { array(string) ts=getstrings();    switch(sizeof(ts)) {
881:    break;    }    default:PD("Unknown message received %c\n",msgtype); -  msglen-=4;PD("%O\n",GETSTRING(msglen));msglen=0; +  msglen-=4;PD("%O\n",_c.getstring(msglen));msglen=0;    errtype=protocolunsupported;    break;    }
908: Inside #if undefined(UNBUFFEREDIO)
     #ifndef UNBUFFEREDIO   private int read_cb(mixed foo, string d) { -  conn.unread(d); +  _c.unread(d);    do _decodemsg(); -  while(PEEK(0)==1); +  while(_c.bpeek(0)==1);    return 0;   }   #endif      void destroy() { -  conn.sendterminate(); +  if(_c) +  _c.sendterminate();   }      private void reconnect(void|int force) { -  if(conn) { +  if(_c) {    reconnected++;   #ifdef DEBUG    ERROR("While debugging, reconnects are forbidden\n");    exit(1);   #endif    if(!force) -  conn.sendterminate(); +  _c.sendterminate();    foreach(prepareds;;mapping tprepared)    m_delete(tprepared,"preparedname");    } -  if(!(conn=getsocket())) +  if(!(_c=getsocket()))    ERROR("Couldn't connect to database on %s:%d\n",host,port);    _closesent=0;    mstate=unauthenticated;    qstate=queryidle;    runtimeparameter=([]); -  array(string) plugbuf=({"",plugint32(PG_PROTOCOL(3,0))}); +  array(string) plugbuf=({"",_c.plugint32(PG_PROTOCOL(3,0))});    if(user)    plugbuf+=({"user\0",user,"\0"});    if(database)
948:    int len=4;    foreach(plugbuf;;string s)    len+=sizeof(s); -  plugbuf[0]=plugint32(len); -  SENDCMD(plugbuf); +  plugbuf[0]=_c.plugint32(len); +  _c.sendcmd(plugbuf);    PD("%O\n",plugbuf);    _decodemsg(readyforquery);    PD("%O\n",runtimeparameter);
967:    PD("Portalsinflight: %d\n",portalsinflight);    if(!portalsinflight) {    PD("Sync\n"); -  SENDCMD(({"S",plugint32(4)})); +  _c.sendcmd(({"S",_c.plugint32(4)}));    didsync=1;    if(!special) {    _decodemsg(readyforquery);
984:    else if(didsync && special==2)    _decodemsg(readyforquery);   #ifndef UNBUFFEREDIO -  conn.set_read_callback(read_cb); +  _c.set_read_callback(read_cb);   #endif   }   
1112:   //! If a glob is specified, it will return only those tables with matching   //! names.   array(string) list_tables (void|string glob) { -  array row,ret=({}); // This query might not work on PostgreSQL 7.4 -  object res=big_query( // due to missing schemasupport +  array row,ret=({}); // This query might not work on PostgreSQL 7.4 +  object res=big_query( // due to missing schemasupport    "SELECT CASE WHEN 'public'=n.nspname THEN '' ELSE n.nspname||'.' END "    " ||c.relname AS name " -  "FROM pg_catalog.pg_class c " -  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace " -  "WHERE c.relkind IN ('r','v') AND n.nspname<>'pg_catalog' " -  " AND n.nspname !~ '^pg_toast' AND pg_catalog.pg_table_is_visible(c.oid) " +  "FROM pgcatalog.pgclass c " +  " LEFT JOIN pgcatalog.pg_namespace n ON n.oid=c.relnamespace " +  "WHERE c.relkind IN ('r','v') AND n.nspname<>'pgcatalog' " +  " AND n.nspname !~ '^pg_toast' AND pgcatalog.pg_table_is_visible(c.oid) "    " AND c.relname ILIKE :glob "    " ORDER BY 1",    ([":glob":glob2reg(glob)]));
1192:    " WHEN 'i' THEN 'index' "    " WHEN 'S' THEN 'sequence' "    " WHEN 's' THEN 'special' " -  " WHEN 't' THEN 'toastable' " // pun intended :-) +  " WHEN 't' THEN 'toastable' " // pun intended :-)    " WHEN 'c' THEN 'composite' "    " ELSE c.relkind::TEXT END AS relkind, "    " r.rolname " -  "FROM pg_catalog.pg_class c " -  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace " -  " JOIN pg_catalog.pg_roles r ON r.oid=c.relowner " -  " JOIN pg_catalog.pg_attribute a ON c.oid=a.attrelid " -  " JOIN pg_catalog.pg_type t ON a.atttypid=t.oid " +  "FROM pgcatalog.pgclass c " +  " LEFT JOIN pgcatalog.pg_namespace n ON n.oid=c.relnamespace " +  " JOIN pgcatalog.pg_roles r ON r.oid=c.relowner " +  " JOIN pgcatalog.pg_attribute a ON c.oid=a.attrelid " +  " JOIN pgcatalog.pg_type t ON a.atttypid=t.oid "    "WHERE c.relname ILIKE :table AND "    " (n.nspname ILIKE :schema OR "    " :schema IS NULL " -  " AND n.nspname<>'pg_catalog' AND n.nspname !~ '^pg_toast') " +  " AND n.nspname<>'pgcatalog' AND n.nspname !~ '^pg_toast') "    " AND a.attname ILIKE :wild "    " AND (a.attnum>0 OR '*'=:realwild) "    "ORDER BY n.nspname,c.relname,a.attnum,a.attname",
1268:    case UUIDOID:    return 1; //binary    } -  return 0; // text +  return 0; // text   }      final void _sendexecute(int fetchlimit) { -  string portalname=_portal->_portalname; +  string portalname=_c.portal->_portalname;    PD("Execute portal %s fetchlimit %d\n",portalname,fetchlimit); -  SENDCMD(({"E",plugint32(4+sizeof(portalname)+1+4),portalname, -  "\0",plugint32(fetchlimit)}),1); -  _portal->_inflight+=fetchlimit; +  _c.sendcmd(({"E",_c.plugint32(4+sizeof(portalname)+1+4),portalname, +  "\0",_c.plugint32(fetchlimit)}),1); +  _c.portal->_inflight+=fetchlimit;   }      final private void sendclose() {    string portalname;    portalsinflight--; -  if(_portal && (portalname=_portal->_portalname)) { -  _portal->_portalname = UNDEFINED; -  _portal = UNDEFINED; +  if(_c.portal && (portalname=_c.portal->_portalname)) { +  _c.portal->_portalname = UNDEFINED; +  _c.setportal();   #ifdef DEBUGMORE    PD("Closetrace %O\n",backtrace());   #endif    if(!sizeof(portalname))    unnamedportalinuse--;    PD("Close portal %s\n",portalname); -  SENDCMD(({"C",plugint32(4+1+sizeof(portalname)+1), +  _c.sendcmd(({"C",_c.plugint32(4+1+sizeof(portalname)+1),    "P",portalname,"\0"}),1);    _closesent=1;    }
1346:    array(string) from=allocate(sizeof(bindings));    array(string) to=allocate(sizeof(bindings));    foreach(bindings; mixed name; mixed value) { -  // Throws if mapping key is empty string. -  if(stringp(name)) { +  if(stringp(name)) { // Throws if mapping key is empty string    if(name[0]!=':')    name=":"+name; -  if(name[1]=='_') { -  // Special parameter +  if(name[1]=='_') { // Special option parameter +  // No options supported at the moment    continue;    }    }
1362:    }    else {    if(zero_type(value)) -  paramValues[pi++]=UNDEFINED; // NULL +  paramValues[pi++]=UNDEFINED; // NULL    else {    if(stringp(value) && String.width(value)>8)    value=string_to_utf8(value);
1398:    string oldprep=tprepared->preparedname;    if(oldprep) {    PD("Close statement %s\n",oldprep); -  plugbuf+=({"C",plugint32(4+1+sizeof(oldprep)+1), +  plugbuf+=({"C",_c.plugint32(4+1+sizeof(oldprep)+1),    "S",oldprep,"\0"});    }    m_delete(prepareds,ind);    }    }    if(sizeof(plugbuf)) -  SENDCMD(plugbuf,1); // close expireds +  _c.sendcmd(plugbuf,1); // close expireds    PD("%O\n",plugbuf);    }    prepareds[q]=tprepared=([]);    }    tstart=gethrtime(); -  } // pgsql_result autoassigns to portal +  } // pgsql_result autoassigns to portal    pgsql_result(this,tprepared,q,_fetchlimit,portalbuffersize);    if(unnamedportalinuse)    portalname=PORTALPREFIX+(string)pportalcount++;    else    unnamedportalinuse++; -  _portal->_portalname=portalname; +  _c.portal->_portalname=portalname;    qstate=inquery;    portalsinflight++;    mixed err;
1428:    // followed by a flush, it makes a VERY noticeable difference in    // performance if it is omitted; seems like a flaw in the PostgreSQL    // server -  SENDCMD(({"P",plugint32(4+sizeof(preparedname)+1+sizeof(q)+1+2), -  preparedname,"\0",q,"\0",plugint16(0)}),1); +  _c.sendcmd(({"P",_c.plugint32(4+sizeof(preparedname)+1+sizeof(q)+1+2), +  preparedname,"\0",q,"\0",_c.plugint16(0)}),1);    PD("Query: %O\n",q);    } // sends Parameter- and RowDescription for 'S' -  conn.set_read_callback(0); +  _c.set_read_callback(0);    if(!tprepared || !tprepared->datatypeoid) {    PD("Describe statement %s\n",preparedname); -  SENDCMD(({"D",plugint32(4+1+sizeof(preparedname)+1), +  _c.sendcmd(({"D",_c.plugint32(4+1+sizeof(preparedname)+1),    "S",preparedname,"\0"}),1);    }    else { -  _portal->_datatypeoid=tprepared->datatypeoid; -  _portal->_datarowdesc=tprepared->datarowdesc; +  _c.portal->_datatypeoid=tprepared->datatypeoid; +  _c.portal->_datarowdesc=tprepared->datarowdesc;    }    { array(string) plugbuf=({"B",UNDEFINED});    int len=4+sizeof(portalname)+1+sizeof(preparedname)+1    +2+sizeof(paramValues)*(2+4)+2+2;    plugbuf+=({portalname,"\0",preparedname,"\0", -  plugint16(sizeof(paramValues))}); +  _c.plugint16(sizeof(paramValues))});    if(!tprepared || !tprepared->datatypeoid) {    _decodemsg(gotparameterdescription);    if(tprepared) -  tprepared->datatypeoid=_portal->_datatypeoid; +  tprepared->datatypeoid=_c.portal->_datatypeoid;    } -  array dtoid=_portal->_datatypeoid; +  array dtoid=_c.portal->_datatypeoid;    foreach(dtoid;;int textbin) -  plugbuf+=({plugint16(oidformat(textbin))}); -  plugbuf+=({plugint16(sizeof(paramValues))}); +  plugbuf+=({_c.plugint16(oidformat(textbin))}); +  plugbuf+=({_c.plugint16(sizeof(paramValues))});    foreach(paramValues;int i;mixed value) {    if(zero_type(value)) -  plugbuf+=({plugint32(-1)}); // NULL +  plugbuf+=({_c.plugint32(-1)}); // NULL    else    switch(dtoid[i]) {    default:    { int k;    len+=k=sizeof(value=(string)value); -  plugbuf+=({plugint32(k),value}); +  plugbuf+=({_c.plugint32(k),value});    break;    } -  case BOOLOID:plugbuf+=({plugint32(1)});len++; +  case BOOLOID:plugbuf+=({_c.plugint32(1)});len++;    switch(stringp(value)?value[0]:value) {    case 'o':case 'O': -  plugbyte(stringp(value)&&sizeof(value)>1 +  _c.plugbyte(stringp(value)&&sizeof(value)>1    &&(value[1]=='n'||value[1]=='N'));    break;    case 0:case 'f':case 'F':case 'n':case 'N': -  plugbuf+=({plugbyte(0)}); +  plugbuf+=({_c.plugbyte(0)});    break;    default: -  plugbuf+=({plugbyte(1)}); +  plugbuf+=({_c.plugbyte(1)});    break;    }    break; -  case CHAROID:plugbuf+=({plugint32(1)});len++; +  case CHAROID:plugbuf+=({_c.plugint32(1)});len++;    if(intp(value)) -  plugbuf+=({plugbyte(value)}); +  plugbuf+=({_c.plugbyte(value)});    else {    value=(string)value;    if(sizeof(value)!=1)
1493:    }    break;    case INT8OID:len+=8; -  plugbuf+=({plugint32(8),plugint64((int)value)}); +  plugbuf+=({_c.plugint32(8),_c.plugint64((int)value)});    break;    case INT4OID:len+=4; -  plugbuf+=({plugint32(4),plugint32((int)value)}); +  plugbuf+=({_c.plugint32(4),_c.plugint32((int)value)});    break;    case INT2OID:len+=2; -  plugbuf+=({plugint32(2),plugint16((int)value)}); +  plugbuf+=({_c.plugint32(2),_c.plugint16((int)value)});    break;    }    }    if(!tprepared || !tprepared->datarowdesc) {    _decodemsg(gotrowdescription);    if(tprepared) -  tprepared->datarowdesc=_portal->_datarowdesc; +  tprepared->datarowdesc=_c.portal->_datarowdesc;    }    { array a;int i; -  len+=(i=sizeof(a=_portal->_datarowdesc))*2; -  plugbuf+=({plugint16(i)}); +  len+=(i=sizeof(a=_c.portal->_datarowdesc))*2; +  plugbuf+=({_c.plugint16(i)});    foreach(a;;mapping col) -  plugbuf+=({plugint16(oidformat(col->type))}); +  plugbuf+=({_c.plugint16(oidformat(col->type))});    } -  plugbuf[1]=plugint32(len); +  plugbuf[1]=_c.plugint32(len);    PD("Bind portal %s statement %s\n",portalname,preparedname); -  SENDCMD(plugbuf); +  _c.sendcmd(plugbuf);   #ifdef DEBUGMORE    PD("%O\n",plugbuf);   #endif    } -  _portal->_statuscmdcomplete=UNDEFINED; +  _c.portal->_statuscmdcomplete=UNDEFINED;    _sendexecute(_fetchlimit && FETCHLIMITLONGRUN);    if(tprepared) {    _decodemsg(bindcomplete);
1549:    backendstatus=UNDEFINED;    throw(err);    } -  { pgsql_result tportal=_portal; // Make copy, because it might dislodge -  tportal->fetch_row(1); // upon initial fetch_row() +  { pgsql_result tportal=_c.portal; // Make copy, because it might dislodge +  tportal->fetch_row(1); // upon initial fetch_row()    return tportal;    }   }
1655:   }      int num_fields() { -  return sizeof(_portal->datarowdesc); +  return sizeof(_c.portal->datarowdesc);   }      int num_rows() {
1676:    if(_pgsqlsess) {    if(copyinprogress) {    PD("CopyDone\n"); -  _pgsqlsess.SENDCMD("c\0\0\0\4",1); +  _pgsqlsess._c.sendcmd("c\0\0\0\4",1);    }    _pgsqlsess.reload(2);    }
1685:   }      void destroy() { -  catch { // inside destructors, exceptions don't work +  catch { // inside destructors, exceptions don't work    releasesession();    };   }
1698:      private void steallock() {   #ifndef NO_LOCKING -  PD("Going to steal oldportal %d\n",!!_pgsqlsess._portal); +  PD("Going to steal oldportal %d\n",!!_pgsqlsess._c.portal);    Thread.MutexKey stealmtxkey = stealmutex.lock();    do    if(_qmtxkey = querymutex.current_locking_key()) {    pgsql_result portalb; -  if(portalb=_pgsqlsess._portal) { +  if(portalb=_pgsqlsess._c.portal) {    _pgsqlsess._nextportal++;    if(portalb->_interruptable)    portalb->fetch_row(2);
1726:    PD("Skipping lock\n");    _qmtxkey=1;   #endif -  _pgsqlsess._portal=this; +  _pgsqlsess._c.setportal(this);    PD("Stealing successful\n");   }   
1740:    fetchmtxkey = UNDEFINED;    if(stringp(buffer)) {    PD("CopyData\n"); -  _pgsqlsess.SENDCMD(({"d",plugint32(4+sizeof(buffer)),buffer})); +  _pgsqlsess._c.sendcmd(({"d",_pgsqlsess._c.plugint32(4+sizeof(buffer)), +  buffer}));    }    else    releasesession();
1758:    _pgsqlsess._sendexecute(_fetchlimit);    }    while(_pgsqlsess._closesent) -  _pgsqlsess._decodemsg(); // Flush previous portal sequence +  _pgsqlsess._decodemsg(); // Flush previous portal sequence    for(;;) {   #ifdef DEBUGMORE    PD("buffer: %d nextportal: %d lock: %d\n",
1803: Inside #if STREAMEXECUTES
   }   #if STREAMEXECUTES    if(_fetchlimit && _inflight<=_fetchlimit-1) -  _pgsqlsess._sendexecute(_fetchlimit); // Overlap Executes +  _pgsqlsess._sendexecute(_fetchlimit); // Overlap Executes   #endif    return getdatarow();    case commandcomplete: