]> granicus.if.org Git - php/commitdiff
mega patch to avoid recursive oci-calls as they might break oracle!
authorThies C. Arntzen <thies@php.net>
Wed, 15 Aug 2001 16:00:56 +0000 (16:00 +0000)
committerThies C. Arntzen <thies@php.net>
Wed, 15 Aug 2001 16:00:56 +0000 (16:00 +0000)
php will simply exit() (!!!) once it encounters an attemp to call oracle
while still in an oracle-call. this can only happen when the script gets
interrupted (timeout, apache-restart) and php tries to run the cleanups even
though we are in an unclean state. i will add an -ini flag soon (not before
4.0.7) which will (optional) make php not run the cleanups when in an unclean
state!

ext/oci8/oci8.c

index cefe7d950f8a7d00d0824bdca8cc0da38a1d0cfa..7b5e6c54bf6f17f8f135f45160cc1070c6ff47ff 100644 (file)
@@ -90,6 +90,39 @@ static zend_class_entry *oci_coll_class_entry_ptr;
 
 #define SAFE_STRING(s) ((s)?(s):"")
 
+
+/* dirty marcos to make sure we _never_ call oracle-functions recursivly 
+ *
+ * i'm well aware that we should _never_ call exit directly - this core is for
+ * pure testing and commented out - as you can see;-)
+ * thies@thieso.net 20010723
+ */
+
+#define CALL_OCI(call) \
+{ \
+       if (OCI(in_call)) { \
+               php_error(E_WARNING, "OCI8 Recursive call!\n"); \
+               exit(-1); \
+       } else { \
+               OCI(in_call)=1; \
+               call; \
+               OCI(in_call)=0; \
+       } \
+}
+
+#define CALL_OCI_RETURN(retcode,call) \
+{ \
+       if (OCI(in_call)) { \
+               retcode=-1; \
+               php_error(E_WARNING, "OCI8 Recursive call!\n"); \
+               exit(-1); \
+       } else { \
+               OCI(in_call)=1; \
+               retcode=call; \
+               OCI(in_call)=0; \
+       } \
+}
+
 #ifndef PHP_WIN32
 #include "build-defs.h"
 #endif
@@ -398,6 +431,7 @@ CONST void ocifree(dvoid *ctx, dvoid *ptr)
 static void php_oci_init_globals(php_oci_globals *oci_globals_p TSRMLS_DC)
 { 
        OCI(shutdown)   = 0;
+       OCI(in_call)    = 0;
 
        OCI(user) = malloc(sizeof(HashTable));
        zend_hash_init(OCI(user), 13, NULL, NULL, 1);
@@ -405,12 +439,18 @@ static void php_oci_init_globals(php_oci_globals *oci_globals_p TSRMLS_DC)
        OCI(server) = malloc(sizeof(HashTable));
        zend_hash_init(OCI(server), 13, NULL, NULL, 1); 
 
-       OCIEnvInit(&OCI(pEnv), OCI_DEFAULT, 0, NULL);
-       OCIHandleAlloc(OCI(pEnv), 
-                                  (dvoid **)&OCI(pError),
-                                  OCI_HTYPE_ERROR, 
-                                  0, 
-                                  NULL);
+       CALL_OCI(OCIEnvInit(
+                               &OCI(pEnv), 
+                               OCI_DEFAULT, 
+                               0, 
+                               NULL));
+       
+       CALL_OCI(OCIHandleAlloc(
+                               OCI(pEnv), 
+                               (dvoid **)&OCI(pError), 
+                               OCI_HTYPE_ERROR, 
+                               0, 
+                               NULL));
 }
 
 PHP_MINIT_FUNCTION(oci)
@@ -427,9 +467,9 @@ PHP_MINIT_FUNCTION(oci)
 #endif
 
 #if OCI_USE_EMALLOC
-    OCIInitialize(PHP_OCI_INIT_MODE, NULL, ocimalloc, ocirealloc, ocifree);
+       OCIInitialize(PHP_OCI_INIT_MODE, NULL, ocimalloc, ocirealloc, ocifree);
 #else
-    OCIInitialize(PHP_OCI_INIT_MODE, NULL, NULL, NULL, NULL);
+       OCIInitialize(PHP_OCI_INIT_MODE, NULL, NULL, NULL, NULL);
 #endif
 
 #ifdef ZTS
@@ -513,6 +553,7 @@ PHP_RINIT_FUNCTION(oci)
        */
 
        OCI(debug_mode) = 0; /* start "fresh" */
+/*     OCI(in_call) = 0; i don't think we want this! */
 
     oci_debug("php_rinit_oci");
 
@@ -548,7 +589,9 @@ PHP_MSHUTDOWN_FUNCTION(oci)
        free(OCI(user));
        free(OCI(server));
 
-       OCIHandleFree((dvoid *)OCI(pEnv), OCI_HTYPE_ENV);
+       CALL_OCI(OCIHandleFree(
+                               (dvoid *)OCI(pEnv), 
+                               OCI_HTYPE_ENV));
 
     oci_debug("END   php_mshutdown_oci");
 
@@ -694,12 +737,18 @@ _oci_stmt_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
        oci_debug("START _oci_stmt_list_dtor: id=%d last_query=\"%s\"",statement->id,SAFE_STRING(statement->last_query));
 
        if (statement->pStmt) {
-               OCIHandleFree(statement->pStmt, OCI_HTYPE_STMT);
+               CALL_OCI(OCIHandleFree(
+                                       statement->pStmt, 
+                                       OCI_HTYPE_STMT));
+               
                statement->pStmt = 0;
        }
 
        if (statement->pError) {
-               OCIHandleFree(statement->pError, OCI_HTYPE_ERROR);
+               CALL_OCI(OCIHandleFree(
+                                       statement->pError, 
+                                       OCI_HTYPE_ERROR));
+               
                statement->pError = 0;
        }
 
@@ -742,16 +791,18 @@ _oci_conn_list_dtor(oci_connection *connection TSRMLS_DC)
        oci_debug("START _oci_conn_list_dtor: id=%d",connection->id);
 
        if (connection->pServiceContext) {
-               connection->error =
-                       OCITransRollback(connection->pServiceContext,
-                                                        connection->pError,
-                                                        (ub4)0);
+               CALL_OCI_RETURN(connection->error,OCITransRollback(
+                                       connection->pServiceContext,
+                                       connection->pError,
+                                       (ub4)0));
  
                if (connection->error) {
                        oci_error(connection->pError, "failed to rollback outstanding transactions!", connection->error);
                }
 
-               OCIHandleFree((dvoid *) connection->pServiceContext, (ub4) OCI_HTYPE_SVCCTX);
+               CALL_OCI(OCIHandleFree(
+                                       (dvoid *) connection->pServiceContext, 
+                                       (ub4) OCI_HTYPE_SVCCTX));
        }
 
        if (connection->session && connection->session->exclusive) {
@@ -761,7 +812,9 @@ _oci_conn_list_dtor(oci_connection *connection TSRMLS_DC)
        }
 
        if (connection->pError) {
-               OCIHandleFree((dvoid *) connection->pError, (ub4) OCI_HTYPE_ERROR);
+               CALL_OCI(OCIHandleFree(
+                                       (dvoid *) connection->pError, 
+                                       (ub4) OCI_HTYPE_ERROR));
        }
 
        oci_debug("END   _oci_conn_list_dtor: id=%d",connection->id);
@@ -814,7 +867,9 @@ _oci_descriptor_list_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
 
        zend_list_delete(descr->conn->id);
 
-    OCIDescriptorFree(descr->ocidescr, descr->type);
+       CALL_OCI(OCIDescriptorFree(
+                               descr->ocidescr, 
+                               descr->type));
 
     oci_debug("END   _oci_descriptor_list_dtor: %d",descr->id);
 
@@ -892,11 +947,20 @@ oci_error(OCIError *err_p, char *what, sword status)
        case OCI_NO_DATA:
                php_error(E_WARNING, "%s: OCI_NO_DATA", what);
                break;
-       case OCI_ERROR:
-               OCIErrorGet(err_p, (ub4)1, NULL, &errcode, errbuf,
-                                       (ub4)sizeof(errbuf), (ub4)OCI_HTYPE_ERROR);
-               php_error(E_WARNING, "%s: %s", what, errbuf);
-               break;
+       case OCI_ERROR: {
+                       TSRMLS_FETCH();
+                       CALL_OCI(OCIErrorGet(
+                                       err_p, 
+                                       (ub4)1, 
+                                       NULL, 
+                                       &errcode, 
+                                       errbuf,
+                                       (ub4)sizeof(errbuf), 
+                                       (ub4)OCI_HTYPE_ERROR));
+               
+                       php_error(E_WARNING, "%s: %s", what, errbuf);
+                       break;
+               }
        case OCI_INVALID_HANDLE:
                php_error(E_WARNING, "%s: OCI_INVALID_HANDLE", what);
                break;
@@ -919,13 +983,14 @@ static int oci_ping(oci_server *server)
 {
        char version[256];
        TSRMLS_FETCH();
+       
+       CALL_OCI_RETURN(OCI(error), OCIServerVersion(
+                               server->pServer,
+                               OCI(pError), 
+                               (text*)version, 
+                               sizeof(version),
+                               OCI_HTYPE_SERVER));
 
-    OCI(error) = 
-               OCIServerVersion(server->pServer,
-                                                OCI(pError), 
-                                                (text*)version, 
-                                                sizeof(version),
-                                                OCI_HTYPE_SERVER);
        if (OCI(error) == OCI_SUCCESS) {
                return 1;
        }
@@ -1068,13 +1133,13 @@ oci_new_desc(int type,oci_connection *connection)
                        php_error(E_WARNING, "Unknown descriptor type %d.",descr->type);
                        return 0;
        }
-
-       OCI(error) = 
-               OCIDescriptorAlloc(OCI(pEnv),
-                                                  (dvoid*)&(descr->ocidescr), 
-                                                  descr->type, 
-                                                  (size_t) 0, 
-                                                  (dvoid **) 0);
+       
+       CALL_OCI_RETURN(OCI(error), OCIDescriptorAlloc(
+                               OCI(pEnv),
+                               (dvoid*)&(descr->ocidescr), 
+                               descr->type, 
+                               (size_t) 0, 
+                               (dvoid **) 0));
        
        if (OCI(error)) {
                ub4 error;
@@ -1213,30 +1278,35 @@ static int
 oci_setprefetch(oci_statement *statement,int size)
 { 
        ub4   prefetch;
+       sword error;
+       TSRMLS_FETCH();
 
        prefetch = size * 1024;
-       statement->error = 
-               oci_error(statement->pError, 
-                                  "OCIAttrSet OCI_ATTR_PREFETCH_MEMORY",
-                                  OCIAttrSet(statement->pStmt,
-                                                         OCI_HTYPE_STMT,
-                                                         &prefetch,
-                                                         0, 
-                                                         OCI_ATTR_PREFETCH_MEMORY,
-                                                         statement->pError));
+
+       CALL_OCI_RETURN(error, OCIAttrSet(
+                               statement->pStmt,
+                               OCI_HTYPE_STMT,
+                               &prefetch,
+                               0, 
+                               OCI_ATTR_PREFETCH_MEMORY,
+                               statement->pError));
+
+       statement->error = oci_error(statement->pError, "OCIAttrSet OCI_ATTR_PREFETCH_MEMORY", error);
+
        if (statement->error) {
               oci_handle_error(statement->conn, statement->error);
        }
+
        prefetch = size;
-       statement->error = 
-               oci_error(statement->pError, 
-                                  "OCIAttrSet OCI_ATTR_PREFETCH_MEMORY",
-                                  OCIAttrSet(statement->pStmt,
-                                                         OCI_HTYPE_STMT,
-                                                         &prefetch,
-                                                         0, 
-                                                         OCI_ATTR_PREFETCH_ROWS,
-                                                         statement->pError));
+       CALL_OCI_RETURN(error, OCIAttrSet(
+                               statement->pStmt,
+                               OCI_HTYPE_STMT,
+                               &prefetch,
+                               0, 
+                               OCI_ATTR_PREFETCH_ROWS,
+                               statement->pError));
+
+       statement->error = oci_error(statement->pError, "OCIAttrSet OCI_ATTR_PREFETCH_MEMORY", error);
     if (statement->error) {
                oci_handle_error(statement->conn, statement->error);
        }
@@ -1250,34 +1320,44 @@ oci_setprefetch(oci_statement *statement,int size)
 static oci_statement *oci_parse(oci_connection *connection, char *query, int len)
 {
        oci_statement *statement;
+       sword error;
        TSRMLS_FETCH();
 
        statement = ecalloc(1,sizeof(oci_statement));
 
-    OCIHandleAlloc(OCI(pEnv),
-                                  (dvoid **)&statement->pStmt,
-                                  OCI_HTYPE_STMT, 
-                                  0, 
-                                  NULL);
-    OCIHandleAlloc(OCI(pEnv),
-                                  (dvoid **)&statement->pError,
-                                  OCI_HTYPE_ERROR,
-                                  0,
-                                  NULL);
+    CALL_OCI(OCIHandleAlloc(
+                               OCI(pEnv),
+                           (dvoid **)&statement->pStmt,
+                               OCI_HTYPE_STMT, 
+                               0, 
+                               NULL));
+
+    CALL_OCI(OCIHandleAlloc(
+                               OCI(pEnv),
+                               (dvoid **)&statement->pError,
+                               OCI_HTYPE_ERROR,
+                               0,
+                               NULL));
 
        if (len > 0) {
-               connection->error = 
-                       oci_error(connection->pError,
-                                          "OCIParse",
-                                          OCIStmtPrepare(statement->pStmt,
-                                                                         connection->pError,
-                                                                         (text*)query,
-                                                                         len,
-                                                                         OCI_NTV_SYNTAX,
-                                                                         OCI_DEFAULT));
+               CALL_OCI_RETURN(error, OCIStmtPrepare(
+                                       statement->pStmt,
+                                       connection->pError,
+                                       (text*)query,
+                                       len,
+                                       OCI_NTV_SYNTAX,
+                                       OCI_DEFAULT));
+
+               connection->error = oci_error(connection->pError, "OCIParse", error);
                if (connection->error) {
-                       OCIHandleFree(statement->pStmt, OCI_HTYPE_STMT);
-                       OCIHandleFree(statement->pError, OCI_HTYPE_ERROR);
+                       CALL_OCI(OCIHandleFree(
+                                               statement->pStmt, 
+                                               OCI_HTYPE_STMT));
+                       
+                       CALL_OCI(OCIHandleFree(
+                                               statement->pError, 
+                                               OCI_HTYPE_ERROR));
+
                        efree(statement);
                        oci_handle_error(connection, connection->error);
                        return 0;
@@ -1320,18 +1400,18 @@ oci_execute(oci_statement *statement, char *func,ub4 mode)
        int dtype;
        dvoid *buf;
        oci_descriptor *descr;
+       sword error;
        TSRMLS_FETCH();
 
-       statement->error = 
-               oci_error(statement->pError,
-                                 "OCIAttrGet OCI_HTYPE_STMT/OCI_ATTR_STMT_TYPE",
-                                 OCIAttrGet((dvoid *)statement->pStmt,
-                                                        OCI_HTYPE_STMT,
-                                                        (ub2 *)&stmttype,
-                                                        (ub4 *)0,
-                                                        OCI_ATTR_STMT_TYPE,
-                                                        statement->pError));
+       CALL_OCI_RETURN(error, OCIAttrGet(
+                               (dvoid *)statement->pStmt,
+                               OCI_HTYPE_STMT,
+                               (ub2 *)&stmttype,
+                               (ub4 *)0,
+                               OCI_ATTR_STMT_TYPE,
+                               statement->pError));
 
+       statement->error = oci_error(statement->pError, "OCIAttrGet OCI_HTYPE_STMT/OCI_ATTR_STMT_TYPE", error);
        if (statement->error) {
                oci_handle_error(statement->conn, statement->error);
                return 0;
@@ -1351,17 +1431,17 @@ oci_execute(oci_statement *statement, char *func,ub4 mode)
                        zend_hash_apply(statement->binds, (apply_func_t) _oci_bind_pre_exec TSRMLS_CC);
                }
 
-               statement->error = 
-                       oci_error(statement->pError,
-                                         "OCIStmtExecute",
-                                         OCIStmtExecute(statement->conn->pServiceContext,
-                                                                        statement->pStmt,
-                                                                        statement->pError,
-                                                                        iters,
-                                                                        0,
-                                                                        NULL,
-                                                                        NULL,
-                                                                        mode));
+               CALL_OCI_RETURN(error, OCIStmtExecute(
+                                       statement->conn->pServiceContext,
+                                       statement->pStmt,
+                                       statement->pError,
+                                       iters,
+                                       0,
+                                       NULL,
+                                       NULL,
+                                       mode));
+
+               statement->error = oci_error(statement->pError, "OCIStmtExecute", error);
                if (statement->binds) {
                        zend_hash_apply(statement->binds, (apply_func_t) _oci_bind_post_exec TSRMLS_CC);
                }
@@ -1382,15 +1462,15 @@ oci_execute(oci_statement *statement, char *func,ub4 mode)
                
                counter = 1;
 
-               statement->error = 
-                       oci_error(statement->pError,
-                                         "OCIAttrGet OCI_HTYPE_STMT/OCI_ATTR_PARAM_COUNT",
-                                         OCIAttrGet((dvoid *)statement->pStmt,
-                                                                OCI_HTYPE_STMT,
-                                                                (dvoid *)&colcount,
-                                                                (ub4 *)0,
-                                                                OCI_ATTR_PARAM_COUNT,
-                                                                statement->pError));
+               CALL_OCI_RETURN(error, OCIAttrGet(
+                                       (dvoid *)statement->pStmt,
+                                       OCI_HTYPE_STMT,
+                                       (dvoid *)&colcount,
+                                       (ub4 *)0,
+                                       OCI_ATTR_PARAM_COUNT,
+                                       statement->pError));
+
+               statement->error = oci_error(statement->pError, "OCIAttrGet OCI_HTYPE_STMT/OCI_ATTR_PARAM_COUNT", error);
                if (statement->error) {
                        oci_handle_error(statement->conn, statement->error);
                        return 0; /* XXX we loose memory!!! */
@@ -1410,44 +1490,42 @@ oci_execute(oci_statement *statement, char *func,ub4 mode)
                        
                        outcol->statement = statement;
 
-                       statement->error = 
-                               oci_error(statement->pError,
-                                                  "OCIParamGet OCI_HTYPE_STMT",
-                                                  OCIParamGet(
-                                                                          (dvoid *)statement->pStmt,
-                                                                          OCI_HTYPE_STMT,
-                                                                          statement->pError,
-                                                                          (dvoid**)&param,
-                                                                          counter));
+                       CALL_OCI_RETURN(error, OCIParamGet(
+                                               (dvoid *)statement->pStmt,
+                                               OCI_HTYPE_STMT,
+                                               statement->pError,
+                                               (dvoid**)&param,
+                                               counter));
+
+                       statement->error = oci_error(statement->pError, "OCIParamGet OCI_HTYPE_STMT", error);
                        if (statement->error) {
                                oci_handle_error(statement->conn, statement->error);
                                return 0; /* XXX we loose memory!!! */
                        }
 
-                       statement->error = 
-                               oci_error(statement->pError, 
-                                                  "OCIAttrGet OCI_DTYPE_PARAM/OCI_ATTR_DATA_TYPE",
-                                                  OCIAttrGet((dvoid *)param,
-                                                                         OCI_DTYPE_PARAM,
-                                                                         (dvoid *)&outcol->data_type,
-                                                                         (ub4 *)0,
-                                                                         OCI_ATTR_DATA_TYPE,
-                                                                         statement->pError));
+                       CALL_OCI_RETURN(error, OCIAttrGet(
+                                               (dvoid *)param,
+                                               OCI_DTYPE_PARAM,
+                                               (dvoid *)&outcol->data_type,
+                                               (ub4 *)0,
+                                               OCI_ATTR_DATA_TYPE,
+                                               statement->pError));
+
+                       statement->error = oci_error(statement->pError, "OCIAttrGet OCI_DTYPE_PARAM/OCI_ATTR_DATA_TYPE", error);
                        if (statement->error) {
                                oci_handle_error(statement->conn, statement->error);
                                return 0; /* XXX we loose memory!!! */
                        }
 
+                       CALL_OCI_RETURN(error, OCIAttrGet(
+                                               (dvoid *)param,
+                                               OCI_DTYPE_PARAM,
+                                               (dvoid *)&outcol->data_size,
+                                               (dvoid *)0,
+                                               OCI_ATTR_DATA_SIZE,
+                                               statement->pError));
 
-                       statement->error = 
-                               oci_error(statement->pError,
-                                                  "OCIAttrGet OCI_DTYPE_PARAM/OCI_ATTR_DATA_SIZE",
-                                                  OCIAttrGet((dvoid *)param,
-                                                                         OCI_DTYPE_PARAM,
-                                                                         (dvoid *)&outcol->data_size,
-                                                                         (dvoid *)0,
-                                                                         OCI_ATTR_DATA_SIZE,
-                                                                         statement->pError));
+                       statement->error = oci_error(statement->pError, "OCIAttrGet OCI_DTYPE_PARAM/OCI_ATTR_DATA_SIZE", error);
                        if (statement->error) {
                                oci_handle_error(statement->conn, statement->error);
                                return 0; /* XXX we loose memory!!! */
@@ -1455,44 +1533,44 @@ oci_execute(oci_statement *statement, char *func,ub4 mode)
 
                        outcol->storage_size4 = outcol->data_size;
                        outcol->retlen = outcol->data_size;
-
-                       statement->error =
-                               oci_error(statement->pError,
-                                                  "OCIAttrGet OCI_DTYPE_PARAM/OCI_ATTR_SCALE",
-                                                  OCIAttrGet((dvoid *)param,
-                                                                         OCI_DTYPE_PARAM,
-                                                                         (dvoid *)&outcol->scale,
-                                                                         (dvoid *)0,
-                                                                         OCI_ATTR_SCALE,
-                                                                         statement->pError));
+       
+                       CALL_OCI_RETURN(error, OCIAttrGet(
+                                               (dvoid *)param, 
+                                               OCI_DTYPE_PARAM, 
+                                               (dvoid *)&outcol->scale, 
+                                               (dvoid *)0, 
+                                               OCI_ATTR_SCALE, 
+                                               statement->pError));
+                                               
+                       statement->error = oci_error(statement->pError, "OCIAttrGet OCI_DTYPE_PARAM/OCI_ATTR_SCALE", error);
                        if (statement->error) {
                                oci_handle_error(statement->conn, statement->error);
                                return 0; /* XXX we lose memory!!! */
                        }
 
-                       statement->error =
-                               oci_error(statement->pError,
-                                                  "OCIAttrGet OCI_DTYPE_PARAM/OCI_ATTR_PRECISION",
-                                                  OCIAttrGet((dvoid *)param,
-                                                                         OCI_DTYPE_PARAM,
-                                                                         (dvoid *)&outcol->precision,
-                                                                         (dvoid *)0,
-                                                                         OCI_ATTR_PRECISION,
-                                                                         statement->pError));
+                       CALL_OCI_RETURN(error, OCIAttrGet(
+                                               (dvoid *)param, 
+                                               OCI_DTYPE_PARAM, 
+                                               (dvoid *)&outcol->precision, 
+                                               (dvoid *)0, 
+                                               OCI_ATTR_PRECISION, 
+                                               statement->pError)); 
+
+                       statement->error = oci_error(statement->pError, "OCIAttrGet OCI_DTYPE_PARAM/OCI_ATTR_PRECISION", error);
                        if (statement->error) {
                                oci_handle_error(statement->conn, statement->error);
                                return 0; /* XXX we lose memory!!! */
                        }
-                                               
-                       statement->error = 
-                               oci_error(statement->pError,
-                                                  "OCIAttrGet OCI_DTYPE_PARAM/OCI_ATTR_NAME",
-                                                  OCIAttrGet((dvoid *)param,
-                                                                         OCI_DTYPE_PARAM,
-                                                                         (dvoid **)&colname,                                   /* XXX this string is NOT zero terminated!!!! */
-                                                                         (ub4 *)&outcol->name_len,
-                                                                         (ub4)OCI_ATTR_NAME,
-                                                                         statement->pError));
+                                       
+                       CALL_OCI_RETURN(error, OCIAttrGet(
+                                               (dvoid *)param, 
+                                               OCI_DTYPE_PARAM, 
+                                               (dvoid **)&colname,                                     /* XXX this string is NOT zero terminated!!!! */ 
+                                               (ub4 *)&outcol->name_len, 
+                                               (ub4)OCI_ATTR_NAME, 
+                                               statement->pError));
+
+                       statement->error = oci_error(statement->pError, "OCIAttrGet OCI_DTYPE_PARAM/OCI_ATTR_NAME", error);
                        if (statement->error) {
                                oci_handle_error(statement->conn, statement->error);
                                return 0; /* XXX we loose memory!!! */
@@ -1570,35 +1648,35 @@ oci_execute(oci_statement *statement, char *func,ub4 mode)
                        }
 
                        if (dynamic == OCI_DYNAMIC_FETCH) {
-                               statement->error = 
-                                       oci_error(statement->pError,
-                                                          "OCIDefineByPos",
-                                                          OCIDefineByPos(statement->pStmt,                             /* IN/OUT handle to the requested SQL query */
-                                                                                         (OCIDefine **)&outcol->pDefine,/* IN/OUT pointer to a pointer to a define handle */
-                                                                                         statement->pError,                    /* IN/OUT An error handle  */
-                                                                                         counter,                                              /* IN     position in the select list */
-                                                                                         (dvoid *)NULL,                                /* IN/OUT pointer to a buffer */
-                                                                                         outcol->storage_size4,            /* IN         The size of each valuep buffer in bytes */
-                                                                                         define_type,                                  /* IN     The data type */
-                                                                                         (dvoid *)&outcol->indicator,  /* IN     pointer to an indicator variable or arr */
-                                                                                         (ub2 *)NULL,                      /* IN/OUT Pointer to array of length of data fetched */
-                                                                                         (ub2 *)NULL,                      /* OUT        Pointer to array of column-level return codes */
-                                                                                         OCI_DYNAMIC_FETCH));          /* IN     mode (OCI_DEFAULT, OCI_DYNAMIC_FETCH) */
+                               CALL_OCI_RETURN(error, OCIDefineByPos(
+                                                       statement->pStmt,                                                       /* IN/OUT handle to the requested SQL query */
+                                                       (OCIDefine **)&outcol->pDefine,                         /* IN/OUT pointer to a pointer to a define handle */
+                                                       statement->pError,                                                      /* IN/OUT An error handle  */
+                                                       counter,                                                                        /* IN     position in the select list */ 
+                                                       (dvoid *)NULL,                                                          /* IN/OUT pointer to a buffer */ 
+                                                       outcol->storage_size4,                                  /* IN     The size of each valuep buffer in bytes */ 
+                                                       define_type,                                                            /* IN     The data type */ 
+                                                       (dvoid *)&outcol->indicator,                            /* IN     pointer to an indicator variable or arr */ 
+                                                       (ub2 *)NULL,                                            /* IN/OUT Pointer to array of length of data fetched */ 
+                                                       (ub2 *)NULL,                                            /* OUT    Pointer to array of column-level return codes */ 
+                                                       OCI_DYNAMIC_FETCH));                                    /* IN     mode (OCI_DEFAULT, OCI_DYNAMIC_FETCH) */
+
+                               statement->error = oci_error(statement->pError, "OCIDefineByPos", error);
                        } else {
-                               statement->error = 
-                                       oci_error(statement->pError,
-                                                          "OCIDefineByPos",
-                                                          OCIDefineByPos(statement->pStmt,                             /* IN/OUT handle to the requested SQL query */
-                                                                                         (OCIDefine **)&outcol->pDefine,/* IN/OUT pointer to a pointer to a define handle */
-                                                                                         statement->pError,                    /* IN/OUT An error handle  */
-                                                                                         counter,                                              /* IN     position in the select list */
-                                                                                         (dvoid *)buf,                                 /* IN/OUT pointer to a buffer */
-                                                                                         outcol->storage_size4,            /* IN         The size of each valuep buffer in bytes */
-                                                                                         define_type,                                  /* IN     The data type */
-                                                                                         (dvoid *)&outcol->indicator,  /* IN     pointer to an indicator variable or arr */
-                                                                                         (ub2 *)&outcol->retlen,               /* IN/OUT Pointer to array of length of data fetched */
-                                                                                         (ub2 *)&outcol->retcode,              /* OUT    Pointer to array of column-level return codes */
-                                                                                         OCI_DEFAULT));                        /* IN     mode (OCI_DEFAULT, OCI_DYNAMIC_FETCH) */
+                               CALL_OCI_RETURN(error, OCIDefineByPos(
+                                                       statement->pStmt,                                                       /* IN/OUT handle to the requested SQL query */ 
+                                                       (OCIDefine **)&outcol->pDefine,                         /* IN/OUT pointer to a pointer to a define handle */
+                                                       statement->pError,                                                      /* IN/OUT An error handle  */
+                                                       counter,                                                                        /* IN     position in the select list */
+                                                       (dvoid *)buf,                                                           /* IN/OUT pointer to a buffer */
+                                                       outcol->storage_size4,                                  /* IN     The size of each valuep buffer in bytes */
+                                                       define_type,                                                            /* IN     The data type */
+                                                       (dvoid *)&outcol->indicator,                            /* IN     pointer to an indicator variable or arr */
+                                                       (ub2 *)&outcol->retlen,                                         /* IN/OUT Pointer to array of length of data fetched */
+                                                       (ub2 *)&outcol->retcode,                                        /* OUT    Pointer to array of column-level return codes */
+                                                       OCI_DEFAULT));                                                  /* IN     mode (OCI_DEFAULT, OCI_DYNAMIC_FETCH) */
+
+                               statement->error = oci_error(statement->pError, "OCIDefineByPos", error);
                        }
                        if (statement->error) {
                                oci_handle_error(statement->conn, statement->error);
@@ -1636,11 +1714,12 @@ oci_fetch(oci_statement *statement, ub4 nrows, char *func TSRMLS_DC)
                zend_hash_apply(statement->columns, (apply_func_t) _oci_column_pre_fetch TSRMLS_CC);
        }
 
-       statement->error =
-               OCIStmtFetch(statement->pStmt,
-                                        statement->pError, nrows,
-                                        OCI_FETCH_NEXT,
-                                        OCI_DEFAULT);
+       CALL_OCI_RETURN(statement->error, OCIStmtFetch(
+                               statement->pStmt, 
+                               statement->pError, 
+                               nrows, 
+                               OCI_FETCH_NEXT, 
+                               OCI_DEFAULT));
 
        if ((statement->error == OCI_NO_DATA) || (nrows == 0)) {
                /* XXX this is needed for REFCURSORS! */
@@ -1669,22 +1748,24 @@ oci_fetch(oci_statement *statement, ub4 nrows, char *func TSRMLS_DC)
 
                                column->cb_retlen = OCI_PIECE_SIZE;
 
-                               OCIStmtSetPieceInfo((void *) column->pDefine,
-                                                                       OCI_HTYPE_DEFINE,
-                                                                       statement->pError,
-                                                                       ((char*)column->data) + column->retlen4,
-                                                                       &(column->cb_retlen),
-                                                                       OCI_NEXT_PIECE,
-                                                                       &column->indicator,
-                                                                       &column->retcode);
+                               CALL_OCI(OCIStmtSetPieceInfo(
+                                                       (void *) column->pDefine, 
+                                                       OCI_HTYPE_DEFINE, 
+                                                       statement->pError, 
+                                                       ((char*)column->data) + column->retlen4, 
+                                                       &(column->cb_retlen), 
+                                                       OCI_NEXT_PIECE, 
+                                                       &column->indicator, 
+                                                       &column->retcode));
                        }
                }       
 
-               statement->error =
-                       OCIStmtFetch(statement->pStmt,
-                                                statement->pError, nrows,
-                                                OCI_FETCH_NEXT,
-                                                OCI_DEFAULT);
+               CALL_OCI_RETURN(statement->error, OCIStmtFetch(
+                                       statement->pStmt, 
+                                       statement->pError, 
+                                       nrows, 
+                                       OCI_FETCH_NEXT, 
+                                       OCI_DEFAULT));
 
                for (i = 0; i < statement->ncolumns; i++) {
                        column = oci_get_col(statement, i + 1, 0);
@@ -1730,27 +1811,29 @@ oci_loadlob(oci_connection *connection, oci_descriptor *mydescr, char **buffer,u
        ub4 siz = 0;
        ub4 readlen = 0;
        char *buf;
+       TSRMLS_FETCH();
 
        *loblen = 0;
        
        if (mydescr->type == OCI_DTYPE_FILE) {
-               connection->error = 
-                       OCILobFileOpen(connection->pServiceContext,
-                                                  connection->pError,
-                                                  mydescr->ocidescr,
-                                                  OCI_FILE_READONLY);
+               CALL_OCI_RETURN(connection->error, OCILobFileOpen(
+                                       connection->pServiceContext, 
+                                       connection->pError, 
+                                       mydescr->ocidescr,
+                                       OCI_FILE_READONLY));
+
                if (connection->error) {
                        oci_error(connection->pError, "OCILobFileOpen",connection->error);
                        oci_handle_error(connection, connection->error);
                        return -1;
                }
        }
-
-       connection->error =
-               OCILobGetLength(connection->pServiceContext,
-                                               connection->pError,
-                                               mydescr->ocidescr,
-                                               &readlen);
+       
+       CALL_OCI_RETURN(connection->error, OCILobGetLength(
+                               connection->pServiceContext, 
+                               connection->pError, 
+                               mydescr->ocidescr, 
+                               &readlen));
 
        if (connection->error) {
                oci_error(connection->pError, "OCILobGetLength",connection->error);
@@ -1761,18 +1844,18 @@ oci_loadlob(oci_connection *connection, oci_descriptor *mydescr, char **buffer,u
        buf = emalloc(readlen + 1);
 
        while (readlen > 0) { /* thies loop should not be entered on readlen == 0 */
-               connection->error = 
-                       OCILobRead(connection->pServiceContext, 
-                                          connection->pError,
-                                          mydescr->ocidescr,
-                                          &readlen,                            /* IN/OUT bytes toread/read */
-                                          siz + 1,                                     /* offset (starts with 1) */ 
-                                          (dvoid *) ((char *) buf + siz),      
-                                          readlen,                                     /* size of buffer */
-                                          (dvoid *)0,
-                                          (OCICallbackLobRead) 0,      /* callback... */
-                                          (ub2) 0,                             /* The character set ID of the buffer data. */
-                                          (ub1) SQLCS_IMPLICIT);       /* The character set form of the buffer data. */
+               CALL_OCI_RETURN(connection->error, OCILobRead(
+                                       connection->pServiceContext, 
+                                       connection->pError, 
+                                       mydescr->ocidescr, 
+                                       &readlen,                                       /* IN/OUT bytes toread/read */ 
+                                       siz + 1,                                        /* offset (starts with 1) */ 
+                                       (dvoid *) ((char *) buf + siz), 
+                                       readlen,                                        /* size of buffer */ 
+                                       (dvoid *)0, 
+                                       (OCICallbackLobRead) 0,         /* callback... */ 
+                                       (ub2) 0,                                        /* The character set ID of the buffer data. */ 
+                                       (ub1) SQLCS_IMPLICIT));         /* The character set form of the buffer data. */
 
                siz += readlen;
                readlen = LOBREADSIZE;
@@ -1793,10 +1876,11 @@ oci_loadlob(oci_connection *connection, oci_descriptor *mydescr, char **buffer,u
        }
 
        if (mydescr->type == OCI_DTYPE_FILE) {
-               connection->error = 
-                       OCILobFileClose(connection->pServiceContext,
-                                                       connection->pError,
-                                                       mydescr->ocidescr);
+               CALL_OCI_RETURN(connection->error, OCILobFileClose(
+                                       connection->pServiceContext, 
+                                       connection->pError, 
+                                       mydescr->ocidescr));
+
                if (connection->error) {
                        oci_error(connection->pError, "OCILobFileClose", connection->error);
                        oci_handle_error(connection, connection->error);
@@ -2045,81 +2129,89 @@ static oci_session *_oci_open_session(oci_server* server,char *username,char *pa
        session->exclusive = exclusive;
 
        /* allocate temporary Service Context */
-       OCI(error) = 
-               OCIHandleAlloc(OCI(pEnv), 
-                                          (dvoid **)&svchp,
-                                          OCI_HTYPE_SVCCTX,
-                                          0,
-                                          NULL);
+       CALL_OCI_RETURN(OCI(error), OCIHandleAlloc(
+                               OCI(pEnv), 
+                               (dvoid **)&svchp, 
+                               OCI_HTYPE_SVCCTX, 
+                               0, 
+                               NULL));
+       
        if (OCI(error) != OCI_SUCCESS) {
                oci_error(OCI(pError), "_oci_open_session: OCIHandleAlloc OCI_HTYPE_SVCCTX", OCI(error));
                goto CLEANUP;
        }
 
        /* allocate private session-handle */
-       OCI(error) = 
-               OCIHandleAlloc(OCI(pEnv),
-                                          (dvoid **)&session->pSession,
-                                          OCI_HTYPE_SESSION,
-                                          0,
-                                          NULL);
+       CALL_OCI_RETURN(OCI(error), OCIHandleAlloc(
+                               OCI(pEnv), 
+                               (dvoid **)&session->pSession, 
+                               OCI_HTYPE_SESSION, 
+                               0, 
+                               NULL));
+
        if (OCI(error) != OCI_SUCCESS) {
                oci_error(OCI(pError), "_oci_open_session: OCIHandleAlloc OCI_HTYPE_SESSION", OCI(error));
                goto CLEANUP;
        }
 
        /* Set the server handle in service handle */ 
-       OCI(error) = 
-               OCIAttrSet(svchp,
-                                  OCI_HTYPE_SVCCTX,
-                                  server->pServer,
-                                  0, 
-                                  OCI_ATTR_SERVER, 
-                                  OCI(pError));
+       CALL_OCI_RETURN(OCI(error), OCIAttrSet(
+                               svchp, 
+                               OCI_HTYPE_SVCCTX, 
+                               server->pServer, 
+                               0,
+                               OCI_ATTR_SERVER,
+                               OCI(pError)));
+
        if (OCI(error) != OCI_SUCCESS) {
                oci_error(OCI(pError), "_oci_open_session: OCIAttrSet OCI_ATTR_SERVER", OCI(error));
                goto CLEANUP;
        }
 
        /* set the username in user handle */
-       OCI(error) = 
-               OCIAttrSet((dvoid *) session->pSession,
-                                  (ub4) OCI_HTYPE_SESSION, 
-                                  (dvoid *) username, 
-                                  (ub4) strlen(username), 
-                                  (ub4) OCI_ATTR_USERNAME, 
-                                  OCI(pError));
+       CALL_OCI_RETURN(OCI(error), OCIAttrSet(
+                               (dvoid *) session->pSession, 
+                               (ub4) OCI_HTYPE_SESSION, 
+                               (dvoid *) username, 
+                               (ub4) strlen(username), 
+                               (ub4) OCI_ATTR_USERNAME, 
+                               OCI(pError)));
+
        if (OCI(error) != OCI_SUCCESS) {
                oci_error(OCI(pError), "OCIAttrSet OCI_ATTR_USERNAME", OCI(error));
                goto CLEANUP;
        }
 
        /* set the password in user handle */
-       OCI(error) = 
-               OCIAttrSet((dvoid *) session->pSession,
-                                  (ub4) OCI_HTYPE_SESSION, 
-                                  (dvoid *) password, 
-                                  (ub4) strlen(password), 
-                                  (ub4) OCI_ATTR_PASSWORD, 
-                                  OCI(pError));
+       CALL_OCI_RETURN(OCI(error), OCIAttrSet(
+                               (dvoid *) session->pSession, 
+                               (ub4) OCI_HTYPE_SESSION, 
+                               (dvoid *) password, 
+                               (ub4) strlen(password), 
+                               (ub4) OCI_ATTR_PASSWORD, 
+                               OCI(pError)));
+
        if (OCI(error) != OCI_SUCCESS) {
                oci_error(OCI(pError), "OCIAttrSet OCI_ATTR_PASSWORD", OCI(error));
                goto CLEANUP;
        }
 
-       OCI(error) = 
-               OCISessionBegin(svchp,
-                                               OCI(pError),
-                                               session->pSession, 
-                                               (ub4) OCI_CRED_RDBMS, 
-                                               (ub4) OCI_DEFAULT);
+       CALL_OCI_RETURN(OCI(error), OCISessionBegin(
+                               svchp, 
+                               OCI(pError), 
+                               session->pSession, 
+                               (ub4) OCI_CRED_RDBMS, 
+                               (ub4) OCI_DEFAULT));
+
        if (OCI(error) != OCI_SUCCESS) {
                oci_error(OCI(pError), "OCISessionBegin", OCI(error));
                goto CLEANUP;
        }
 
        /* Free Temporary Service Context */
-       OCIHandleFree((dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX);
+       CALL_OCI(OCIHandleFree(
+                               (dvoid *) svchp, 
+                               (ub4) OCI_HTYPE_SVCCTX));
 
        if (exclusive) {
                psession = session;
@@ -2168,58 +2260,65 @@ _oci_close_session(oci_session *session)
 
        if (session->is_open) {
                /* Temporary Service Context */
-               OCI(error) = 
-                       OCIHandleAlloc(OCI(pEnv), 
-                                                  (dvoid **) &svchp,
-                                                  (ub4) OCI_HTYPE_SVCCTX,
-                                                  (size_t) 0, 
-                                                  (dvoid **) 0);
+               CALL_OCI_RETURN(OCI(error), OCIHandleAlloc(
+                                       OCI(pEnv), 
+                                       (dvoid **) &svchp, 
+                                       (ub4) OCI_HTYPE_SVCCTX, 
+                                       (size_t) 0, 
+                                       (dvoid **) 0));
                
                if (OCI(error) != OCI_SUCCESS) {
                        oci_error(OCI(pError), "_oci_close_session OCIHandleAlloc OCI_HTYPE_SVCCTX", OCI(error));
                }
                
                /* Set the server handle in service handle */ 
-               OCI(error) = 
-                       OCIAttrSet(svchp,
-                                          OCI_HTYPE_SVCCTX,
-                                          session->server->pServer,
-                                          0, 
-                                          OCI_ATTR_SERVER, 
-                                          OCI(pError));
+               CALL_OCI_RETURN(OCI(error), OCIAttrSet(
+                                       svchp, 
+                                       OCI_HTYPE_SVCCTX, 
+                                       session->server->pServer, 
+                                       0, 
+                                       OCI_ATTR_SERVER, 
+                                       OCI(pError)));
+
                if (OCI(error) != OCI_SUCCESS) {
                        oci_error(OCI(pError), "_oci_close_session: OCIAttrSet OCI_ATTR_SERVER", OCI(error));
                }
                
                /* Set the Authentication handle in the service handle */
-               OCI(error) = 
-                       OCIAttrSet(svchp, 
-                                          OCI_HTYPE_SVCCTX,
-                                          session->pSession,
-                                          0, 
-                                          OCI_ATTR_SESSION,
-                                          OCI(pError));
+               CALL_OCI_RETURN(OCI(error), OCIAttrSet(
+                                       svchp,  
+                                       OCI_HTYPE_SVCCTX, 
+                                       session->pSession, 
+                                       0, 
+                                       OCI_ATTR_SESSION, 
+                                       OCI(pError)));
+
                if (OCI(error) != OCI_SUCCESS) {
                        oci_error(OCI(pError), "_oci_close_session: OCIAttrSet OCI_ATTR_SESSION", OCI(error));
                }
-               
-               OCI(error) = 
-                       OCISessionEnd(svchp,
-                                                 OCI(pError),
-                                                 session->pSession,
-                                                 (ub4) 0); 
+       
+               CALL_OCI_RETURN(OCI(error), OCISessionEnd(
+                                       svchp, 
+                                       OCI(pError), 
+                                       session->pSession, 
+                                       (ub4) 0));
+
                if (OCI(error) != OCI_SUCCESS) {
                        oci_error(OCI(pError), "_oci_close_session: OCISessionEnd", OCI(error));
                }
 
-               OCIHandleFree((dvoid *) svchp, (ub4) OCI_HTYPE_SVCCTX);
+               CALL_OCI(OCIHandleFree(
+                                       (dvoid *) svchp, 
+                                       (ub4) OCI_HTYPE_SVCCTX));
 
        } else {
                oci_debug("_oci_close_session: logging-off DEAD session");
        }
 
        if (session->pSession) {
-               OCIHandleFree((dvoid *) session->pSession, (ub4) OCI_HTYPE_SESSION);
+               CALL_OCI(OCIHandleFree(
+                                       (dvoid *) session->pSession, 
+                                       (ub4) OCI_HTYPE_SESSION));
        }
 
        hashed_details = session->hashed_details;
@@ -2275,19 +2374,20 @@ static oci_server *_oci_open_server(char *dbname,int persistent)
 
        server->persistent = persistent;
        server->dbname = strdup(SAFE_STRING(dbname));
+
+       CALL_OCI(OCIHandleAlloc(
+                               OCI(pEnv), 
+                               (dvoid **)&server->pServer, 
+                               OCI_HTYPE_SERVER, 
+                               0, 
+                               NULL)); 
        
-       OCIHandleAlloc(OCI(pEnv), 
-                                  (dvoid **)&server->pServer, 
-                                  OCI_HTYPE_SERVER, 
-                                  0, 
-                                  NULL); 
-
-       OCI(error) = 
-               OCIServerAttach(server->pServer,
-                                               OCI(pError),
-                                               (text*)server->dbname,
-                                               strlen(server->dbname),
-                                               (ub4) OCI_DEFAULT);
+       CALL_OCI_RETURN(OCI(error), OCIServerAttach(
+                               server->pServer, 
+                               OCI(pError), 
+                               (text*)server->dbname, 
+                               strlen(server->dbname), 
+                               (ub4) OCI_DEFAULT));
 
        if (OCI(error)) {
                oci_error(OCI(pError), "_oci_open_server", OCI(error));
@@ -2372,10 +2472,11 @@ _oci_close_server(oci_server *server)
 
        if (server->is_open) {
                if (server->pServer && OCI(pError)) {
-                       OCI(error) = 
-                               OCIServerDetach(server->pServer,
-                                                               OCI(pError),
-                                                               OCI_DEFAULT);
+                       CALL_OCI_RETURN(
+                                       OCI(error), 
+                                       OCIServerDetach(server->pServer, 
+                                               OCI(pError), 
+                                               OCI_DEFAULT));
 
                        if (OCI(error)) {
                                oci_error(OCI(pError), "oci_close_server OCIServerDetach", OCI(error));
@@ -2386,7 +2487,9 @@ _oci_close_server(oci_server *server)
        }
 
        if (server->pServer) {
-               OCIHandleFree((dvoid *) server->pServer, (ub4) OCI_HTYPE_SERVER);
+               CALL_OCI(OCIHandleFree(
+                                       (dvoid *) server->pServer, 
+                                       (ub4) OCI_HTYPE_SERVER));
        }
 
        dbname = server->dbname;
@@ -2453,50 +2556,54 @@ static void oci_do_connect(INTERNAL_FUNCTION_PARAMETERS,int persistent,int exclu
        connection->session = session;
 
        /* allocate our private error-handle */
-       OCI(error) = 
-               OCIHandleAlloc(OCI(pEnv), 
-                                          (dvoid **)&connection->pError, 
-                                          OCI_HTYPE_ERROR, 
-                                          0, 
-                                          NULL);
+       CALL_OCI_RETURN(OCI(error), OCIHandleAlloc(
+                               OCI(pEnv), 
+                               (dvoid **)&connection->pError, 
+                               OCI_HTYPE_ERROR, 
+                               0, 
+                               NULL));
+
        if (OCI(error) != OCI_SUCCESS) {
                oci_error(OCI(pError), "oci_do_connect: OCIHandleAlloc OCI_HTYPE_ERROR",OCI(error));
                goto CLEANUP;
        }
 
        /* allocate our service-context */
-       OCI(error) = 
-               OCIHandleAlloc(OCI(pEnv), 
-                                          (dvoid **)&connection->pServiceContext, 
-                                          OCI_HTYPE_SVCCTX, 
-                                          0, 
-                                          NULL);
+       CALL_OCI_RETURN(OCI(error), OCIHandleAlloc(
+                               OCI(pEnv), 
+                               (dvoid **)&connection->pServiceContext, 
+                               OCI_HTYPE_SVCCTX, 
+                               0, 
+                               NULL));
+
        if (OCI(error) != OCI_SUCCESS) {
                oci_error(OCI(pError), "oci_do_connect: OCIHandleAlloc OCI_HTYPE_SVCCTX",OCI(error));
                goto CLEANUP;
        }
 
        /* Set the server handle in service handle */ 
-       connection->error = 
-               OCIAttrSet(connection->pServiceContext, 
-                                  OCI_HTYPE_SVCCTX,
-                                  server->pServer, 
-                                  0, 
-                                  OCI_ATTR_SERVER,
-                                  connection->pError);
+       CALL_OCI_RETURN(connection->error, OCIAttrSet(
+                               connection->pServiceContext, 
+                               OCI_HTYPE_SVCCTX, 
+                               server->pServer, 
+                               0, 
+                               OCI_ATTR_SERVER, 
+                               connection->pError));
+
        if (connection->error != OCI_SUCCESS) {
                oci_error(connection->pError, "oci_do_connect: OCIAttrSet OCI_ATTR_SERVER", connection->error);
                goto CLEANUP;
        }
 
        /* Set the Authentication handle in the service handle */
-       connection->error = 
-               OCIAttrSet(connection->pServiceContext, 
-                                  OCI_HTYPE_SVCCTX,
-                                  session->pSession,
-                                  0, 
-                                  OCI_ATTR_SESSION,
-                                  connection->pError);
+       CALL_OCI_RETURN(connection->error, OCIAttrSet(
+                               connection->pServiceContext, 
+                               OCI_HTYPE_SVCCTX, 
+                               session->pSession, 
+                               0, 
+                               OCI_ATTR_SESSION, 
+                               connection->pError));
+
        if (connection->error != OCI_SUCCESS) {
                oci_error(connection->pError, "oci_do_connect: OCIAttrSet OCI_ATTR_SESSION", connection->error);
                goto CLEANUP;
@@ -2615,9 +2722,9 @@ PHP_FUNCTION(ocibindbyname)
        oci_descriptor *descr;
 #ifdef WITH_COLLECTIONS
     oci_collection *coll;
-       int mode = OCI_DATA_AT_EXEC;
     dvoid *mycoll = 0;
 #endif
+       int mode = OCI_DATA_AT_EXEC;
        ub2     ocitype = SQLT_CHR; /* unterminated string */
     OCIStmt *mystmt = 0;
        dvoid *mydescr = 0;
@@ -2715,26 +2822,23 @@ PHP_FUNCTION(ocibindbyname)
        bindp->pStmt = mystmt;
        bindp->zval = *var;
        zval_add_ref(var); 
-
-       statement->error = 
-               OCIBindByName(statement->pStmt,                /* statement handle */
-                                         (OCIBind **)&bindp->pBind,       /* bind hdl (will alloc) */
-                                         statement->pError,               /* error handle */
-                                         (text*) (*name)->value.str.val,  /* placeholder name */                                         
-                                         (*name)->value.str.len,          /* placeholder length */
-                                         (dvoid *)0,                      /* in/out data */
-                                         value_sz, /* OCI_MAX_DATA_SIZE, */               /* max size of input/output data */
-                                         (ub2)ocitype,                    /* in/out data type */
-                                         (dvoid *)&bindp->indicator,      /* indicator (ignored) */
-                                         (ub2 *)0,                        /* size array (ignored) */
-                                         (ub2 *)&bindp->retcode,          /* return code (ignored) */
-                                         (ub4)0,                          /* maxarr_len (PL/SQL only?) */
-                                         (ub4 *)0,                        /* actual array size (PL/SQL only?) */
-#ifdef WITH_COLLECTIONS
-                                         mode                             /* mode */);
-#else
-                                         OCI_DATA_AT_EXEC                 /* mode */);
-#endif
+       
+       CALL_OCI_RETURN(statement->error, OCIBindByName(
+                               statement->pStmt,                /* statement handle */
+                           (OCIBind **)&bindp->pBind,       /* bind hdl (will alloc) */
+                           statement->pError,               /* error handle */
+                           (text*) (*name)->value.str.val,  /* placeholder name */                                       
+                           (*name)->value.str.len,          /* placeholder length */
+                           (dvoid *)0,                      /* in/out data */
+                           value_sz, /* OCI_MAX_DATA_SIZE, */               /* max size of input/output data */
+                           (ub2)ocitype,                    /* in/out data type */
+                           (dvoid *)&bindp->indicator,      /* indicator (ignored) */
+                           (ub2 *)0,                        /* size array (ignored) */
+                           (ub2 *)&bindp->retcode,          /* return code (ignored) */
+                           (ub4)0,                          /* maxarr_len (PL/SQL only?) */
+                           (ub4 *)0,                        /* actual array size (PL/SQL only?) */
+                           mode                             /* mode */
+                               ));
 
        if (statement->error != OCI_SUCCESS) {
                oci_error(statement->pError, "OCIBindByName", statement->error);
@@ -2742,34 +2846,34 @@ PHP_FUNCTION(ocibindbyname)
                RETURN_FALSE;
        }
 
-#ifdef WITH_COLLECTIONS
-       if(mode == OCI_DATA_AT_EXEC) {
-#endif
-       statement->error = 
-               OCIBindDynamic(bindp->pBind,
-                                          statement->pError,
-                                          (dvoid *)bindp,
-                                          oci_bind_in_callback,
-                                          (dvoid *)bindp,
-                                          oci_bind_out_callback);
+       if (mode == OCI_DATA_AT_EXEC) {
+               CALL_OCI_RETURN(statement->error, OCIBindDynamic(
+                                       bindp->pBind, 
+                                       statement->pError, 
+                                       (dvoid *)bindp, 
+                                       oci_bind_in_callback, 
+                                       (dvoid *)bindp, 
+                                       oci_bind_out_callback));
 
-       if (statement->error != OCI_SUCCESS) {
-               oci_error(statement->pError, "OCIBindDynamic", statement->error);
-               oci_handle_error(statement->conn, statement->error);
-               RETURN_FALSE;
-       }
-#ifdef WITH_COLLECTIONS
+               if (statement->error != OCI_SUCCESS) {
+                       oci_error(statement->pError, "OCIBindDynamic", statement->error);
+                       oci_handle_error(statement->conn, statement->error);
+                       RETURN_FALSE;
+               }
        }
-#endif 
 
 #ifdef WITH_COLLECTIONS
-       if(ocitype == SQLT_NTY) {
+       if (ocitype == SQLT_NTY) {
                /* Bind object */
-               statement->error = OCIBindObject(bindp->pBind, 
-                                                                                statement->pError,
-                                                                                coll->tdo, 
-                                                                                (dvoid **) &(coll->coll),
-                                                                                (ub4 *) 0, (dvoid **) 0, (ub4 *) 0);
+               CALL_OCI_RETURN(statement->error, OCIBindObject(
+                                       bindp->pBind, 
+                                       statement->pError, 
+                                       coll->tdo, 
+                                       (dvoid **) &(coll->coll), 
+                                       (ub4 *) 0, 
+                                       (dvoid **) 0, 
+                                       (ub4 *) 0));
+
                if (statement->error) {
                        oci_error(statement->pError, "OCIBindObject", statement->error);
                        RETURN_FALSE;
@@ -2838,11 +2942,11 @@ PHP_FUNCTION(ocisavelob)
                        convert_to_long_ex(oarg);
                        offparam = (*oarg)->value.lval;
 
-                       connection->error =
-                               OCILobGetLength(connection->pServiceContext,
-                                                               connection->pError,
-                                                               mylob,
-                                                               &curloblen);
+                       CALL_OCI_RETURN(connection->error, OCILobGetLength(
+                                               connection->pServiceContext, 
+                                               connection->pError, 
+                                               mylob, 
+                                               &curloblen));
 
                        oci_debug("OCIsavedesc: curloblen=%d",curloblen);
 
@@ -2867,8 +2971,8 @@ PHP_FUNCTION(ocisavelob)
                        RETURN_FALSE;
                }
 
-               connection->error = 
-                       OCILobWrite(connection->pServiceContext,
+               CALL_OCI_RETURN(connection->error, OCILobWrite(
+                                       connection->pServiceContext, 
                                        connection->pError,
                                        mylob,
                                        &loblen,
@@ -2879,7 +2983,7 @@ PHP_FUNCTION(ocisavelob)
                                        (dvoid *)0,
                                        (OCICallbackLobWrite) 0,
                                        (ub2) 0,
-                                       (ub1) SQLCS_IMPLICIT );
+                                       (ub1) SQLCS_IMPLICIT));
 
                oci_debug("OCIsavedesc: size=%d offset=%d",loblen,offset);
 
@@ -2943,19 +3047,19 @@ PHP_FUNCTION(ocisavelobfile)
         } 
 
                while ((loblen = read(fp, &buf, sizeof(buf))) > 0) {    
-                       connection->error = 
-                               OCILobWrite(connection->pServiceContext,
-                                                       connection->pError,
-                                                       mylob,
-                                                       &loblen,
-                                                       (ub4) offset,
-                                                       (dvoid *) &buf,
-                                                       (ub4) loblen,
-                                                       OCI_ONE_PIECE,
-                                                       (dvoid *)0,
-                                                       (OCICallbackLobWrite) 0,
-                                                       (ub2) 0,
-                                                       (ub1) SQLCS_IMPLICIT);
+                       CALL_OCI_RETURN(connection->error, OCILobWrite(
+                                               connection->pServiceContext, 
+                                               connection->pError, 
+                                               mylob, 
+                                               &loblen, 
+                                               (ub4) offset, 
+                                               (dvoid *) &buf, 
+                                               (ub4) loblen, 
+                                               OCI_ONE_PIECE, 
+                                               (dvoid *)0, 
+                                               (OCICallbackLobWrite) 0, 
+                                               (ub2) 0, 
+                                               (ub1) SQLCS_IMPLICIT));
 
                        oci_debug("OCIsavelob: size=%d",loblen);
 
@@ -3060,12 +3164,12 @@ PHP_FUNCTION(ociwritelobtofile)
                                goto bail;
                        } 
                }
-
-               connection->error = 
-                       OCILobGetLength(connection->pServiceContext,
-                                                       connection->pError,
-                                                       descr->ocidescr,
-                                                       &loblen);
+       
+               CALL_OCI_RETURN(connection->error, OCILobGetLength(
+                                       connection->pServiceContext, 
+                                       connection->pError, 
+                                       descr->ocidescr, 
+                                       &loblen));
 
                if (connection->error) {
                        oci_error(connection->pError, "OCILobGetLength", connection->error);
@@ -3074,11 +3178,12 @@ PHP_FUNCTION(ociwritelobtofile)
                }
                
                if (descr->type == OCI_DTYPE_FILE) {
-                       connection->error = 
-                               OCILobFileOpen(connection->pServiceContext,
-                                                          connection->pError,
-                                                          descr->ocidescr,
-                                                          OCI_FILE_READONLY);
+                       CALL_OCI_RETURN(connection->error, OCILobFileOpen(
+                                               connection->pServiceContext, 
+                                               connection->pError, 
+                                               descr->ocidescr, 
+                                               OCI_FILE_READONLY));
+
                        if (connection->error) {
                                oci_error(connection->pError, "OCILobFileOpen",connection->error);
                                oci_handle_error(connection, connection->error);
@@ -3117,18 +3222,18 @@ PHP_FUNCTION(ociwritelobtofile)
 
                        oci_debug("OCILobRead(coffs = %d, toread = %d",coffs,toread);
 
-                       connection->error = 
-                               OCILobRead(connection->pServiceContext, 
-                                                  connection->pError,
-                                                  descr->ocidescr,
-                                                  &toread,                                /* IN/OUT bytes toread/read */
-                                                  coffs+1,                                /* offset (starts with 1) */ 
-                                                  (dvoid *) buffer,    
-                                                  toread,                                 /* size of buffer */
-                                                  (dvoid *)0,
-                                                  (OCICallbackLobRead) 0, /* callback... */
-                                                  (ub2) 0,                        /* The character set ID of the buffer data. */
-                                                  (ub1) SQLCS_IMPLICIT);  /* The character set form of the buffer data. */
+                       CALL_OCI_RETURN(connection->error, OCILobRead(
+                                               connection->pServiceContext, 
+                                           connection->pError,
+                                           descr->ocidescr,
+                                           &toread,                            /* IN/OUT bytes toread/read */
+                                           coffs+1,                            /* offset (starts with 1) */ 
+                                           (dvoid *) buffer,
+                                           toread,                             /* size of buffer */
+                                           (dvoid *)0,
+                                           (OCICallbackLobRead) 0, /* callback... */
+                                           (ub2) 0,                            /* The character set ID of the buffer data. */
+                                           (ub1) SQLCS_IMPLICIT)); /* The character set form of the buffer data. */
                        
                        oci_debug("OCILobRead(read - %d",toread);
 
@@ -3160,10 +3265,11 @@ PHP_FUNCTION(ociwritelobtofile)
                }
 
                if (descr->type == OCI_DTYPE_FILE) {
-                       connection->error = 
-                               OCILobFileClose(connection->pServiceContext,
-                                                               connection->pError,
-                                                               descr->ocidescr);
+                       CALL_OCI_RETURN(connection->error,OCILobFileClose(
+                                               connection->pServiceContext, 
+                                               connection->pError, 
+                                               descr->ocidescr)); 
+                       
                        if (connection->error) {
                                oci_error(connection->pError, "OCILobFileClose", connection->error);
                                oci_handle_error(connection, connection->error);
@@ -3222,16 +3328,16 @@ PHP_FUNCTION(ociwritetemporarylob)
     }
 
     convert_to_string_ex(var);
-    
-    connection->error = 
-        OCILobCreateTemporary(connection->pServiceContext,
-                              connection->pError,
-                              mylob,
-                              OCI_DEFAULT,
-                              OCI_DEFAULT,
-                              OCI_TEMP_CLOB,
-                              TRUE,
-                              OCI_DURATION_SESSION);
+
+       CALL_OCI_RETURN(connection->error, OCILobCreateTemporary(
+                               connection->pServiceContext, 
+                               connection->pError, 
+                               mylob, 
+                               OCI_DEFAULT, 
+                               OCI_DEFAULT, 
+                               OCI_TEMP_CLOB, 
+                               TRUE, 
+                               OCI_DURATION_SESSION));
 
     if (connection->error) {
         oci_error(connection->pError, "OCILobCreateTemporary", connection->error);
@@ -3239,11 +3345,11 @@ PHP_FUNCTION(ociwritetemporarylob)
         RETURN_FALSE;
     }
 
-    connection->error = 
-        OCILobOpen(connection->pServiceContext,
-                   connection->pError,
-                   mylob,
-                   OCI_LOB_READWRITE);
+       CALL_OCI_RETURN(connection->error, OCILobOpen(
+                               connection->pServiceContext, 
+                               connection->pError, 
+                               mylob, 
+                               OCI_LOB_READWRITE));
 
     if (connection->error) {
         oci_error(connection->pError, "OCILobOpen", connection->error);
@@ -3259,19 +3365,19 @@ PHP_FUNCTION(ociwritetemporarylob)
         RETURN_FALSE;
     }
 
-    connection->error = 
-        OCILobWrite(connection->pServiceContext,
-                                       connection->pError,
-                                       mylob,
-                                       (ub4 *) &loblen,
-                                       (ub4) offset,
-                                       (dvoid *) (*var)->value.str.val,
-                                       (ub4) loblen,
-                                       OCI_ONE_PIECE,
-                                       (dvoid *)0,
-                    (sb4 (*)(dvoid *, dvoid *, ub4 *, ub1 *)) 0,
-                                       (ub2) 0,
-                                       (ub1) SQLCS_IMPLICIT );
+       CALL_OCI_RETURN(connection->error, OCILobWrite(
+                               connection->pServiceContext, 
+                               connection->pError, 
+                               mylob, 
+                               (ub4 *) &loblen, 
+                               (ub4) offset, 
+                               (dvoid *) (*var)->value.str.val, 
+                               (ub4) loblen, 
+                               OCI_ONE_PIECE, 
+                               (dvoid *)0, 
+                               (sb4 (*)(dvoid *, dvoid *, ub4 *, ub1 *)) 0, 
+                               (ub2) 0, 
+                               (ub1) SQLCS_IMPLICIT));
 
     if (connection->error) {
         oci_error(connection->pError, "OCILobWrite", connection->error);
@@ -3307,9 +3413,10 @@ PHP_FUNCTION(ocicloselob)
 
             connection = descriptor->conn;
 
-            connection->error = OCILobClose (connection->pServiceContext, 
-                                             connection->pError, 
-                                             mylob);
+                       CALL_OCI_RETURN(connection->error, OCILobClose(
+                                               connection->pServiceContext, 
+                                               connection->pError, 
+                                               mylob)); 
 
             if (connection->error) {
                 oci_error(connection->pError, "OCILobClose", connection->error);
@@ -3373,10 +3480,10 @@ PHP_FUNCTION(ocirollback)
 
        OCI_GET_CONN(connection,conn);
 
-       connection->error = 
-               OCITransRollback(connection->pServiceContext,
-                                                connection->pError, 
-                                                (ub4)0);
+       CALL_OCI_RETURN(connection->error, OCITransRollback(
+                               connection->pServiceContext, 
+                               connection->pError, 
+                               (ub4) 0));
 
        if (connection->error) {
                oci_error(connection->pError, "OCIRollback", connection->error);
@@ -3405,10 +3512,10 @@ PHP_FUNCTION(ocicommit)
 
     oci_debug("<OCITransCommit");
 
-       connection->error = 
-               OCITransCommit(connection->pServiceContext,
-                                          connection->pError, 
-                                          (ub4)0);
+       CALL_OCI_RETURN(connection->error, OCITransCommit(
+                               connection->pServiceContext, 
+                               connection->pError, 
+                               (ub4) 0));
 
     oci_debug(">OCITransCommit");
 
@@ -3472,9 +3579,9 @@ PHP_FUNCTION(ocicolumnsize)
                                  outcol->name,outcol->retlen,outcol->retlen4,outcol->data_size,outcol->storage_size4,outcol->indicator,outcol->retcode);
                
        /* Handle data type of LONG */
-       if(outcol->data_type == SQLT_LNG){
+       if (outcol->data_type == SQLT_LNG){
                RETURN_LONG(outcol->storage_size4);
-       }else{
+       } else {
                RETURN_LONG(outcol->data_size);
        }
 }
@@ -4012,7 +4119,14 @@ PHP_FUNCTION(ocierror)
                RETURN_FALSE;
        }
 
-       OCIErrorGet(errh,1,NULL,&errcode,errbuf,(ub4)sizeof(errbuf),(ub4)OCI_HTYPE_ERROR);
+       CALL_OCI(OCIErrorGet(
+                               errh,
+                               1,
+                               NULL,
+                               &errcode,
+                               errbuf,
+                               (ub4) sizeof(errbuf),
+                               (ub4) OCI_HTYPE_ERROR));
 
        if (errcode) {
                array_init(return_value);
@@ -4158,12 +4272,12 @@ PHP_FUNCTION(ociserverversion)
 
        OCI_GET_CONN(connection,conn);
 
-       connection->error = 
-               OCIServerVersion(connection->pServiceContext,
-                                                connection->pError, 
-                                                (text*)version, 
-                                                sizeof(version),
-                                                OCI_HTYPE_SVCCTX);
+       CALL_OCI_RETURN(connection->error, OCIServerVersion(
+                               connection->pServiceContext, 
+                               connection->pError, 
+                               (text*)version, 
+                               sizeof(version), 
+                               OCI_HTYPE_SVCCTX));
        
        if (connection->error != OCI_SUCCESS) {
                oci_error(connection->pError, "OCIServerVersion", connection->error);
@@ -4193,13 +4307,14 @@ PHP_FUNCTION(ocistatementtype)
 
        OCI_GET_STMT(statement,stmt);
 
-       statement->error = 
-               OCIAttrGet((dvoid *)statement->pStmt, 
-                                  OCI_HTYPE_STMT,
-                                  (ub2 *)&stmttype, 
-                                  (ub4 *)0, 
-                                  OCI_ATTR_STMT_TYPE,
-                                  statement->pError);
+       CALL_OCI_RETURN(statement->error, OCIAttrGet(
+                               (dvoid *)statement->pStmt, 
+                               OCI_HTYPE_STMT, 
+                               (ub2 *)&stmttype, 
+                               (ub4 *)0, 
+                               OCI_ATTR_STMT_TYPE, 
+                               statement->pError));
+
        if (statement->error != OCI_SUCCESS) {
                oci_error(statement->pError, "OCIStatementType", statement->error);
                oci_handle_error(statement->conn, statement->error);
@@ -4255,13 +4370,13 @@ PHP_FUNCTION(ocirowcount)
 
        OCI_GET_STMT(statement,stmt);
 
-       statement->error = 
-               OCIAttrGet((dvoid *)statement->pStmt, 
-                                  OCI_HTYPE_STMT,
-                                  (ub2 *)&rowcount, 
-                                  (ub4 *)0, 
-                                  OCI_ATTR_ROW_COUNT,
-                                  statement->pError);
+       CALL_OCI_RETURN(statement->error, OCIAttrGet(
+                               (dvoid *)statement->pStmt, 
+                               OCI_HTYPE_STMT, 
+                               (ub2 *)&rowcount, 
+                               (ub4 *)0, 
+                               OCI_ATTR_ROW_COUNT,
+                               statement->pError));
 
        if (statement->error != OCI_SUCCESS) {
                oci_error(statement->pError, "OCIRowCount", statement->error);
@@ -4311,10 +4426,13 @@ PHP_FUNCTION(ocifreecollection)
                         */
                        connection = coll->conn;
             oci_debug("OCIfreecollection: coll=%d",inx);
-                       connection->error = OCIObjectFree(OCI(pEnv),
-                                                                                         connection->pError,
-                                                                                         (dvoid *)coll->coll,
-                                                                                         (ub2)(OCI_OBJECTFREE_FORCE));
+
+                       CALL_OCI_RETURN(connection->error, OCIObjectFree(
+                                               OCI(pEnv), 
+                                               connection->pError, 
+                                               (dvoid *)coll->coll, 
+                                               (ub2)(OCI_OBJECTFREE_FORCE)));
+
                        if (connection->error) {
                                oci_error(connection->pError, "OCIObjectFree", connection->error);
                                RETURN_FALSE;
@@ -4357,19 +4475,29 @@ PHP_FUNCTION(ocicollappend)
                switch(coll->element_typecode) {
                   case OCI_TYPECODE_DATE:
                           convert_to_string_ex(arg);
-                          connection->error = OCIDateFromText(connection->pError,
-                                                                                                  (*arg)->value.str.val,
-                                                                                                  (*arg)->value.str.len,
-                                                                                                  0,0,0,0,&dt);
+
+                          CALL_OCI_RETURN(connection->error, OCIDateFromText(
+                                                  connection->pError, 
+                                                  (*arg)->value.str.val, 
+                                                  (*arg)->value.str.len, 
+                                                  0,
+                                                  0,
+                                                  0,
+                                                  0,
+                                                  &dt));
+
                           if (connection->error) {
                                   oci_error(connection->pError, "OCIDateFromText", connection->error);
                                   RETURN_FALSE;
                           }
-                          connection->error = OCICollAppend(OCI(pEnv), 
-                                                                                                connection->pError, 
-                                                                                                (dvoid *) &dt,
-                                                                                                (dvoid *) &new_ind,
-                                                                                                (OCIColl *) coll->coll);               
+
+                          CALL_OCI_RETURN(connection->error, OCICollAppend(
+                                                  OCI(pEnv), 
+                                                  connection->pError, 
+                                                  (dvoid *) &dt, 
+                                                  (dvoid *) &new_ind, 
+                                                  (OCIColl *) coll->coll));
+
                           if (connection->error) {
                                   oci_error(connection->pError, "OCICollAppend", connection->error);
                                   RETURN_FALSE;
@@ -4378,20 +4506,26 @@ PHP_FUNCTION(ocicollappend)
                           break;
                   case OCI_TYPECODE_VARCHAR2 :
                           convert_to_string_ex(arg);
-                          connection->error = OCIStringAssignText(OCI(pEnv),
-                                                                                                          connection->pError,
-                                                                                                          (*arg)->value.str.val,
-                                                                                                          (*arg)->value.str.len,
-                                                                                                          &ocistr);
+
+                          CALL_OCI_RETURN(connection->error, OCIStringAssignText(
+                                                  OCI(pEnv), 
+                                                  connection->pError, 
+                                                  (*arg)->value.str.val, 
+                                                  (*arg)->value.str.len, 
+                                                  &ocistr));
+
                           if (connection->error) {
                                   oci_error(connection->pError, "OCIStringAssignText", connection->error);
                                   RETURN_FALSE;
                           }
-                          connection->error = OCICollAppend(OCI(pEnv), 
-                                                                                                connection->pError, 
-                                                                                                (dvoid *) ocistr,
-                                                                                                (dvoid *) &new_ind,
-                                                                                                (OCIColl *) coll->coll);               
+
+                          CALL_OCI_RETURN(connection->error, OCICollAppend(
+                                                  OCI(pEnv), 
+                                                  connection->pError, 
+                                                  (dvoid *) ocistr, 
+                                                  (dvoid *) &new_ind, 
+                                                  (OCIColl *) coll->coll));
+
                           if (connection->error) {
                                   oci_error(connection->pError, "OCICollAppend", connection->error);
                                   RETURN_FALSE;
@@ -4411,18 +4545,24 @@ PHP_FUNCTION(ocicollappend)
                   case OCI_TYPECODE_SMALLINT :                                /* SMALLINT */
                           convert_to_double_ex(arg);
                           ndx = (double)(*arg)->value.dval;
-                          connection->error = OCINumberFromReal(connection->pError,&ndx,
-                                                                                                        sizeof(double),&num);
+
+                          CALL_OCI_RETURN(connection->error, OCINumberFromReal(
+                                                  connection->pError,
+                                                  &ndx, 
+                                                  sizeof(double),&num));
+
                           if (connection->error) {
                                   oci_error(connection->pError, "OCINumberFromReal", connection->error);
                                   RETURN_FALSE;
                           }
 
-                          connection->error = OCICollAppend(OCI(pEnv), 
-                                                                                                connection->pError, 
-                                                                                                (dvoid *) &num,
-                                                                                                (dvoid *) &new_ind,
-                                                                                                (OCIColl *) coll->coll);               
+                          CALL_OCI_RETURN(connection->error, OCICollAppend(
+                                                  OCI(pEnv), 
+                                                  connection->pError, 
+                                                  (dvoid *) &num, 
+                                                  (dvoid *) &new_ind, 
+                                                  (OCIColl *) coll->coll));
+
                           RETURN_TRUE;
                           break;
                }
@@ -4464,31 +4604,37 @@ PHP_FUNCTION(ocicollgetelem)
 
                connection = coll->conn;
 
-               connection->error = OCICollGetElem(OCI(pEnv),
-                                                                                  connection->pError,
-                                                                                  coll->coll,
-                                                                                  ndx,
-                                                                                  &exists,
-                                                                                  &elem,
-                                                                                  &elemind);
+               CALL_OCI_RETURN(connection->error, OCICollGetElem(
+                                       OCI(pEnv), 
+                                       connection->pError, 
+                                       coll->coll, 
+                                       ndx, 
+                                       &exists, 
+                                       &elem, 
+                                       &elemind));
+
                if (connection->error) {
                        oci_error(connection->pError, "OCICollGetElem", connection->error);
                        RETURN_FALSE;
                }
-               switch(coll->element_typecode) {
+
+               switch (coll->element_typecode) {
                   case OCI_TYPECODE_DATE:
                           len = 1024;
-                          OCIDateToText(connection->pError,
-                                                        elem,
-                                                        0, /* fmt */
-                                                        0, /* fmt_length */
-                                                        0, /* lang_name */
-                                                        0, /* lang_length */
-                                                        &len,buff);
+                          CALL_OCI(OCIDateToText(
+                                                  connection->pError, 
+                                                  elem, 
+                                                  0, /* fmt */ 
+                                                  0, /* fmt_length */ 
+                                                  0, /* lang_name */ 
+                                                  0, /* lang_length */ 
+                                                  &len,
+                                                  buff));
+
                           RETURN_STRINGL(buff,len,1);
                   case OCI_TYPECODE_VARCHAR2 :
                           ocistr = *(OCIString **)elem;
-                          str = OCIStringPtr(OCI(pEnv),ocistr);
+                          str = OCIStringPtr(OCI(pEnv),ocistr); /* XXX not protected against recursion! */
                           RETURN_STRINGL(str,strlen(str),1);
                           break;
                   case OCI_TYPECODE_UNSIGNED16 :                       /* UNSIGNED SHORT  */
@@ -4502,9 +4648,12 @@ PHP_FUNCTION(ocicollgetelem)
                   case OCI_TYPECODE_FLOAT :                            /* FLOAT    */
                   case OCI_TYPECODE_NUMBER :                           /* NUMBER   */
                   case OCI_TYPECODE_SMALLINT :                         /* SMALLINT */
-                          connection->error = OCINumberToReal(connection->pError, 
-                                                                                                  (CONST OCINumber *) elem,
-                                                                                                  (uword) sizeof(dnum), (dvoid *) &dnum);
+                          CALL_OCI_RETURN(connection->error, OCINumberToReal(
+                                                  connection->pError, 
+                                                  (CONST OCINumber *) elem, 
+                                                  (uword) sizeof(dnum), 
+                                                  (dvoid *) &dnum));
+
                           if (connection->error) {
                                   oci_error(connection->pError, "OCINumberToReal", connection->error);
                                   RETURN_FALSE;
@@ -4542,9 +4691,13 @@ PHP_FUNCTION(ocicollassign)
                }
 
                connection = coll->conn;
+       
+               CALL_OCI_RETURN(connection->error, OCICollAssign(
+                                       OCI(pEnv),
+                                       connection->pError, 
+                                       from_coll->coll,
+                                       coll->coll));
 
-               connection->error = OCICollAssign(OCI(pEnv),connection->pError,
-                                                                                 from_coll->coll,coll->coll);
                if (connection->error) {
                        oci_error(connection->pError, "OCICollAssignElem", connection->error);
                        RETURN_FALSE;
@@ -4593,20 +4746,29 @@ PHP_FUNCTION(ocicollassignelem)
                switch(coll->element_typecode) {
                   case OCI_TYPECODE_DATE:
                           convert_to_string_ex(val);
-                          connection->error = OCIDateFromText(connection->pError,
-                                                                                                  (*val)->value.str.val,
-                                                                                                  (*val)->value.str.len,
-                                                                                                  0,0,0,0,&dt);
+                          CALL_OCI_RETURN(connection->error, OCIDateFromText(
+                                                  connection->pError, 
+                                                  (*val)->value.str.val, 
+                                                  (*val)->value.str.len, 
+                                                  0,
+                                                  0,
+                                                  0,
+                                                  0,
+                                                  &dt));
+
                           if (connection->error) {
                                   oci_error(connection->pError, "OCIDateFromText", connection->error);
                                   RETURN_FALSE;
                           }
-                          connection->error = OCICollAssignElem(OCI(pEnv),
-                                                                                                        connection->pError,
-                                                                                                        ndx,
-                                                                                                        (dword *)&dt,
-                                                                                                        &new_ind,
-                                                                                                        coll->coll);
+
+                          CALL_OCI_RETURN(connection->error, OCICollAssignElem(
+                                                  OCI(pEnv), 
+                                                  connection->pError, 
+                                                  ndx, 
+                                                  (dword *)&dt, 
+                                                  &new_ind, 
+                                                  coll->coll));
+
                           if (connection->error) {
                                   oci_error(connection->pError, "OCICollAssignElem", connection->error);
                                   RETURN_FALSE;
@@ -4614,21 +4776,27 @@ PHP_FUNCTION(ocicollassignelem)
                           break;
                   case OCI_TYPECODE_VARCHAR2 :
                           convert_to_string_ex(val);
-                          connection->error = OCIStringAssignText(OCI(pEnv),
-                                                                                                          connection->pError,
-                                                                                                          (*val)->value.str.val,
-                                                                                                          (*val)->value.str.len,
-                                                                                                          &ocistr);
+
+                          CALL_OCI_RETURN(connection->error, OCIStringAssignText(
+                                                  OCI(pEnv), 
+                                                  connection->pError, 
+                                                  (*val)->value.str.val, 
+                                                  (*val)->value.str.len, 
+                                                  &ocistr));
+
                           if (connection->error) {
                                   oci_error(connection->pError, "OCIStringAssignText", connection->error);
                                   RETURN_FALSE;
                           }
-                          connection->error = OCICollAssignElem(OCI(pEnv),
-                                                                                                        connection->pError,
-                                                                                                        ndx,
-                                                                                                        (dword *)ocistr,
-                                                                                                        &new_ind,
-                                                                                                        coll->coll);
+
+                          CALL_OCI_RETURN(connection->error, OCICollAssignElem(
+                                                  OCI(pEnv), 
+                                                  connection->pError, 
+                                                  ndx, 
+                                                  (dword *)ocistr, 
+                                                  &new_ind, 
+                                                  coll->coll));
+
                           if (connection->error) {
                                   oci_error(connection->pError, "OCICollAssignElem", connection->error);
                                   RETURN_FALSE;
@@ -4648,18 +4816,26 @@ PHP_FUNCTION(ocicollassignelem)
                   case OCI_TYPECODE_SMALLINT :                         /* SMALLINT */
                           convert_to_double_ex(val);
                           dnum = (double)(*val)->value.dval;
-                          connection->error = OCINumberFromReal(connection->pError,&dnum,
-                                                                                                        sizeof(double),&num);
+
+                          CALL_OCI_RETURN(connection->error, OCINumberFromReal(
+                                                  connection->pError,
+                                                  &dnum, 
+                                                  sizeof(double),
+                                                  &num));
+
                           if (connection->error) {
                                   oci_error(connection->pError, "OCINumberFromReal", connection->error);
                                   RETURN_FALSE;
                           }
-                          connection->error = OCICollAssignElem(OCI(pEnv),
-                                                                                                        connection->pError,
-                                                                                                        ndx,
-                                                                                                        (dword *)&num,
-                                                                                                        &new_ind,
-                                                                                                        coll->coll);
+
+                          CALL_OCI_RETURN(connection->error, OCICollAssignElem(
+                                                  OCI(pEnv), 
+                                                  connection->pError, 
+                                                  ndx, 
+                                                  (dword *)&num, 
+                                                  &new_ind, 
+                                                  coll->coll));
+
                           if (connection->error) {
                                   oci_error(connection->pError, "OCICollAssignElem", connection->error);
                                   RETURN_FALSE;
@@ -4688,7 +4864,13 @@ PHP_FUNCTION(ocicollsize)
                        RETURN_FALSE;
                }
                connection = coll->conn;
-               connection->error = OCICollSize(OCI(pEnv),coll->conn->pError,coll->coll,&sz);
+
+               CALL_OCI_RETURN(connection->error, OCICollSize(
+                                       OCI(pEnv),
+                                       coll->conn->pError,
+                                       coll->coll,
+                                       &sz));
+
                if (connection->error) {
                        oci_error(connection->pError, "OCICollSize", connection->error);
                        RETURN_FALSE;
@@ -4714,7 +4896,8 @@ PHP_FUNCTION(ocicollmax)
                if ((inx = _oci_get_ocicoll(id,&coll TSRMLS_CC)) == 0) {
                        RETURN_FALSE;
                }
-               sz = OCICollMax(OCI(pEnv),coll->coll);
+               sz = OCICollMax(OCI(pEnv),coll->coll); /* XXX not protected against recursion */
+
                RETURN_LONG(sz);
        }
        RETURN_FALSE;
@@ -4738,7 +4921,13 @@ PHP_FUNCTION(ocicolltrim)
                        WRONG_PARAM_COUNT;
                }
                convert_to_long_ex(arg);
-               coll->conn->error = OCICollTrim(OCI(pEnv),coll->conn->pError,(*arg)->value.lval,coll->coll);
+
+               CALL_OCI_RETURN(coll->conn->error, OCICollTrim(
+                                       OCI(pEnv),
+                                       coll->conn->pError,
+                                       (*arg)->value.lval,
+                                       coll->coll));
+
                if (coll->conn->error) {
                        oci_error(coll->conn->pError, "OCICollTrim", coll->conn->error);
                        RETURN_FALSE;
@@ -4780,51 +4969,75 @@ PHP_FUNCTION(ocinewcollection)
        coll->id = zend_list_insert(coll,le_coll);
        zend_list_addref(connection->id);
 
-       connection->error = OCITypeByName(OCI(pEnv),
-                                                                         connection->pError,
-                                                                         connection->pServiceContext,
-                                                                         ac==3?(text *)(*schema)->value.str.val:(text *)0,
-                                                                         ac==3?(ub4)(*schema)->value.str.len: (ub4)0,
-                                                                         (text *) (*tdo)->value.str.val,
-                                                                         (ub4)    (*tdo)->value.str.len,
-                                                                         (CONST text *) 0, (ub4) 0,
-                                                                         OCI_DURATION_SESSION,
-                                                                         OCI_TYPEGET_ALL,
-                                                                         &(coll->tdo));
+       CALL_OCI_RETURN(connection->error, OCITypeByName(
+                               OCI(pEnv), 
+                               connection->pError, 
+                               connection->pServiceContext, 
+                               ac==3?(text *)(*schema)->value.str.val:(text *)0, 
+                               ac==3?(ub4)(*schema)->value.str.len: (ub4)0, 
+                               (text *) (*tdo)->value.str.val, 
+                               (ub4)    (*tdo)->value.str.len, 
+                               (CONST text *) 0, 
+                               (ub4) 0, 
+                               OCI_DURATION_SESSION, 
+                               OCI_TYPEGET_ALL, 
+                               &(coll->tdo)));
+
     if (connection->error) {
         oci_error(connection->pError, "OCITypeByName", connection->error);
         RETURN_FALSE;
     }
 
-       connection->error = OCIHandleAlloc(OCI(pEnv), (dvoid **) &dschp1,
-                                                                          (ub4) OCI_HTYPE_DESCRIBE,
-                                                                          (size_t) 0, (dvoid **) 0);
+       CALL_OCI_RETURN(connection->error, OCIHandleAlloc(
+                               OCI(pEnv), 
+                               (dvoid **) &dschp1, 
+                               (ub4) OCI_HTYPE_DESCRIBE, 
+                               (size_t) 0, 
+                               (dvoid **) 0)); 
 
     if (connection->error) {
         oci_error(connection->pError, "OCI_HTYPE_DESCRIBE", connection->error);
         RETURN_FALSE;
     }
-       connection->error = OCIDescribeAny(connection->pServiceContext, connection->pError, (dvoid *) coll->tdo,
-                                                                          (ub4) 0, OCI_OTYPE_PTR, (ub1)1,
-                                                                          (ub1) OCI_PTYPE_TYPE, dschp1);
+
+       CALL_OCI_RETURN(connection->error, OCIDescribeAny(
+                               connection->pServiceContext, 
+                               connection->pError, 
+                               (dvoid *) coll->tdo, 
+                               (ub4) 0, 
+                               OCI_OTYPE_PTR, 
+                               (ub1)1, 
+                               (ub1) OCI_PTYPE_TYPE, 
+                               dschp1));
+
     if (connection->error) {
         oci_error(connection->pError, "OCI_OTYPE_PTR", connection->error);
         RETURN_FALSE;
     }
 
-       connection->error = OCIAttrGet((dvoid *) dschp1,
-                                                                  (ub4) OCI_HTYPE_DESCRIBE,
-                                                                  (dvoid *)&parmp1, (ub4 *)0, (ub4)OCI_ATTR_PARAM,connection->pError);
+       CALL_OCI_RETURN(connection->error, OCIAttrGet(
+                               (dvoid *) dschp1, 
+                               (ub4) OCI_HTYPE_DESCRIBE, 
+                               (dvoid *)&parmp1, 
+                               (ub4 *)0, 
+                               (ub4)OCI_ATTR_PARAM,
+                               connection->pError));
+
     if (connection->error) {
         oci_error(connection->pError, "OCI_ATTR_PARAM", connection->error);
         RETURN_FALSE;
     }
 
        /* get the collection type code of the attribute */
-       connection->error = OCIAttrGet((dvoid*) parmp1, (ub4) OCI_DTYPE_PARAM,
-                                                                  (dvoid*) &(coll->coll_typecode), (ub4 *) 0,
-                                                                  (ub4) OCI_ATTR_COLLECTION_TYPECODE,
-                                                                  connection->pError);
+
+       CALL_OCI_RETURN(connection->error, OCIAttrGet(
+                               (dvoid*) parmp1, 
+                               (ub4) OCI_DTYPE_PARAM, 
+                               (dvoid*) &(coll->coll_typecode), 
+                               (ub4 *) 0, 
+                               (ub4) OCI_ATTR_COLLECTION_TYPECODE, 
+                               connection->pError));
+
     if (connection->error) {
         oci_error(connection->pError, "OCI_ATTR_COLLECTION_TYPECODE", connection->error);
         RETURN_FALSE;
@@ -4833,37 +5046,53 @@ PHP_FUNCTION(ocinewcollection)
        switch(coll->coll_typecode) {
           case OCI_TYPECODE_VARRAY:
           case OCI_TYPECODE_TABLE:
-                  connection->error = OCIAttrGet((dvoid*) parmp1,
-                                                                                 (ub4) OCI_DTYPE_PARAM,
-                                                                                 (dvoid*) &parmp2, (ub4 *) 0,
-                                                                                 (ub4) OCI_ATTR_COLLECTION_ELEMENT,
-                                                                                 connection->pError);
+                  CALL_OCI_RETURN(connection->error, OCIAttrGet(
+                                          (dvoid*) parmp1, 
+                                          (ub4) OCI_DTYPE_PARAM, 
+                                          (dvoid*) &parmp2, 
+                                          (ub4 *) 0, 
+                                          (ub4) OCI_ATTR_COLLECTION_ELEMENT, 
+                                          connection->pError));
+
                   if (connection->error) {
                           oci_error(connection->pError, "OCI_ATTR_COLLECTION_ELEMENT", connection->error);
                           RETURN_FALSE;
                   }
-                  connection->error =  OCIAttrGet((dvoid*) parmp2,
-                                                                                  (ub4) OCI_DTYPE_PARAM,
-                                                                                  (dvoid*) &(coll->elem_ref), (ub4 *) 0,
-                                                                                  (ub4) OCI_ATTR_REF_TDO,
-                                                                                  connection->pError);
+
+                  CALL_OCI_RETURN(connection->error, OCIAttrGet(
+                                          (dvoid*) parmp2, 
+                                          (ub4) OCI_DTYPE_PARAM, 
+                                          (dvoid*) &(coll->elem_ref), 
+                                          (ub4 *) 0, 
+                                          (ub4) OCI_ATTR_REF_TDO, 
+                                          connection->pError));
+
                   if (connection->error) {
                           oci_error(connection->pError, "OCI_ATTR_REF_TDO", connection->error);
                           RETURN_FALSE;
                   }
-                  connection->error = OCITypeByRef(OCI(pEnv), connection->pError, coll->elem_ref,
-                                                                                       OCI_DURATION_SESSION,
-                                                                                       OCI_TYPEGET_HEADER, &(coll->element_type));
+
+                  CALL_OCI_RETURN(connection->error, OCITypeByRef(
+                                          OCI(pEnv), 
+                                          connection->pError, 
+                                          coll->elem_ref, 
+                                          OCI_DURATION_SESSION, 
+                                          OCI_TYPEGET_HEADER, 
+                                          &(coll->element_type)));
+
                   if (connection->error) {
                           oci_error(connection->pError, "OCI_TYPEGET_HEADER", connection->error);
                           RETURN_FALSE;
                   }
 
-                  connection->error =  OCIAttrGet((dvoid*) parmp2,
-                                                                                  (ub4) OCI_DTYPE_PARAM,
-                                                                                  (dvoid*) &(coll->element_typecode), (ub4 *) 0,
-                                                                                  (ub4) OCI_ATTR_TYPECODE,
-                                                                                  connection->pError);
+                  CALL_OCI_RETURN(connection->error, OCIAttrGet(
+                                          (dvoid*) parmp2, 
+                                          (ub4) OCI_DTYPE_PARAM, 
+                                          (dvoid*) &(coll->element_typecode), 
+                                          (ub4 *) 0, 
+                                          (ub4) OCI_ATTR_TYPECODE, 
+                                          connection->pError));
+
                   if (connection->error) {
                           oci_error(connection->pError, "OCI_ATTR_TYPECODE", connection->error);
                           RETURN_FALSE;
@@ -4871,18 +5100,21 @@ PHP_FUNCTION(ocinewcollection)
                   break;
           default:
                   php_error(E_WARNING, "OCINewCollection - Unknown Type %d", coll->coll_typecode);
+                  break;
        }    
 
        /* Create object to hold return table */
-       connection->error = OCIObjectNew(OCI(pEnv), 
-                                                                        connection->pError, 
-                                                                        connection->pServiceContext, 
-                                                                        OCI_TYPECODE_TABLE,
-                                                                        coll->tdo, 
-                                                                        (dvoid *)0, 
-                                                                        OCI_DURATION_DEFAULT,
-                                                                        TRUE, 
-                                                                        (dvoid **) &(coll->coll));
+       CALL_OCI_RETURN(connection->error, OCIObjectNew(
+                               OCI(pEnv), 
+                               connection->pError, 
+                               connection->pServiceContext, 
+                               OCI_TYPECODE_TABLE, 
+                               coll->tdo, 
+                               (dvoid *)0, 
+                               OCI_DURATION_DEFAULT, 
+                               TRUE, 
+                               (dvoid **) &(coll->coll)));
+
        if (connection->error) {
                oci_error(connection->pError, "OCIObjectNew", connection->error);
                RETURN_FALSE;