Diff for /sql/pgsql/parser3pgsql.C between versions 1.24 and 1.26

version 1.24, 2004/12/23 16:18:21 version 1.26, 2007/01/26 10:10:32
Line 22  static const char *RCSId="$Id$"; Line 22  static const char *RCSId="$Id$";
 // actually writing chunks of that size failed, reduced it twice  // actually writing chunks of that size failed, reduced it twice
 #define LO_BUFSIZE                0x1000  #define LO_BUFSIZE                0x1000
 // from postgres_ext.h  // from postgres_ext.h
 #define InvalidOid              ((Oid) 0)  //#define InvalidOid            ((Oid) 0)
   
   
 #include "ltdl.h"  #include "ltdl.h"
Line 58  static char *lsplit(char **string_ref, c Line 58  static char *lsplit(char **string_ref, c
     return result;      return result;
 }  }
   
   static char* rsplit(char* string, char delim) {
       if(string) {
                   char* v=strrchr(string, delim); 
                   if(v) {
                           *v=0;
                           return v+1;
                   }
       }
       return NULL;        
   }
   
 static void toupper_str(char *out, const char *in, size_t size) {  static void toupper_str(char *out, const char *in, size_t size) {
         while(size--)          while(size--)
                 *out++=(char)toupper(*in++);                  *out++=(char)toupper(*in++);
Line 104  public: Line 115  public:
                 void **connection_ref ///< output: Connection*                  void **connection_ref ///< output: Connection*
                 ) {                  ) {
                 char *user=url;                  char *user=url;
                 char *host=lsplit(user, '@');                  char *host=rsplit(user, '@');
                 char *db=lsplit(host, '/');                  char *db=lsplit(host, '/');
                 char *pwd=lsplit(user, ':');                  char *pwd=lsplit(user, ':');
                 char *port=lsplit(host, ':');                  char *port=lsplit(host, ':');
Line 141  public: Line 152  public:
                                                 } else if(strcasecmp(key, "datestyle")==0) {                                                  } else if(strcasecmp(key, "datestyle")==0) {
                                                         datestyle=value;                                                          datestyle=value;
                                                 } else if(strcmp(key, "WithoutDefaultTransaction")==0) {                                                  } else if(strcmp(key, "WithoutDefaultTransaction")==0) {
                                                         isDefaultTransaction = false;                                                          if(strcmp(value, "1" ) == 0) {
                                                                   isDefaultTransaction = false;
                                                           } else if(strcmp(value, "0" ) == 0) {
                                                                   isDefaultTransaction = true;
                                                           } else {
                                                                   services._throw("Bad WithoutDefaultTransaction option value. Only 0 or 1 are accepted." /*value*/);
                                                           }
                                                 } else                                                  } else
                                                         services._throw("unknown connect option" /*key*/);                                                          services._throw("unknown connect option" /*key*/);
                                         } else                                           } else 
Line 158  public: Line 175  public:
                         // set CLIENT_ENCODING                          // set CLIENT_ENCODING
                         char statement[MAX_STRING]="set CLIENT_ENCODING="; // win                          char statement[MAX_STRING]="set CLIENT_ENCODING="; // win
                         strncat(statement, cstrBackwardCompAskServerToTranscode, MAX_STRING);                          strncat(statement, cstrBackwardCompAskServerToTranscode, MAX_STRING);
                           
                         PGresult *res=PQexec(connection.conn, statement);                          execute_resultless(connection, statement);
                         if(!res)   
                                 throwPQerror;  
                         PQclear(res); // throw out the result [don't need but must call]  
                 }                  }
   
                 if(datestyle) {                  if(datestyle) {
                         // set DATESTYLE                          // set DATESTYLE
                         char statement[MAX_STRING]="set DATESTYLE="; // ISO,SQL,Postgres,European,NonEuropean=US,German,DEFAULT=ISO                          char statement[MAX_STRING]="set DATESTYLE="; // ISO,SQL,Postgres,European,NonEuropean=US,German,DEFAULT=ISO
                         strncat(statement, charset, MAX_STRING);                          strncat(statement, charset, MAX_STRING);
                           
                         PGresult *res=PQexec(connection.conn, statement);                          execute_resultless(connection, statement);
                         if(!res)   
                                 throwPQerror;  
                         PQclear(res); // throw out the result [don't need but must call]  
                 }                  }
   
                 begin_transaction(connection);                  begin_transaction(connection);
Line 185  public: Line 196  public:
                 connection.conn=0;                  connection.conn=0;
         }          }
         void commit(void *aconnection) {          void commit(void *aconnection) {
                 if(isDefaultTransaction)                  execute_transaction_cmd(aconnection, "COMMIT");
                 {  
                         Connection& connection=*static_cast<Connection*>(aconnection);  
   
                         if(PGresult *res=PQexec(connection.conn, "COMMIT"))  
                                 PQclear(res);  
                         else  
                                 throwPQerror;  
                         begin_transaction(connection);  
                 }  
         }          }
         void rollback(void *aconnection) {          void rollback(void *aconnection) {
                 if(isDefaultTransaction)                  execute_transaction_cmd(aconnection, "ROLLBACK");
                 {  
                         Connection& connection=*static_cast<Connection*>(aconnection);  
   
                         if(PGresult *res=PQexec(connection.conn, "ROLLBACK"))  
                                 PQclear(res);  
                         else  
                                 throwPQerror;  
                         begin_transaction(connection);  
                 }  
         }          }
   
         bool ping(void *aconnection) {          bool ping(void *aconnection) {
Line 221  public: Line 214  public:
                 Connection& connection=*static_cast<Connection*>(aconnection);                  Connection& connection=*static_cast<Connection*>(aconnection);
   
                 char *result=(char*)connection.services->malloc_atomic(length*2+1);                  char *result=(char*)connection.services->malloc_atomic(length*2+1);
                 char *to=result;                  int err = 0;
                 while(length--) {                  PQescapeStringConn (connection.conn,
                         switch(*from) {                             result, from, length,
                         case '\'': // "'" -> "''"                             &err);
                                 *to++='\'';  
                                 break;  
                         case '\\': // "\" -> "\\"  
                                 *to++='\\';  
                                 break;  
                         }  
                         *to++=*from++;  
                 }  
                 *to=0;  
                 return result;                  return result;
                 }          }
           
         void query(void *aconnection,           void query(void *aconnection, 
                 const char *astatement,                   const char *astatement, 
                 size_t placeholders_count, Placeholder* placeholders,                   size_t placeholders_count, Placeholder* placeholders, 
Line 247  public: Line 232  public:
                 SQL_Driver_services& services=*connection.services;                  SQL_Driver_services& services=*connection.services;
                 PGconn *conn=connection.conn;                  PGconn *conn=connection.conn;
   
                 if(placeholders_count>0)                  const char** paramValues;
                         services._throw("bind variables not supported (yet)");                  if(placeholders_count>0){
                           //services._throw("bind variables not supported (yet)");
                           int binds_size=sizeof(char) * placeholders_count;
                           paramValues = static_cast<const char**>(services.malloc_atomic(binds_size));
                           for(size_t i=0; i<placeholders_count; ++i) {
                                   Placeholder& ph=placeholders[i];
                                   size_t value_length;
                                   if(cstrClientCharset) {
                                           size_t name_length;
                                           services.transcode(ph.name, strlen(ph.name),
                                                   ph.name, name_length,
                                                   services.request_charset(),
                                                   cstrClientCharset);
   
                                           if(ph.value){
                                                   services.transcode(ph.value, strlen(ph.value),
                                                           ph.value, value_length,
                                                           services.request_charset(),
                                                           cstrClientCharset);
                                           }
                                   } else {
                                           value_length=ph.value? strlen(ph.value): 0;
                                   }
                                   if( atoi(ph.name) <= 0 || atoi(ph.name) > placeholders_count) {
                                           services._throw("bad bind parameter key");
                                   }
                                   paramValues[atoi(ph.name)-1] = ph.value;
                           }
                   }
   
                 // transcode from $request:charset to connect-string?client_charset                  // transcode from $request:charset to connect-string?client_charset
                 if(cstrClientCharset) {                  if(cstrClientCharset) {
Line 262  public: Line 275  public:
                 const char *statement=preprocess_statement(connection,                  const char *statement=preprocess_statement(connection,
                         astatement, offset, limit);                          astatement, offset, limit);
   
                 PGresult *res=PQexec(conn, statement);                  PGresult *res;
                   if(placeholders_count>0){
                           res=PQexecParams(conn, statement, placeholders_count, NULL, paramValues, NULL, NULL, 0);
                   } else {
                           res=PQexec(conn, statement);
                   }
                 if(!res)                   if(!res) 
                         throwPQerror;                          throwPQerror;
   
Line 381  cleanup: Line 399  cleanup:
   
 private: // private funcs  private: // private funcs
   
           void execute_transaction_cmd(void *aconnection, const char *query) {
                   if(isDefaultTransaction)
                   {
                           Connection& connection=*static_cast<Connection*>(aconnection);
                           execute_resultless(connection, query);
                           begin_transaction(connection);
                   }
           }
           
           /**
                   Executes a query and throws the result.
           */
           void execute_resultless(const Connection& connection, const char *query) {
                   if(PGresult *res=PQexec(connection.conn, query))
                           PQclear(res); // throw out the result [don't need but must call]
                   else
                           throwPQerror;
           }
   
         void begin_transaction(Connection& connection) {          void begin_transaction(Connection& connection) {
                 if(isDefaultTransaction)                  if(isDefaultTransaction)
                 {                  {
                         if(PGresult *res=PQexec(connection.conn, "BEGIN"))                          execute_resultless(connection, "BEGIN");
                                 PQclear(res);  
                         else  
                                 throwPQerror;  
                 }                  }
         }          }
   
Line 476  private: // private funcs Line 510  private: // private funcs
 private: // lo_read/write exchancements  private: // lo_read/write exchancements
   
         bool lo_read_ex(PGconn *conn, int fd, const/*paf*/ char *buf, size_t len) {          bool lo_read_ex(PGconn *conn, int fd, const/*paf*/ char *buf, size_t len) {
                 int size_read;                  return lo_rw_method (conn, fd, buf, len, lo_read);
                 while(len && (size_read=lo_read(conn, fd, buf, min(LO_BUFSIZE, len)))>0) {  
                         buf+=size_read;  
                         len-=size_read;                                                                   
                 }  
                 return len==0;  
         }          }
   
         bool lo_write_ex(PGconn *conn, int fd, const/*paf*/ char *buf, size_t len) {          bool lo_write_ex(PGconn *conn, int fd, const/*paf*/ char *buf, size_t len) {
                 int size_written;                  return lo_rw_method (conn, fd, buf, len, lo_write);
                 while(len && (size_written=lo_write(conn, fd, buf, min(LO_BUFSIZE, len)))>0) {          }
                         buf+=size_written;  
                         len-=size_written;                                                                                bool lo_rw_method(PGconn *conn, int fd, const/*paf*/ char *buf, size_t len, int (*lo_func)(PGconn *conn, int fd, const/*paf*/ char *buf, size_t len)) {
                   int size_op;
                   while(len && (size_op=lo_func(conn, fd, buf, min(LO_BUFSIZE, len)))>0) {
                           buf+=size_op;
                           len-=size_op;                                                                   
                 }                  }
                 return len==0;                  return len==0;
         }          }
Line 508  private: // conn client library funcs Line 541  private: // conn client library funcs
         typedef ConnStatusType (*t_PQstatus)(const PGconn *conn); t_PQstatus PQstatus;          typedef ConnStatusType (*t_PQstatus)(const PGconn *conn); t_PQstatus PQstatus;
         typedef PGresult *(*t_PQexec)(PGconn *conn,          typedef PGresult *(*t_PQexec)(PGconn *conn,
                          const char *query); t_PQexec PQexec;                           const char *query); t_PQexec PQexec;
   //PQexecParams
           typedef PGresult *(*t_PQexecParams)(
                                              PGconn *conn,
                                              const char *query, 
                                              int nParams,
                          const Oid *paramTypes,
                          const char * const *paramValues,
                          const int *paramLengths,
                          const int *paramFormats,
                          int resultFormat); t_PQexecParams PQexecParams;
   
         typedef ExecStatusType (*t_PQresultStatus)(const PGresult *res); t_PQresultStatus PQresultStatus;          typedef ExecStatusType (*t_PQresultStatus)(const PGresult *res); t_PQresultStatus PQresultStatus;
         typedef int (*t_PQgetlength)(const PGresult *res,          typedef int (*t_PQgetlength)(const PGresult *res,
                                         int tup_num,                                          int tup_num,
Line 523  private: // conn client library funcs Line 567  private: // conn client library funcs
   
         typedef Oid     (*t_PQftype)(const PGresult *res, int field_num); t_PQftype PQftype;          typedef Oid     (*t_PQftype)(const PGresult *res, int field_num); t_PQftype PQftype;
   
           typedef size_t (*t_PQescapeStringConn)(PGconn *conn,
                              char *to, const char *from, size_t length,
                              int *error); t_PQescapeStringConn PQescapeStringConn;
   
         typedef int     (*t_lo_open)(PGconn *conn, Oid lobjId, int mode); t_lo_open lo_open;          typedef int     (*t_lo_open)(PGconn *conn, Oid lobjId, int mode); t_lo_open lo_open;
         typedef int     (*t_lo_close)(PGconn *conn, int fd); t_lo_close lo_close;          typedef int     (*t_lo_close)(PGconn *conn, int fd); t_lo_close lo_close;
         typedef int     (*t_lo_read)(PGconn *conn, int fd, const/*paf*/ char *buf, size_t len); t_lo_read lo_read;          typedef int     (*t_lo_read)(PGconn *conn, int fd, const/*paf*/ char *buf, size_t len); t_lo_read lo_read;
Line 562  private: // conn client library funcs li Line 610  private: // conn client library funcs li
                 DLINK(PQclear);                  DLINK(PQclear);
                 DLINK(PQresultStatus);                  DLINK(PQresultStatus);
                 DLINK(PQexec);                  DLINK(PQexec);
                   DLINK(PQexecParams);
                 DLINK(PQftype);                  DLINK(PQftype);
                   DLINK(PQescapeStringConn);
                 DLINK(lo_open);         DLINK(lo_close);                  DLINK(lo_open);         DLINK(lo_close);
                 DLINK(lo_read);         DLINK(lo_write);                  DLINK(lo_read);         DLINK(lo_write);
                 DLINK(lo_lseek);                DLINK(lo_creat);                  DLINK(lo_lseek);                DLINK(lo_creat);

Removed from v.1.24  
changed lines
  Added in v.1.26


E-mail: