--- sql/oracle/parser3oracle.C 2002/10/31 10:00:04 1.21 +++ sql/oracle/parser3oracle.C 2002/12/09 11:43:08 1.26 @@ -7,7 +7,7 @@ 2001.07.30 using Oracle 8.1.6 [@test tested with Oracle 7.x.x] */ -static const char *RCSId="$Id: parser3oracle.C,v 1.21 2002/10/31 10:00:04 paf Exp $"; +static const char *RCSId="$Id: parser3oracle.C,v 1.26 2002/12/09 11:43:08 paf Exp $"; #include "config_includes.h" @@ -68,18 +68,17 @@ static int pa_setenv(const char *name, c #else //#ifdef HAVE_SETENV if(value) { - char *buf; if(prev_value) { // MEM_LEAK_HERE - buf=(char *)::malloc(strlen(prev_value) + char *buf=(char *)::malloc(strlen(prev_value) +strlen(value) +1); strcpy(buf, prev_value); strcat(buf, value); - } else - buf=value; + value=buf; + } - return setenv(name, buf, 1/*overwrite*/); + return setenv(name, value, 1/*overwrite*/); } else { unsetenv(name); return 0; @@ -133,6 +132,7 @@ static const char *options2env(char *opt #ifndef DOXYGEN struct OracleSQL_connection_struct { jmp_buf mark; char error[MAX_STRING]; + SQL_Exception sql_exception; OCIEnv *envhp; OCIServer *srvhp; OCIError *errhp; @@ -443,8 +443,11 @@ cleanup: // no check call after this poi if(stmthp) OCIHandleFree((dvoid *)stmthp, (ub4)OCI_HTYPE_STMT); - if(failed) + if(failed) { + if(cs.sql_exception.defined()) + services._throw(cs.sql_exception); services._throw(cs.error); + } } private: // private funcs @@ -632,114 +635,125 @@ private: // private funcs failed=true; goto cleanup; } else { - // idea of preincrementing is that at error time all handles would free up - 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) { - --column_count; - break; - } - - /* Retrieve the data type attribute */ - check(services, cs, "get type", OCIAttrGet( - (dvoid*) mypard, (ub4)OCI_DTYPE_PARAM, - (dvoid*) &dtype, (ub4 *)0, (ub4)OCI_ATTR_DATA_TYPE, - (OCIError *)cs.errhp)); - - /* Retrieve the column name attribute */ - ub4 col_name_len; - check(services, cs, "get name", OCIAttrGet( - (dvoid*) mypard, (ub4)OCI_DTYPE_PARAM, - (dvoid**) &col_name, (ub4 *) &col_name_len, (ub4)OCI_ATTR_NAME, - (OCIError *)cs.errhp)); - - { - size_t size=(size_t)col_name_len; - char *ptr=(char *)services.malloc(size); - tolower(ptr, (char *)col_name, size); - handlers.add_column(ptr, size); - } - - ub2 coerce_type=dtype; - sb4 size=0; - void *ptr; - - switch(dtype) { - case SQLT_CLOB: + try { + + // idea of preincrementing is that at error time all handles would free up + 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) { + --column_count; + break; + } + + /* Retrieve the data type attribute */ + check(services, cs, "get type", OCIAttrGet( + (dvoid*) mypard, (ub4)OCI_DTYPE_PARAM, + (dvoid*) &dtype, (ub4 *)0, (ub4)OCI_ATTR_DATA_TYPE, + (OCIError *)cs.errhp)); + + /* Retrieve the column name attribute */ + ub4 col_name_len; + check(services, cs, "get name", OCIAttrGet( + (dvoid*) mypard, (ub4)OCI_DTYPE_PARAM, + (dvoid**) &col_name, (ub4 *) &col_name_len, (ub4)OCI_ATTR_NAME, + (OCIError *)cs.errhp)); + { - check(services, cs, "alloc output var desc", OCIDescriptorAlloc( - (dvoid *)cs.envhp, (dvoid **)(ptr=&cols[column_count-1].var), - (ub4)OCI_DTYPE_LOB, - 0, (dvoid **)0)); - - size=0; + size_t size=(size_t)col_name_len; + char *ptr=(char *)services.malloc(size); + tolower(ptr, (char *)col_name, size); + handlers.add_column(ptr, size); + } + + ub2 coerce_type=dtype; + sb4 size=0; + void *ptr; + + switch(dtype) { + case SQLT_CLOB: + { + check(services, cs, "alloc output var desc", OCIDescriptorAlloc( + (dvoid *)cs.envhp, (dvoid **)(ptr=&cols[column_count-1].var), + (ub4)OCI_DTYPE_LOB, + 0, (dvoid **)0)); + + size=0; + break; + } + default: + coerce_type=SQLT_STR; + ptr=cols[column_count-1].str=(char *)services.malloc(MAX_OUT_STRING_LENGTH+1); + size=MAX_OUT_STRING_LENGTH; break; } - default: - coerce_type=SQLT_STR; - ptr=cols[column_count-1].str=(char *)services.malloc(MAX_OUT_STRING_LENGTH+1); - size=MAX_OUT_STRING_LENGTH; - break; + + cols[column_count-1].type=coerce_type; + + check(services, cs, "DefineByPos", OCIDefineByPos( + stmthp, &cols[column_count-1].def, cs.errhp, + column_count, (ub1 *) ptr, size, + coerce_type, (dvoid *) &cols[column_count-1].indicator, + (ub2 *)0, (ub2 *)0, OCI_DEFAULT)); } - cols[column_count-1].type=coerce_type; + handlers.before_rows(); - check(services, cs, "DefineByPos", OCIDefineByPos( - stmthp, &cols[column_count-1].def, cs.errhp, - column_count, (ub1 *) ptr, size, - coerce_type, (dvoid *) &cols[column_count-1].indicator, - (ub2 *)0, (ub2 *)0, OCI_DEFAULT)); - } - - handlers.before_rows(); - - for(unsigned long row=0; !limit||row=offset) { - handlers.add_row(); - for(int i=0; i=offset) { + handlers.add_row(); + for(int i=0; iOCIErrorGet((dvoid *)cs.errhp, (ub4)1, (text *)NULL, &errcode, (text *)reason, (ub4)sizeof(reason), OCI_HTYPE_ERROR)==OCI_SUCCESS) msg=reason; @@ -951,8 +964,8 @@ void check( msg="unknown"; break; } - snprintf(cs.error, sizeof(cs.error), "%s: %s (%s, %d)", - prefix, msg, step, (int)status); + snprintf(cs.error, sizeof(cs.error), "%s (%s, %d)", + msg, step, (int)status); longjmp(cs.mark, 1); }