Diff for /sql/pgsql/parser3pgsql.C between versions 1.38 and 1.45

version 1.38, 2012/04/18 09:39:15 version 1.45, 2019/10/25 12:27:44
Line 1 Line 1
 /** @file  /** @file
         Parser PgSQL driver.          Parser PgSQL driver.
   
         Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com)          Copyright (c) 2001-2015 Art. Lebedev Studio (http://www.artlebedev.com)
   
         Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)          Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
   
Line 99  struct Connection { Line 99  struct Connection {
         PGconn *conn;          PGconn *conn;
         const char* client_charset;          const char* client_charset;
         bool autocommit;          bool autocommit;
         bool without_default_transactions;          bool with_default_transactions;
           bool standard_conforming_strings;
 };  };
   
 /**  /**
Line 133  public: Line 134  public:
                         ClientCharset=charset&  // transcode by parser                          ClientCharset=charset&  // transcode by parser
                         charset=value&                  // transcode by server with 'SET CLIENT_ENCODING=value'                          charset=value&                  // transcode by server with 'SET CLIENT_ENCODING=value'
                         datestyle=value&                // 'SET DATESTYLE=value' available values are: ISO|SQL|Postgres|European|US|German [default=ISO]                          datestyle=value&                // 'SET DATESTYLE=value' available values are: ISO|SQL|Postgres|European|US|German [default=ISO]
                         autocommit=1&                   // each transaction is commited automatically (default)                          autocommit=0&                   // 1 -- each statement is commited automatically, only when with_default_transaction enabled
                         WithoutDefaultTransaction=0     // 1 -- disable any BEGIN TRAN/COMMIT/ROLLBACK [can NOT be used with autocommit option]                          standard_conforming_strings=1&  // 0 -- escape \ char that could be needed for old servers
                           with_default_transaction=0      // 1 -- wrap connection into BEGIN TRAN/COMMIT/ROLLBACK
         */          */
         void connect(          void connect(
                                 char* url,                                   char* url, 
Line 153  public: Line 155  public:
                 char* datestyle=0;                  char* datestyle=0;
   
                 Connection& connection=*(Connection *)services.malloc(sizeof(Connection));                  Connection& connection=*(Connection *)services.malloc(sizeof(Connection));
   
                 *connection_ref=&connection;                  *connection_ref=&connection;
                 connection.services=&services;                  connection.services=&services;
                 connection.client_charset=0;                      connection.client_charset=0;
                 connection.autocommit=true;                  connection.autocommit=false;
                 connection.without_default_transactions=false;                  connection.with_default_transactions=false;
                   connection.standard_conforming_strings=true;
   
                 connection.conn=PQsetdbLogin(                  connection.conn=PQsetdbLogin(
                         (host&&strcasecmp(host, "local")==0)?NULL/* local Unix domain socket */:host, port,                           (host&&strcasecmp(host, "local")==0)?NULL/* local Unix domain socket */:host, port, 
Line 181  public: Line 185  public:
                                                 } else if(strcasecmp(key, "datestyle")==0){                                                  } else if(strcasecmp(key, "datestyle")==0){
                                                         datestyle=value;                                                          datestyle=value;
                                                 } else if(strcasecmp(key, "autocommit")==0){                                                  } else if(strcasecmp(key, "autocommit")==0){
                                                         if(connection.without_default_transactions)  
                                                                 services._throw("options WithoutDefaultTransaction and autocommit can't be used together");  
                                                         if(atoi(value)==0)  
                                                                 connection.autocommit=false;  
                                                 } else if(strcmp(key, "WithoutDefaultTransaction")==0){  
                                                         if(!connection.autocommit)  
                                                                 services._throw("options WithoutDefaultTransaction and autocommit can't be used together");  
                                                         if(atoi(value)==1){                                                          if(atoi(value)==1){
                                                                 connection.without_default_transactions=true;                                                                  if(!connection.with_default_transactions)
                                                                 connection.autocommit=false;                                                                          services._throw("autocommit can be used only with_default_transaction enabled");
                                                                   connection.autocommit=true;
                                                         }                                                          }
                                                   } else if(strcmp(key, "with_default_transaction")==0){
                                                           if(atoi(value)==1)
                                                                   connection.with_default_transactions=true;
                                                   } else if(strcmp(key, "WithoutDefaultTransaction")==0){
                                                           if(atoi(value)==0)
                                                                   connection.with_default_transactions=true;
                                                   } else if(strcasecmp(key, "standard_conforming_strings")==0){
                                                           if(atoi(value)==0)
                                                                   connection.standard_conforming_strings=false;
                                                 } else                                                  } else
                                                         services._throw("unknown connect option" /*key*/);                                                          services._throw("unknown connect option" /*key*/);
                                         } else                                           } else 
Line 201  public: Line 208  public:
                 }                  }
   
                 if(charset){                  if(charset){
                         char statement[MAX_STRING]="SET CLIENT_ENCODING=";                          char statement[MAX_STRING+1]="SET CLIENT_ENCODING=";
                         strncat(statement, charset, MAX_STRING);                          strncat(statement, charset, MAX_STRING);
   
                         _execute_cmd(connection, statement);                          _execute_cmd(connection, statement);
                 }                  }
   
                 if(datestyle){                  if(datestyle){
                         char statement[MAX_STRING]="SET DATESTYLE=";                          char statement[MAX_STRING+1]="SET DATESTYLE=";
                         strncat(statement, datestyle, MAX_STRING);                          strncat(statement, datestyle, MAX_STRING);
   
                         _execute_cmd(connection, statement);                          _execute_cmd(connection, statement);
Line 244  public: Line 251  public:
         // thus we can't use the sql server quoting support          // thus we can't use the sql server quoting support
         const char* quote(void *aconnection, const char *str, unsigned int length)           const char* quote(void *aconnection, const char *str, unsigned int length) 
         {          {
                   Connection& connection=*static_cast<Connection*>(aconnection);
   
                 const char* from;                  const char* from;
                 const char* from_end=str+length;                  const char* from_end=str+length;
   
                 size_t quoted=0;                  size_t quoted=0;
   
                 for(from=str; from<from_end; from++){                  if(connection.standard_conforming_strings){
                         switch (*from) {                          for(from=str; from<from_end; from++){
                         case '\'':                                  if(*from=='\'')
                         case '\\':                                          quoted++;
                                 quoted++;                          }
                   } else {
                           for(from=str; from<from_end; from++){
                                   switch (*from) {
                                   case '\'':
                                   case '\\':
                                           quoted++;
                                   }
                         }                          }
                 }                  }
   
                 if(!quoted)                  if(!quoted)
                         return str;                          return str;
   
                 Connection& connection=*static_cast<Connection*>(aconnection);  
                 char *result=(char*)connection.services->malloc_atomic(length + quoted + 1);                  char *result=(char*)connection.services->malloc_atomic(length + quoted + 1);
                 char *to = result;                  char *to = result;
   
                 for(from=str; from<from_end; from++){                  if(connection.standard_conforming_strings){
                         switch (*from) {                          for(from=str; from<from_end; from++){
                         case '\'': // "'" -> "''"                                  if(*from=='\'')
                                 *to++='\'';                                          *to++= '\''; // "'" -> "''"
                                 break;                                  *to++=*from;
                         case '\\': // "\" -> "\\"                          }
                                 *to++='\\';                  } else {
                                 break;                          for(from=str; from<from_end; from++){
                                   switch (*from) {
                                   case '\'': // "'" -> "''"
                                           *to++= '\'';
                                           break;
                                   case '\\': // "\" -> "\\"
                                           *to++='\\';
                                           break;
                                   }
                                   *to++=*from;
                         }                          }
                         *to++=*from;  
                 }                  }
                                   
                 *to=0;                  *to=0;
Line 512  private: Line 535  private:
         }          }
   
         void _execute_transactions_cmd(const Connection& connection, const char *query){          void _execute_transactions_cmd(const Connection& connection, const char *query){
                 if(!connection.without_default_transactions) // with option ?WithoutDefaultTransaction=1 user must execute BEGIN/COMMIT/ROLLBACK by himself                  if(connection.with_default_transactions) // without ?with_default_transaction=1 user must execute BEGIN/COMMIT/ROLLBACK by himself
                         _execute_cmd(connection, query);                          _execute_cmd(connection, query);
         }          }
   
Line 546  private: Line 569  private:
                         char *cur=result;                          char *cur=result;
                         memcpy(cur, astatement, statement_size); cur+=statement_size;                          memcpy(cur, astatement, statement_size); cur+=statement_size;
                         if(limit!=SQL_NO_LIMIT)                          if(limit!=SQL_NO_LIMIT)
                                 cur+=snprintf(cur, 7+MAX_NUMBER, " limit %u", limit);                                  cur+=snprintf(cur, 7+MAX_NUMBER, " limit %lu", limit);
                         if(offset)                          if(offset)
                                 cur+=snprintf(cur, 8+MAX_NUMBER, " offset %u", offset);                                  cur+=snprintf(cur, 8+MAX_NUMBER, " offset %lu", offset);
                         o=result;                          o=result;
                 } else                   } else 
                         o=astatement;                          o=astatement;
Line 689  private: // conn client library funcs Line 712  private: // conn client library funcs
 private: // conn client library funcs linking  private: // conn client library funcs linking
   
         const char *dlink(const char *dlopen_file_spec) {          const char *dlink(const char *dlopen_file_spec) {
                 if(lt_dlinit())                  if(lt_dlinit()){
                         return lt_dlerror();                          if(const char* result=lt_dlerror())
                                   return result;
                           return "can not prepare to dynamic loading";
                   }
   
                 lt_dlhandle handle=lt_dlopen(dlopen_file_spec);                  lt_dlhandle handle=lt_dlopen(dlopen_file_spec);
                 if(!handle)  
                   if(!handle){
                           if(const char* result=lt_dlerror())
                                   return result;
                         return "can not open the dynamic link module";                          return "can not open the dynamic link module";
                   }
   
                 #define DSLINK(name, action) \                  #define DSLINK(name, action) \
                         name=(t_##name)lt_dlsym(handle, #name); \                          name=(t_##name)lt_dlsym(handle, #name); \

Removed from v.1.38  
changed lines
  Added in v.1.45


E-mail: