Skip to content

Commit 4b778fa

Browse files
committed
Make oci_set_*($connection,...) errors retrievable via oci_error($connection).
Improve some error handling to produce error text on some rare edge cases. Disambiguate the Oracle library function call return status values from ORA error numbers. Review and unify error data types.
1 parent 6ece550 commit 4b778fa

File tree

8 files changed

+527
-402
lines changed

8 files changed

+527
-402
lines changed

ext/oci8/oci8.c

Lines changed: 64 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1643,12 +1643,12 @@ void php_oci_connection_descriptors_free(php_oci_connection *connection TSRMLS_D
16431643
* Fetch & print out error message if we get an error
16441644
* Returns an Oracle error number
16451645
*/
1646-
sb4 php_oci_error(OCIError *err_p, sword status TSRMLS_DC)
1646+
sb4 php_oci_error(OCIError *err_p, sword errstatus TSRMLS_DC)
16471647
{
16481648
text *errbuf = (text *)NULL;
1649-
sb4 errcode = 0;
1649+
sb4 errcode = 0; /* Oracle error number */
16501650

1651-
switch (status) {
1651+
switch (errstatus) {
16521652
case OCI_SUCCESS:
16531653
break;
16541654
case OCI_SUCCESS_WITH_INFO:
@@ -1691,13 +1691,13 @@ sb4 php_oci_error(OCIError *err_p, sword status TSRMLS_DC)
16911691
php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_CONTINUE");
16921692
break;
16931693
default:
1694-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown OCI error code: %d", status);
1694+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown OCI error code: %d", errstatus);
16951695
break;
16961696
}
16971697

16981698
#ifdef HAVE_OCI8_DTRACE
16991699
if (DTRACE_OCI8_ERROR_ENABLED()) {
1700-
DTRACE_OCI8_ERROR(status, errcode);
1700+
DTRACE_OCI8_ERROR((int)errstatus, (long)errcode);
17011701
}
17021702
#endif /* HAVE_OCI8_DTRACE */
17031703

@@ -2210,20 +2210,24 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char
22102210
*/
22112211
static int php_oci_connection_ping(php_oci_connection *connection TSRMLS_DC)
22122212
{
2213+
sword errstatus;
2214+
2215+
OCI_G(errcode) = 0; /* assume ping is successful */
2216+
22132217
/* Use OCIPing instead of OCIServerVersion. If OCIPing returns ORA-1010 (invalid OCI operation)
22142218
* such as from Pre-10.1 servers, the error is still from the server and we would have
22152219
* successfully performed a roundtrip and validated the connection. Use OCIServerVersion for
22162220
* Pre-10.2 clients
22172221
*/
22182222
#if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2))) /* OCIPing available 10.2 onwards */
2219-
PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIPing, (connection->svc, OCI_G(err), OCI_DEFAULT));
2223+
PHP_OCI_CALL_RETURN(errstatus, OCIPing, (connection->svc, OCI_G(err), OCI_DEFAULT));
22202224
#else
22212225
char version[256];
22222226
/* use good old OCIServerVersion() */
2223-
PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIServerVersion, (connection->svc, OCI_G(err), (text *)version, sizeof(version), OCI_HTYPE_SVCCTX));
2227+
PHP_OCI_CALL_RETURN(errstatus, OCIServerVersion, (connection->svc, OCI_G(err), (text *)version, sizeof(version), OCI_HTYPE_SVCCTX));
22242228
#endif
22252229

2226-
if (OCI_G(errcode) == OCI_SUCCESS) {
2230+
if (errstatus == OCI_SUCCESS) {
22272231
return 1;
22282232
} else {
22292233
sb4 error_code = 0;
@@ -2234,10 +2238,9 @@ static int php_oci_connection_ping(php_oci_connection *connection TSRMLS_DC)
22342238
if (error_code == 1010) {
22352239
return 1;
22362240
}
2241+
OCI_G(errcode) = error_code;
22372242
}
22382243

2239-
/* ignore errors here, just return failure
2240-
* php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); */
22412244
return 0;
22422245
}
22432246
/* }}} */
@@ -2248,17 +2251,17 @@ static int php_oci_connection_ping(php_oci_connection *connection TSRMLS_DC)
22482251
*/
22492252
static int php_oci_connection_status(php_oci_connection *connection TSRMLS_DC)
22502253
{
2251-
ub4 ss = 0;
2254+
ub4 ss = OCI_SERVER_NOT_CONNECTED;
2255+
sword errstatus;
22522256

22532257
/* get OCI_ATTR_SERVER_STATUS */
2254-
PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)connection->server, OCI_HTYPE_SERVER, (dvoid *)&ss, (ub4 *)0, OCI_ATTR_SERVER_STATUS, OCI_G(err)));
2258+
PHP_OCI_CALL_RETURN(errstatus, OCIAttrGet, ((dvoid *)connection->server, OCI_HTYPE_SERVER, (dvoid *)&ss, (ub4 *)0, OCI_ATTR_SERVER_STATUS, OCI_G(err)));
22552259

2256-
if (OCI_G(errcode) == OCI_SUCCESS && ss == OCI_SERVER_NORMAL) {
2260+
if (errstatus == OCI_SUCCESS && ss == OCI_SERVER_NORMAL) {
22572261
return 1;
22582262
}
22592263

2260-
/* ignore errors here, just return failure
2261-
* php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC); */
2264+
/* ignore errors here, just return failure */
22622265
return 0;
22632266
}
22642267
/* }}} */
@@ -2269,14 +2272,17 @@ static int php_oci_connection_status(php_oci_connection *connection TSRMLS_DC)
22692272
*/
22702273
int php_oci_connection_rollback(php_oci_connection *connection TSRMLS_DC)
22712274
{
2272-
PHP_OCI_CALL_RETURN(connection->errcode, OCITransRollback, (connection->svc, connection->err, (ub4) 0));
2275+
sword errstatus;
2276+
2277+
PHP_OCI_CALL_RETURN(errstatus, OCITransRollback, (connection->svc, connection->err, (ub4) 0));
22732278
connection->rb_on_disconnect = 0;
22742279

2275-
if (connection->errcode != OCI_SUCCESS) {
2276-
connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC);
2280+
if (errstatus != OCI_SUCCESS) {
2281+
connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
22772282
PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
22782283
return 1;
22792284
}
2285+
connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
22802286
return 0;
22812287
}
22822288
/* }}} */
@@ -2287,14 +2293,17 @@ int php_oci_connection_rollback(php_oci_connection *connection TSRMLS_DC)
22872293
*/
22882294
int php_oci_connection_commit(php_oci_connection *connection TSRMLS_DC)
22892295
{
2290-
PHP_OCI_CALL_RETURN(connection->errcode, OCITransCommit, (connection->svc, connection->err, (ub4) 0));
2296+
sword errstatus;
2297+
2298+
PHP_OCI_CALL_RETURN(errstatus, OCITransCommit, (connection->svc, connection->err, (ub4) 0));
22912299
connection->rb_on_disconnect = 0;
22922300

2293-
if (connection->errcode != OCI_SUCCESS) {
2294-
connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC);
2301+
if (errstatus != OCI_SUCCESS) {
2302+
connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
22952303
PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
22962304
return 1;
22972305
}
2306+
connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
22982307
return 0;
22992308
}
23002309
/* }}} */
@@ -2462,13 +2471,16 @@ int php_oci_connection_release(php_oci_connection *connection TSRMLS_DC)
24622471
*/
24632472
int php_oci_password_change(php_oci_connection *connection, char *user, int user_len, char *pass_old, int pass_old_len, char *pass_new, int pass_new_len TSRMLS_DC)
24642473
{
2465-
PHP_OCI_CALL_RETURN(connection->errcode, OCIPasswordChange, (connection->svc, connection->err, (text *)user, user_len, (text *)pass_old, pass_old_len, (text *)pass_new, pass_new_len, OCI_DEFAULT));
2474+
sword errstatus;
2475+
2476+
PHP_OCI_CALL_RETURN(errstatus, OCIPasswordChange, (connection->svc, connection->err, (text *)user, user_len, (text *)pass_old, pass_old_len, (text *)pass_new, pass_new_len, OCI_DEFAULT));
24662477

2467-
if (connection->errcode != OCI_SUCCESS) {
2468-
connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC);
2478+
if (errstatus != OCI_SUCCESS) {
2479+
connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
24692480
PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
24702481
return 1;
24712482
}
2483+
connection->errcode = 0; /* retain backwards compat with OCI8 1.4 */
24722484
connection->passwd_changed = 1;
24732485
return 0;
24742486
}
@@ -2503,12 +2515,13 @@ void php_oci_client_get_version(char **version TSRMLS_DC)
25032515
*/
25042516
int php_oci_server_get_version(php_oci_connection *connection, char **version TSRMLS_DC)
25052517
{
2518+
sword errstatus;
25062519
char version_buff[256];
25072520

2508-
PHP_OCI_CALL_RETURN(connection->errcode, OCIServerVersion, (connection->svc, connection->err, (text *)version_buff, sizeof(version_buff), OCI_HTYPE_SVCCTX));
2521+
PHP_OCI_CALL_RETURN(errstatus, OCIServerVersion, (connection->svc, connection->err, (text *)version_buff, sizeof(version_buff), OCI_HTYPE_SVCCTX));
25092522

2510-
if (connection->errcode != OCI_SUCCESS) {
2511-
connection->errcode = php_oci_error(connection->err, connection->errcode TSRMLS_CC);
2523+
if (errstatus != OCI_SUCCESS) {
2524+
connection->errcode = php_oci_error(connection->err, errstatus TSRMLS_CC);
25122525
PHP_OCI_HANDLE_ERROR(connection, connection->errcode);
25132526
return 1;
25142527
}
@@ -2806,6 +2819,7 @@ static php_oci_spool *php_oci_create_spool(char *username, int username_len, cha
28062819
zend_bool iserror = 0;
28072820
ub4 poolmode = OCI_DEFAULT; /* Mode to be passed to OCISessionPoolCreate */
28082821
OCIAuthInfo *spoolAuth = NULL;
2822+
sword errstatus;
28092823

28102824
/* Allocate sessionpool out of persistent memory */
28112825
session_pool = (php_oci_spool *) calloc(1, sizeof(php_oci_spool));
@@ -2830,10 +2844,10 @@ static php_oci_spool *php_oci_create_spool(char *username, int username_len, cha
28302844
}
28312845

28322846
/* Allocate the pool handle */
2833-
PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (session_pool->env, (dvoid **) &session_pool->poolh, OCI_HTYPE_SPOOL, (size_t) 0, (dvoid **) 0));
2847+
PHP_OCI_CALL_RETURN(errstatus, OCIHandleAlloc, (session_pool->env, (dvoid **) &session_pool->poolh, OCI_HTYPE_SPOOL, (size_t) 0, (dvoid **) 0));
28342848

2835-
if (OCI_G(errcode) != OCI_SUCCESS) {
2836-
php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
2849+
if (errstatus != OCI_SUCCESS) {
2850+
OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC);
28372851
iserror = 1;
28382852
goto exit_create_spool;
28392853
}
@@ -2842,10 +2856,10 @@ static php_oci_spool *php_oci_create_spool(char *username, int username_len, cha
28422856
* generic bug which can free up the OCI_G(err) variable before destroying connections. We
28432857
* cannot use this for other roundtrip calls as there is no way the user can access this error
28442858
*/
2845-
PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, ((dvoid *) session_pool->env, (dvoid **)&(session_pool->err), (ub4) OCI_HTYPE_ERROR,(size_t) 0, (dvoid **) 0));
2859+
PHP_OCI_CALL_RETURN(errstatus, OCIHandleAlloc, ((dvoid *) session_pool->env, (dvoid **)&(session_pool->err), (ub4) OCI_HTYPE_ERROR,(size_t) 0, (dvoid **) 0));
28462860

2847-
if (OCI_G(errcode) != OCI_SUCCESS) {
2848-
php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
2861+
if (errstatus != OCI_SUCCESS) {
2862+
OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC);
28492863
iserror = 1;
28502864
goto exit_create_spool;
28512865
}
@@ -2859,42 +2873,42 @@ static php_oci_spool *php_oci_create_spool(char *username, int username_len, cha
28592873

28602874
#if ((OCI_MAJOR_VERSION > 11) || ((OCI_MAJOR_VERSION == 11) && (OCI_MINOR_VERSION >= 2)))
28612875
/* {{{ Allocate auth handle for session pool */
2862-
PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIHandleAlloc, (session_pool->env, (dvoid **)&(spoolAuth), OCI_HTYPE_AUTHINFO, 0, NULL));
2876+
PHP_OCI_CALL_RETURN(errstatus, OCIHandleAlloc, (session_pool->env, (dvoid **)&(spoolAuth), OCI_HTYPE_AUTHINFO, 0, NULL));
28632877

2864-
if (OCI_G(errcode) != OCI_SUCCESS) {
2865-
php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
2878+
if (errstatus != OCI_SUCCESS) {
2879+
OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC);
28662880
iserror = 1;
28672881
goto exit_create_spool;
28682882
}
28692883
/* }}} */
28702884

28712885
/* {{{ Set the edition attribute on the auth handle */
28722886
if (OCI_G(edition)) {
2873-
PHP_OCI_CALL_RETURN(OCI_G(errcode),OCIAttrSet, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO, (dvoid *) OCI_G(edition), (ub4)(strlen(OCI_G(edition))), (ub4)OCI_ATTR_EDITION, OCI_G(err)));
2887+
PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO, (dvoid *) OCI_G(edition), (ub4)(strlen(OCI_G(edition))), (ub4)OCI_ATTR_EDITION, OCI_G(err)));
28742888

2875-
if (OCI_G(errcode) != OCI_SUCCESS) {
2876-
php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
2889+
if (errstatus != OCI_SUCCESS) {
2890+
OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC);
28772891
iserror = 1;
28782892
goto exit_create_spool;
28792893
}
28802894
}
28812895
/* }}} */
28822896

28832897
/* {{{ Set the driver name attribute on the auth handle */
2884-
PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrSet, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO, (dvoid *) PHP_OCI8_DRIVER_NAME, (ub4) sizeof(PHP_OCI8_DRIVER_NAME)-1, (ub4) OCI_ATTR_DRIVER_NAME, OCI_G(err)));
2898+
PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO, (dvoid *) PHP_OCI8_DRIVER_NAME, (ub4) sizeof(PHP_OCI8_DRIVER_NAME)-1, (ub4) OCI_ATTR_DRIVER_NAME, OCI_G(err)));
28852899

2886-
if (OCI_G(errcode) != OCI_SUCCESS) {
2887-
php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
2900+
if (errstatus != OCI_SUCCESS) {
2901+
OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC);
28882902
iserror = 1;
28892903
goto exit_create_spool;
28902904
}
28912905
/* }}} */
28922906

28932907
/* {{{ Set the auth handle on the session pool */
2894-
PHP_OCI_CALL_RETURN(OCI_G(errcode),OCIAttrSet, ((dvoid *) (session_pool->poolh),(ub4) OCI_HTYPE_SPOOL, (dvoid *) spoolAuth, (ub4)0, (ub4)OCI_ATTR_SPOOL_AUTH, OCI_G(err)));
2908+
PHP_OCI_CALL_RETURN(errstatus, OCIAttrSet, ((dvoid *) (session_pool->poolh),(ub4) OCI_HTYPE_SPOOL, (dvoid *) spoolAuth, (ub4)0, (ub4)OCI_ATTR_SPOOL_AUTH, OCI_G(err)));
28952909

2896-
if (OCI_G(errcode) != OCI_SUCCESS) {
2897-
php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
2910+
if (errstatus != OCI_SUCCESS) {
2911+
OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC);
28982912
iserror = 1;
28992913
goto exit_create_spool;
29002914
}
@@ -2904,10 +2918,10 @@ static php_oci_spool *php_oci_create_spool(char *username, int username_len, cha
29042918
/* Create the homogeneous session pool - We have different session pools for every different
29052919
* username, password, charset and dbname.
29062920
*/
2907-
PHP_OCI_CALL_RETURN(OCI_G(errcode), OCISessionPoolCreate,(session_pool->env, OCI_G(err), session_pool->poolh, (OraText **)&session_pool->poolname, &session_pool->poolname_len, (OraText *)dbname, (ub4)dbname_len, 0, UB4MAXVAL, 1,(OraText *)username, (ub4)username_len, (OraText *)password,(ub4)password_len, poolmode));
2921+
PHP_OCI_CALL_RETURN(errstatus, OCISessionPoolCreate,(session_pool->env, OCI_G(err), session_pool->poolh, (OraText **)&session_pool->poolname, &session_pool->poolname_len, (OraText *)dbname, (ub4)dbname_len, 0, UB4MAXVAL, 1,(OraText *)username, (ub4)username_len, (OraText *)password,(ub4)password_len, poolmode));
29082922

2909-
if (OCI_G(errcode) != OCI_SUCCESS) {
2910-
php_oci_error(OCI_G(err), OCI_G(errcode) TSRMLS_CC);
2923+
if (errstatus != OCI_SUCCESS) {
2924+
OCI_G(errcode) = php_oci_error(OCI_G(err), errstatus TSRMLS_CC);
29112925
iserror = 1;
29122926
}
29132927

@@ -3477,11 +3491,11 @@ static sword php_oci_ping_init(php_oci_connection *connection, OCIError *errh TS
34773491
*
34783492
* DTrace output for connections that may have become invalid and marked for reopening
34793493
*/
3480-
void php_oci_dtrace_check_connection(php_oci_connection *connection, sword errcode, ub4 serverStatus)
3494+
void php_oci_dtrace_check_connection(php_oci_connection *connection, sb4 errcode, ub4 serverStatus)
34813495
{
34823496
#ifdef HAVE_OCI8_DTRACE
34833497
if (DTRACE_OCI8_CHECK_CONNECTION_ENABLED()) {
3484-
DTRACE_OCI8_CHECK_CONNECTION(connection, connection && connection->is_open ? 1 : 0, (int)errcode, (unsigned long)serverStatus);
3498+
DTRACE_OCI8_CHECK_CONNECTION(connection, connection && connection->is_open ? 1 : 0, (long)errcode, (unsigned long)serverStatus);
34853499
}
34863500
#endif /* HAVE_OCI8_DTRACE */
34873501
}

0 commit comments

Comments
 (0)