--- sql/oracle/parser3oracle.C 2001/10/28 14:51:30 1.2 +++ sql/oracle/parser3oracle.C 2002/12/09 11:07:52 1.25 @@ -1,13 +1,13 @@ /** @file Parser Oracle driver. - Copyright(c) 2001 ArtLebedev Group(http://www.artlebedev.com) + Copyright(c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com) - Author: Alexander Petrosyan (http://design.ru/paf) + Author: Alexandr Petrosian (http://paf.design.ru) 2001.07.30 using Oracle 8.1.6 [@test tested with Oracle 7.x.x] */ -static const char *RCSId="$Id: parser3oracle.C,v 1.2 2001/10/28 14:51:30 paf Exp $"; +static const char *RCSId="$Id: parser3oracle.C,v 1.25 2002/12/09 11:07:52 paf Exp $"; #include "config_includes.h" @@ -38,6 +38,54 @@ inline int max(int a, int b) { return a> inline int min(int a, int b){ return a "''" - *to++='\''; - break; - case '\\': // "\" -> "\\" - *to++='\''; - break; + if(to) { // store mode + unsigned int result=length; + while(length--) { + switch(*from) { + case '\'': // "'" -> "''" + *to++='\''; result++; + break; + } + *to++=*from++; } - *to++=*from++; - } - return result; + return result; + } else // estimate mode + return length*2; } void query( SQL_Driver_services& services, void *connection, @@ -302,6 +387,7 @@ public: OCIStmt *stmthp=0; bool failed=false; + SQL_Exception sql_exception; if(setjmp(cs.mark)) { failed=true; goto cleanup; @@ -337,9 +423,15 @@ public: } } - execute_prepared(services, cs, - statement, stmthp, lobs, - offset, limit, handlers); + try { + execute_prepared(services, cs, + statement, stmthp, lobs, + offset, limit, handlers); + } catch(const SQL_Exception& e) { + sql_exception=e; + } catch(...) { + sql_exception=SQL_Exception("exception occured in SQL_Driver_query_event_handlers"); // out of memory... + } } cleanup: // no check call after this point! { @@ -359,6 +451,8 @@ cleanup: // no check call after this poi if(failed) services._throw(cs.error); + if(sql_exception.defined()) + services._throw(sql_exception); } private: // private funcs @@ -397,7 +491,7 @@ private: // private funcs const char *start=o; bool escaped=false; while(*o && !(o[0]=='\'' && o[1]!='\'' && !escaped)) { - escaped=*o=='\\' || (o[0]=='\'' && o[1]=='\''); + escaped=o[0]=='\'' && o[1]=='\''; if(escaped) { // write pending, skip "\" or "'" if(size_t size=o-start) { @@ -462,6 +556,9 @@ private: // private funcs (dvoid *)stmthp, (ub4)OCI_HTYPE_STMT, (ub1 *)&stmt_type, (ub4 *)0, OCI_ATTR_STMT_TYPE, cs.errhp)); */ + + while(isspace(*statement)) + statement++; if(strncasecmp(statement, "select", 6)==0) stmt_type=OCI_STMT_SELECT; else if(strncasecmp(statement, "insert", 6)==0) @@ -512,6 +609,18 @@ private: // private funcs OCIStmt *stmthp, unsigned long offset, unsigned long limit, SQL_Driver_query_event_handlers& handlers) { + ub4 prefetch_rows=100; + check(services, cs, "AttrSet prefetch-rows", OCIAttrSet( + (dvoid *)stmthp, (ub4)OCI_HTYPE_STMT, + (dvoid *)&prefetch_rows, (ub4)0, + (ub4)OCI_ATTR_PREFETCH_ROWS, (OCIError *)cs.errhp)); + + ub4 prefetch_mem_size=100*0x400; + check(services, cs, "AttrSet prefetch-memory", OCIAttrSet( + (dvoid *)stmthp, (ub4)OCI_HTYPE_STMT, + (dvoid *)&prefetch_mem_size, (ub4)0, + (ub4)OCI_ATTR_PREFETCH_MEMORY, (OCIError *)cs.errhp)); + OCIParam *mypard; ub2 dtype; text *col_name; @@ -535,8 +644,10 @@ private: // private funcs while(++column_count<=MAX_COLS) { /* get next descriptor, if there is one */ if(OCIParamGet(stmthp, OCI_HTYPE_STMT, cs.errhp, (void **)&mypard, - (ub4) column_count)!=OCI_SUCCESS) + (ub4) column_count)!=OCI_SUCCESS) { + --column_count; break; + } /* Retrieve the data type attribute */ check(services, cs, "get type", OCIAttrGet( @@ -591,23 +702,19 @@ private: // private funcs handlers.before_rows(); - for(unsigned long row=0; !limit||row=offset) { handlers.add_row(); for(int i=0; i