Diff for /sql/oracle/parser3oracle.C between versions 1.54 and 1.60

version 1.54, 2004/03/26 13:26:41 version 1.60, 2004/06/18 15:55:52
Line 83  static int pa_setenv(const char *name, c Line 83  static int pa_setenv(const char *name, c
                         strcat(buf, value);                          strcat(buf, value);
                         value=buf;                          value=buf;
                 }                  }
   
                 return setenv(name, value, 1/*overwrite*/);                   return setenv(name, value, 1/*overwrite*/); 
         } else {          } else {
                 unsetenv(name);                  unsetenv(name);
Line 130  struct Connection { Line 129  struct Connection {
         } options;          } options;
 };  };
   
 struct OracleSQL_query_lobs {  struct Query_lobs {
         struct return_rows {          struct return_rows {
                 struct return_row {                  struct return_row {
                         OCILobLocator *locator; ub4 len;                          OCILobLocator *locator; ub4 len;
Line 139  struct OracleSQL_query_lobs { Line 138  struct OracleSQL_query_lobs {
                 } *row;                  } *row;
                 int count;                  int count;
         };          };
         struct cbf_context_struct {  
                 Connection *connection;  
                 return_rows *rows;  
         };  
         struct Item {          struct Item {
                 const char *name_ptr; size_t name_size;                  const char *name_ptr; size_t name_size;
                 char *data_ptr; size_t data_size;                  char *data_ptr; size_t data_size;
                 OCILobLocator *locator;                  OCILobLocator *locator;
                 OCIBind *bind;                  OCIBind *bind;
                 return_rows rows;                  return_rows rows;
                   Connection *connection;
         } items[MAX_IN_LOBS];          } items[MAX_IN_LOBS];
         int count;          int count;
 };  };
   
 #endif  #endif
   
 // forwards  // forwards
 void check(Connection& connection, const char *step, sword status);  static void faile(Connection& connection, const char *msg);
 void check(Connection& connection, bool error);  static void check(Connection& connection, const char *step, sword status);
   static void check(Connection& connection, bool error);
 static sb4 cbf_no_data(  static sb4 cbf_no_data(
                                            dvoid *ctxp,                                              dvoid *ctxp, 
                                            OCIBind *bindp,                                              OCIBind *bindp, 
Line 173  static sb4 cbf_get_data(dvoid *ctxp, Line 171  static sb4 cbf_get_data(dvoid *ctxp,
                                                 ub1 *piecep,                                                   ub1 *piecep, 
                                                 dvoid **indpp,                                                   dvoid **indpp, 
                                                 ub2 **rcodepp);                                                  ub2 **rcodepp);
 static void tolower(char *out, const char *in, size_t size);  static void tolower_str(char *out, const char *in, size_t size);
 static void toupper(char *out, const char *in, size_t size);  static void toupper_str(char *out, const char *in, size_t size);
   
 static const char *options2env(char *s, Connection::Options* options) {  static const char *options2env(char *s, Connection::Options* options) {
         while(s) {          while(s) {
Line 183  static const char *options2env(char *s, Line 181  static const char *options2env(char *s,
                                 if(char *value=lsplit(key, '=')) {                                  if(char *value=lsplit(key, '=')) {
                                         if( strcmp( key, "ClientCharset" ) == 0 ) {                                          if( strcmp( key, "ClientCharset" ) == 0 ) {
                                                 if(options) {                                                  if(options) {
                                                         toupper(value, value, strlen(value));                                                          toupper_str(value, value, strlen(value));
                                                         options->cstrClientCharset = value;                                                          options->cstrClientCharset = value;
                                                 }                                                  }
                                                 continue;                                                  continue;
Line 249  public: Line 247  public:
         }          }
   
         /**     connect          /**     connect
                 @param used_only_in_connect_url                  @param url
                         format: @b user:pass@service?                          format: @b user:pass@service?
                            ORACLE_HOME=/u01/app/oracle/product/8.1.5&                             ORACLE_HOME=/u01/app/oracle/product/8.1.5&
                            ORA_NLS33=/u01/app/oracle/product/8.1.5/ocommon/nls/admin/data&                             ORA_NLS33=/u01/app/oracle/product/8.1.5/ocommon/nls/admin/data&
Line 257  public: Line 255  public:
                            ORA_ENCRYPT_LOGIN=TRUE                             ORA_ENCRYPT_LOGIN=TRUE
   
                 @todo environment manupulation doesnt look thread safe                  @todo environment manupulation doesnt look thread safe
                   @todo allocate 'aused_only_in_connect_url' on gc heap, so it can be manipulated directly
         */          */
         void connect(          void connect(
                 char *used_only_in_connect_url,                   char *url, 
                 SQL_Driver_services& services,                   SQL_Driver_services& services, 
                 void **connection_ref ///< output: Connection *                  void **connection_ref ///< output: Connection *
                 ) {                  ) 
           {
                   // connections are cross-request, do not use services._alloc [linked with request]
                 Connection& connection=*(Connection  *)services.malloc(sizeof(Connection));                  Connection& connection=*(Connection  *)services.malloc(sizeof(Connection));
                 connection.services=&services;                  connection.services=&services;
                 connection.options.bLowerCaseColumnNames = true;                  connection.options.bLowerCaseColumnNames = true;
                 *connection_ref=&connection;                  *connection_ref=&connection;
   
                 char *user=used_only_in_connect_url;                  char *user=url;
                 char *service=lsplit(user, '@');                  char *service=lsplit(user, '@');
                 char *pwd=lsplit(user, ':');                  char *pwd=lsplit(user, ':');
                 char *options=lsplit(service, '?');                  char *options=lsplit(service, '?');
Line 345  public: Line 346  public:
         void disconnect(void *aconnection) {          void disconnect(void *aconnection) {
             Connection& connection=*static_cast<Connection *>(aconnection);              Connection& connection=*static_cast<Connection *>(aconnection);
   
                 // free fetch buffers                  // free fetch buffers. leave that to GC [no such services func. yet?]
                   /*
                 for(int i=0; i<MAX_COLS; i++) {                  for(int i=0; i<MAX_COLS; i++) {
                         if(void* fetch_buffer=connection.fetch_buffers[i])                          if(void* fetch_buffer=connection.fetch_buffers[i])
                                 ::free(fetch_buffer);                                  connection.services->free(fetch_buffer);
                         else                          else
                                 break;                                  break;
                 }                                         }
                   */
   
                 // Terminate a user session                  // Terminate a user session
                 OCISessionEnd(                  OCISessionEnd(
Line 372  public: Line 375  public:
                 OCIHandleFree(                  OCIHandleFree(
                         (dvoid *)connection.envhp, (ub4)OCI_HTYPE_ENV);                          (dvoid *)connection.envhp, (ub4)OCI_HTYPE_ENV);
   
                 // connections are cross-request, do not use services._alloc [linked with request]                  // free connection. leave that to GC [no such services func. yet?]
                 ::free(&connection);                  // connection.services->free(&connection);
         }          }
         void commit(void *aconnection) {          void commit(void *aconnection) {
             Connection& connection=*static_cast<Connection *>(aconnection);              Connection& connection=*static_cast<Connection *>(aconnection);
Line 415  public: Line 418  public:
                 *to=0;                  *to=0;
                 return result;                  return result;
         }          }
         void query(void *aconnection,           void query(void* aconnection, 
                 const char *astatement, unsigned long offset, unsigned long limit,                   const char* astatement, 
                   size_t placeholders_count, Placeholder* placeholders, 
                   unsigned long offset, unsigned long limit,
                 SQL_Driver_query_event_handlers& handlers)                   SQL_Driver_query_event_handlers& handlers) 
         {          {
                 Connection& connection=*static_cast<Connection *>(aconnection);                  Connection& connection=*static_cast<Connection *>(aconnection);
                 const char* cstrClientCharset=connection.options.cstrClientCharset;                  const char* cstrClientCharset=connection.options.cstrClientCharset;
                 OracleSQL_query_lobs lobs={{0}, 0};                  Query_lobs lobs={{0}, 0};
                 OCIStmt *stmthp=0;                  OCIStmt *stmthp=0;
   
                 SQL_Driver_services& services=*connection.services;                  SQL_Driver_services& services=*connection.services;
   
                 // transcode from $request:charset to connect-string?client_charset                  // transcode from $request:charset to connect-string?client_charset
                 if(cstrClientCharset) {                  if(cstrClientCharset) {
                         size_t transcoded_statement_size;                          size_t transcoded_xxx_size;
                         services.transcode(astatement, strlen(astatement),                          services.transcode(astatement, strlen(astatement),
                                 astatement, transcoded_statement_size,                                  astatement, transcoded_xxx_size,
                                 services.request_charset(),                                  services.request_charset(),
                                 cstrClientCharset);                                  cstrClientCharset);
                 }                  }
Line 448  public: Line 453  public:
                                 OCIStmtPrepare(stmthp, connection.errhp, (unsigned char *)statement,                                   OCIStmtPrepare(stmthp, connection.errhp, (unsigned char *)statement, 
                                 (ub4)strlen((char *)statement),                                   (ub4)strlen((char *)statement), 
                                 (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));                                  (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT));
   
                           struct Bind_info {
                                           OCIBind *bind;
                                           sb2 indicator;
                           };
   
                           int binds_size=sizeof(Bind_info) * placeholders_count;
                           Bind_info* binds=static_cast<Bind_info*>(services.malloc_atomic(binds_size));
                         {                          {
                                   for(size_t i=0; i<placeholders_count; i++) {
                                           Placeholder& ph=placeholders[i];
                                           Bind_info& bi=binds[i];
                                           bi.bind=0;
                                           bi.indicator=ph.is_null? -1: 0/*9999*/;
   
                                           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;
                                           }
   
                                           char placeholder_buf[MAX_STRING];
                                           sb4 placeh_len=snprintf(placeholder_buf, sizeof(placeholder_buf), ":%s", ph.name);
                                           check(connection, "bind name", OCIBindByName(stmthp, 
                                                   &bi.bind, connection.errhp, 
                                                   (text*)placeholder_buf, placeh_len,
                                                   (dvoid *)ph.value, (sword)value_length, SQLT_CHR/*SQLT_STR*/, (dvoid *)&bi.indicator, 
                                                   (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DEFAULT));
                                   }
   
                                 for(int i=0; i<lobs.count; i++) {                                  for(int i=0; i<lobs.count; i++) {
                                           Query_lobs::Item &item=lobs.items[i];
                                         check(connection, "alloc output var desc", OCIDescriptorAlloc(                                          check(connection, "alloc output var desc", OCIDescriptorAlloc(
                                                 (dvoid *)connection.envhp, (dvoid **)&lobs.items[i].locator, (ub4)OCI_DTYPE_LOB, 0, 0));                                                  (dvoid *)connection.envhp, (dvoid **)&item.locator, (ub4)OCI_DTYPE_LOB, 0, 0));
   
                                         check(connection, "bind output", OCIBindByPos(stmthp,                                           char placeholder_buf[MAX_STRING];
                                                 &lobs.items[i].bind, connection.errhp,                                           sb4 placeh_len=snprintf(placeholder_buf, sizeof(placeholder_buf), 
                                                 (ub4)1+i,                                                   ":%.*s", item.name_size, item.name_ptr);
                                                 (dvoid *)&lobs.items[i].locator,                                           check(connection, "bind lob", OCIBindByName(stmthp, 
                                                 (sword)sizeof (lobs.items[i].locator), SQLT_CLOB, (dvoid *)0,                                                   &item.bind, connection.errhp, 
                                                   (text*)placeholder_buf, placeh_len,
                                                   (dvoid *)&item.locator, 
                                                   (sword)sizeof (item.locator), SQLT_CLOB, (dvoid *)0, 
                                                 (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DATA_AT_EXEC));                                                  (ub2 *)0, (ub2 *)0, (ub4)0, (ub4 *)0, OCI_DATA_AT_EXEC));
   
                                         lobs.items[i].rows.count=0;                                          item.rows.count=0;
                                         OracleSQL_query_lobs::cbf_context_struct cbf_context={&connection, &lobs.items[i].rows};                                          item.connection=&connection;
                                         check(connection, "bind dynamic", OCIBindDynamic(                                          check(connection, "bind dynamic", OCIBindDynamic(
                                                 lobs.items[i].bind, connection.errhp,                                                   item.bind, connection.errhp, 
                                                 (dvoid *) &cbf_context, cbf_no_data,                                                   (dvoid *) &item, cbf_no_data, 
                                                 (dvoid *) &cbf_context, cbf_get_data));                                                  (dvoid *) &item, cbf_get_data));
                                 }                                  }
                         }                          }
   
                         execute_prepared(connection,                           execute_prepared(connection, 
                                 statement, stmthp, lobs,                                   statement, stmthp, lobs, 
                                 offset, limit, handlers);                                  offset, limit, handlers);
   
                           {
                                   for(size_t i=0; i<placeholders_count; i++) {
                                           Placeholder& ph=placeholders[i];
                                           Bind_info& bi=binds[i];
   
                                           if(bi.indicator==9999 /*unchanged*/)
                                                   continue;
   
                                           if(bi.indicator==-1)
                                                   ph.is_null=true;
                                           else
                                                   if(bi.indicator==0)
                                                           ph.is_null=false;
                                                   else
                                                           fail(connection, bi.indicator<0?
                                                                   "column return buffer overflow, additionally size too big to be returned in 'indicator'"
                                                                   : "column return buffer overflow");
   
                                           ph.were_updated=true;
   
                                           if(cstrClientCharset) {
                                                   if(ph.value) {
                                                           size_t value_length;
                                                           services.transcode(ph.value, strlen(ph.value),
                                                                   ph.value, value_length,
                                                                   cstrClientCharset,
                                                                   services.request_charset());
                                                   }
                                           }
                                   }
                           }
                 }                  }
 cleanup: // no check call after this point!  cleanup: // no check call after this point!
                 {                  {
Line 481  cleanup: // no check call after this poi Line 563  cleanup: // no check call after this poi
                                         OCIDescriptorFree((dvoid *)locator, (ub4)OCI_DTYPE_LOB);                                          OCIDescriptorFree((dvoid *)locator, (ub4)OCI_DTYPE_LOB);
   
                                 /* free rows descriptors */                                  /* free rows descriptors */
                                 OracleSQL_query_lobs::return_rows &rows=lobs.items[i].rows;                                  Query_lobs::return_rows &rows=lobs.items[i].rows;
                                 for(int r=0; r<rows.count; r++)                                  for(int r=0; r<rows.count; r++)
                                         OCIDescriptorFree((dvoid *)rows.row[r].locator, (ub4)OCI_DTYPE_LOB);                                          OCIDescriptorFree((dvoid *)rows.row[r].locator, (ub4)OCI_DTYPE_LOB);
                         }                          }
Line 499  cleanup: // no check call after this poi Line 581  cleanup: // no check call after this poi
 private: // private funcs  private: // private funcs
   
         const char *preprocess_statement(Connection& connection,           const char *preprocess_statement(Connection& connection, 
                 const char *astatement, OracleSQL_query_lobs &lobs) {                  const char *astatement, Query_lobs &lobs) {
                 size_t statement_size=strlen(astatement);                  size_t statement_size=strlen(astatement);
                 SQL_Driver_services& services=*connection.services;                  SQL_Driver_services& services=*connection.services;
   
Line 528  private: // private funcs Line 610  private: // private funcs
                                                 saved_o=0; // found, marking that                                                  saved_o=0; // found, marking that
                                                 const char *name_end=o;                                                  const char *name_end=o;
                                                 o+=4;                                                  o+=4;
                                                 OracleSQL_query_lobs::Item &item=lobs.items[lobs.count++];                                                  Query_lobs::Item &item=lobs.items[lobs.count++];
                                                 item.name_ptr=name_begin; item.name_size=name_end-name_begin;                                                  item.name_ptr=name_begin; item.name_size=name_end-name_begin;
                                                 item.data_ptr=(char *)services.malloc_atomic(statement_size/*max*/); item.data_size=0;                                                  item.data_ptr=(char *)services.malloc_atomic(statement_size/*max*/); item.data_size=0;
   
Line 587  private: // private funcs Line 669  private: // private funcs
   
         void execute_prepared(          void execute_prepared(
                 Connection& connection,                   Connection& connection, 
                 const char *statement, OCIStmt *stmthp, OracleSQL_query_lobs &lobs,                   const char *statement, OCIStmt *stmthp, Query_lobs &lobs, 
                 unsigned long offset, unsigned long limit,                   unsigned long offset, unsigned long limit, 
                 SQL_Driver_query_event_handlers& handlers) {                  SQL_Driver_query_event_handlers& handlers) {
   
Line 620  private: // private funcs Line 702  private: // private funcs
                 {                  {
                         for(int i=0; i<lobs.count; i++)                           for(int i=0; i<lobs.count; i++) 
                                 if(ub4 bytes_to_write=lobs.items[i].data_size) {                                  if(ub4 bytes_to_write=lobs.items[i].data_size) {
                                         OracleSQL_query_lobs::return_rows *rows=&lobs.items[i].rows;                                          Query_lobs::return_rows *rows=&lobs.items[i].rows;
                                         for(int r=0; r<rows->count; r++) {                                          for(int r=0; r<rows->count; r++) {
                                                 OCILobLocator *locator=rows->row[r].locator;                                                  OCILobLocator *locator=rows->row[r].locator;
                                                 check(connection, "lobwrite", OCILobWrite (                                                  check(connection, "lobwrite", OCILobWrite (
Line 720  private: // private funcs Line 802  private: // private funcs
                                         size_t length=(size_t)col_name_len;                                          size_t length=(size_t)col_name_len;
                                         char *ptr=(char *)services.malloc_atomic(length+1);                                          char *ptr=(char *)services.malloc_atomic(length+1);
                                         if( connection.options.bLowerCaseColumnNames )                                           if( connection.options.bLowerCaseColumnNames ) 
                                                 tolower(ptr, col_name, length);                                                  tolower_str(ptr, col_name, length);
                                         else                                          else
                                                 memcpy(ptr, col_name, length);                                                                                            memcpy(ptr, col_name, length);                                          
                                         ptr[length]=0;                                          ptr[length]=0;
Line 747  private: // private funcs Line 829  private: // private funcs
                                         char*& buf=connection.fetch_buffers[column_count-1];                                          char*& buf=connection.fetch_buffers[column_count-1];
                                         ptr=buf; // get cached buffer                                          ptr=buf; // get cached buffer
                                         if(!ptr) // allocate if needed, caching it                                          if(!ptr) // allocate if needed, caching it
                                                 ptr=buf=(char *)::/*see disconnect*/malloc(MAX_OUT_STRING_LENGTH+1/*terminator*/);                                                  ptr=buf=(char *)services.malloc_atomic(MAX_OUT_STRING_LENGTH+1/*terminator*/);
                                         col.str=(char*)ptr;                                          col.str=(char*)ptr;
                                         size=MAX_OUT_STRING_LENGTH;                                          size=MAX_OUT_STRING_LENGTH;
                                         break;                                          break;
Line 781  private: // private funcs Line 863  private: // private funcs
                                         for(int i=0; i<column_count; i++) {                                          for(int i=0; i<column_count; i++) {
                                                 size_t length=0;                                                  size_t length=0;
                                                 char* strm=0;                                                  char* strm=0;
                                                 if(!cols[i].indicator) // not NULL  
                                                   sb2 indicator=cols[i].indicator;
                                                   if(indicator!=-1) { // not NULL
                                                           if(indicator!=0)
                                                                   fail(connection, indicator<0?
                                                                           "column return buffer overflow, additionally size too big to be returned in 'indicator'"
                                                                           : "column return buffer overflow");
   
                                                         switch(cols[i].type) {                                                          switch(cols[i].type) {
                                                         case SQLT_CLOB:                                                           case SQLT_CLOB: 
                                                                 {                                                                  {
Line 822  private: // private funcs Line 911  private: // private funcs
                                                                 }                                                                  }
                                                                 break;                                                                  break;
                                                         }                                                          }
                                                   }
   
                                                 const char* str=strm;                                                  const char* str=strm;
                                                 if(str && length)                                                  if(str && length)
Line 858  cleanup: // no check call after this poi Line 948  cleanup: // no check call after this poi
   
 private: // conn client library funcs  private: // conn client library funcs
                   
           friend void fail(Connection& connection, const char *msg);
         friend void check(Connection& connection, const char *step, sword status);          friend void check(Connection& connection, const char *step, sword status);
         friend sb4 cbf_get_data(dvoid *ctxp,           friend sb4 cbf_get_data(dvoid *ctxp, 
                 OCIBind *bindp,                   OCIBind *bindp, 
Line 892  private: // conn client library funcs Line 983  private: // conn client library funcs
                 ub2 dty, dvoid *indp, ub2 *alenp, ub2 *rcodep,                  ub2 dty, dvoid *indp, ub2 *alenp, ub2 *rcodep,
                 ub4 maxarr_len, ub4 *curelep, ub4 mode));                  ub4 maxarr_len, ub4 *curelep, ub4 mode));
   
           OCI_DECL(BindByName, (OCIStmt *stmtp, OCIBind **bindp, OCIError *errhp,
                   text* placeholder, sb4 placeh_len, dvoid *valuep, sb4 value_sz,
                   ub2 dty, dvoid *indp, ub2 *alenp, ub2 *rcodep,
                   ub4 maxarr_len, ub4 *curelep, ub4 mode));
   
         OCI_DECL(BindDynamic, (OCIBind *bindp, OCIError *errhp, dvoid *ictxp,          OCI_DECL(BindDynamic, (OCIBind *bindp, OCIError *errhp, dvoid *ictxp,
                 OCICallbackInBind icbfp, dvoid *octxp,                  OCICallbackInBind icbfp, dvoid *octxp,
                 OCICallbackOutBind ocbfp));                  OCICallbackOutBind ocbfp));
Line 983  private: // conn client library funcs li Line 1079  private: // conn client library funcs li
                 OCI_LINK(Initialize);                  OCI_LINK(Initialize);
                 OCI_LINK(EnvInit);                  OCI_LINK(EnvInit);
                 OCI_LINK(AttrGet);              OCI_LINK(AttrSet);                  OCI_LINK(AttrGet);              OCI_LINK(AttrSet);
                 OCI_LINK(BindByPos);            OCI_LINK(BindDynamic);                  OCI_LINK(BindByPos);            OCI_LINK(BindByName);   OCI_LINK(BindDynamic);
                 OCI_LINK(DefineByPos);                  OCI_LINK(DefineByPos);
                 OCI_LINK(DescriptorAlloc);              OCI_LINK(DescriptorFree);                  OCI_LINK(DescriptorAlloc);              OCI_LINK(DescriptorFree);
                 OCI_LINK(ErrorGet);                  OCI_LINK(ErrorGet);
Line 1052  void check(Connection& connection, const Line 1148  void check(Connection& connection, const
         longjmp(connection.mark, 1);          longjmp(connection.mark, 1);
 }  }
   
   void fail(Connection& connection, const char* msg) {
           snprintf(connection.error, sizeof(connection.error), "%s", msg);
           longjmp(connection.mark, 1);
   }
   
 void check(Connection& connection, bool error) {  void check(Connection& connection, bool error) {
         if(error)          if(error)
                 longjmp(connection.mark, 1);                  longjmp(connection.mark, 1);
Line 1060  void check(Connection& connection, bool Line 1161  void check(Connection& connection, bool
 /* ----------------------------------------------------------------- */  /* ----------------------------------------------------------------- */
 /* Intbind callback that does not do any data input.                 */  /* Intbind callback that does not do any data input.                 */
 /* ----------------------------------------------------------------- */  /* ----------------------------------------------------------------- */
 static sb4 cbf_no_data(  sb4 cbf_no_data(
                                 dvoid* /*ctxp*/,                                   dvoid* /*ctxp*/, 
                                 OCIBind* /*bindp*/,                                   OCIBind* /*bindp*/, 
                                 ub4 /*iter*/, ub4 /*index*/,                                   ub4 /*iter*/, ub4 /*index*/, 
Line 1088  static sb4 cbf_get_data(dvoid *ctxp, Line 1189  static sb4 cbf_get_data(dvoid *ctxp,
                                  ub1 *piecep,                                    ub1 *piecep, 
                                  dvoid **indpp,                                    dvoid **indpp, 
                                  ub2 **rcodepp) {                                   ub2 **rcodepp) {
         OracleSQL_query_lobs::cbf_context_struct &context=          Query_lobs::Item& context=*static_cast<Query_lobs::Item*>(ctxp);
                 *(OracleSQL_query_lobs::cbf_context_struct *)ctxp;  
   
         if(index==0) {          if(index==0) {
                 static ub4  rows;                  static ub4  rows;
Line 1097  static sb4 cbf_get_data(dvoid *ctxp, Line 1197  static sb4 cbf_get_data(dvoid *ctxp,
                         OracleSQL_driver->OCIAttrGet(                          OracleSQL_driver->OCIAttrGet(
                                 (CONST dvoid *) bindp, OCI_HTYPE_BIND, (dvoid *)&rows,                                   (CONST dvoid *) bindp, OCI_HTYPE_BIND, (dvoid *)&rows, 
                                 (ub4 *)sizeof(ub2), OCI_ATTR_ROWS_RETURNED, context.connection->errhp)) ;                                  (ub4 *)sizeof(ub2), OCI_ATTR_ROWS_RETURNED, context.connection->errhp)) ;
                 context.rows->count=(ub2)rows;                  context.rows.count=(ub2)rows;
                 context.rows->row=(OracleSQL_query_lobs::return_rows::return_row *)                  context.rows.row=(Query_lobs::return_rows::return_row *)
                         context.connection->services->malloc_atomic(sizeof(OracleSQL_query_lobs::return_rows::return_row)*rows);                          context.connection->services->malloc_atomic(sizeof(Query_lobs::return_rows::return_row)*rows);
         }          }
   
         OracleSQL_query_lobs::return_rows::return_row &var=context.rows->row[index];          Query_lobs::return_rows::return_row &var=context.rows.row[index];
   
         check(*context.connection, "alloc output var desc dynamic", OracleSQL_driver->OCIDescriptorAlloc(          check(*context.connection, "alloc output var desc dynamic", OracleSQL_driver->OCIDescriptorAlloc(
                 (dvoid *) context.connection->envhp, (dvoid **)&var.locator,                   (dvoid *) context.connection->envhp, (dvoid **)&var.locator, 
Line 1118  static sb4 cbf_get_data(dvoid *ctxp, Line 1218  static sb4 cbf_get_data(dvoid *ctxp,
         return OCI_CONTINUE;          return OCI_CONTINUE;
 }  }
   
 static void tolower(char *out, const char *in, size_t size) {  static void tolower_str(char *out, const char *in, size_t size) {
         while(size--)          while(size--)
                 *out++=(char)tolower(*in++);                  *out++=(char)tolower(*in++);
 }  }
 static void toupper(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++);
 }  }

Removed from v.1.54  
changed lines
  Added in v.1.60


E-mail: