diff --git a/doc/src/conf.py b/doc/src/conf.py index ae1a8cde..604afdda 100755 --- a/doc/src/conf.py +++ b/doc/src/conf.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- #------------------------------------------------------------------------------ -# Copyright (c) 2016, 2019 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved. # This program is free software: you can modify it and/or redistribute it # under the terms of: # @@ -18,12 +18,12 @@ # the suffix used for all source files source_suffix = '.rst' -# the name of the master document +# the name of the main document master_doc = 'index' # general information about the project project = 'ODPI-C' -copyright = '2016, 2019, Oracle and/or its affiliates. All rights reserved.' +copyright = '2016, 2020, Oracle and/or its affiliates. All rights reserved.' author = 'Oracle' # the version info for the project, acts as replacement for |version| and @@ -33,7 +33,7 @@ version = '4.0' # the full version, including alpha/beta/rc tags -release = '4.0.1' +release = '4.0.2' # the theme to use for HTML pages html_theme = 'oracle' diff --git a/doc/src/index.rst b/doc/src/index.rst index 8e12a614..3b179cf9 100644 --- a/doc/src/index.rst +++ b/doc/src/index.rst @@ -1,4 +1,4 @@ -.. ODPI-C documentation master file. +.. ODPI-C documentation main file. Welcome to ODPI-C's |release| documentation! ============================================ diff --git a/doc/src/installation.rst b/doc/src/installation.rst index 0c9eae9c..d1f825b7 100644 --- a/doc/src/installation.rst +++ b/doc/src/installation.rst @@ -185,8 +185,10 @@ To run ODPI-C applications with Oracle Instant Client zip files: ``sqlnet.ora`` or ``oraaccess.xml``, put the files in an accessible directory. Then set the member :member:`dpiContextCreateParams.oracleClientConfigDir` when calling - :func:`dpiContext_createWithParams()`, or set the environment variable - ``TNS_ADMIN`` to that directory name. + :func:`dpiContext_createWithParams()`. + + Alternatively, set the environment variable ``TNS_ADMIN`` to that directory + name. Alternatively, create a ``network/admin`` subdirectory of Instant Client, if it does not exist. For example:: @@ -248,8 +250,10 @@ To run ODPI-C applications with Oracle Instant Client RPMs: ``sqlnet.ora`` or ``oraaccess.xml``, put the files in an accessible directory. Then set the member :member:`dpiContextCreateParams.oracleClientConfigDir` when calling - :func:`dpiContext_createWithParams()`, or set the environment variable - ``TNS_ADMIN`` to that directory name. + :func:`dpiContext_createWithParams()`. + + Alternatively, set the environment variable ``TNS_ADMIN`` to that directory + name. Alternatively, create a ``network/admin`` subdirectory of Instant Client, if it does not exist. For example:: @@ -348,42 +352,46 @@ To run ODPI-C applications with Oracle Instant Client zip files: ``instantclient-basic-windows.x64-19.6.0.0.0dbru.zip`` to ``C:\oracle\instantclient_19_6``. -3. Either set this directory in the member - :member:`dpiContextCreateParams.oracleClientLibDir` when calling - :func:`dpiContext_createWithParams()`, or do the following. +3. There are several alternative ways to tell your application where your Oracle + Instant Client libraries are. - Add this directory to the ``PATH`` environment variable. For example, on - Windows 7, update ``PATH`` in Control Panel -> System -> Advanced System - Settings -> Advanced -> Environment Variables -> System Variables -> PATH. - The Instant Client directory must occur in ``PATH`` before any other Oracle - directories. + * Set this directory in the member + :member:`dpiContextCreateParams.oracleClientLibDir` when calling + :func:`dpiContext_createWithParams()`. - Restart any open command prompt windows. + * Alternatively, move the unzipped Instant Client files to the same + directory as the ODPIC.DLL (or into the directory of the application's + binary, if ODPI-C is compiled into the application). + + * Alternatively, add the Instant Client directory to the ``PATH`` + environment variable. For example, on Windows 7, update ``PATH`` in + Control Panel -> System -> Advanced System Settings -> Advanced -> + Environment Variables -> System Variables -> PATH. The Instant Client + directory must occur in ``PATH`` before any other Oracle directories. - To avoid interfering with existing tools that require other Oracle - Client versions, instead of updating the system-wide ``PATH`` variable, you - may prefer to write a batch file that sets ``PATH``, for example:: + Restart any open command prompt windows. - REM mywrapper.bat - SET PATH=C:\oracle\instantclient_19_6;%PATH% - myapp %* + To avoid interfering with existing tools that require other Oracle Client + versions, instead of updating the system-wide ``PATH`` variable, you may + prefer to write a batch file that sets ``PATH``, for example:: - Invoke this batch file everytime you want to run your application. + REM mywrapper.bat + SET PATH=C:\oracle\instantclient_19_6;%PATH% + myapp %* - Alternatively use ``SET`` to change your ``PATH`` in each command - prompt window before you run python. + Invoke this batch file every time you want to run your application. - Another option is to move the unzipped Instant Client files to the - same directory as the ODPIC.DLL (or into the directory of the - application's binary, if ODPI-C is compiled into application). If - you do this, then ``PATH`` does not need to be set. + Or simply use ``SET`` to change your ``PATH`` in each command prompt window + before you run your application. 4. If you use optional Oracle configuration files such as ``tnsnames.ora``, ``sqlnet.ora`` or ``oraaccess.xml``, put the files in an accessible directory. Then set the member :member:`dpiContextCreateParams.oracleClientConfigDir` when calling - :func:`dpiContext_createWithParams()`, or set the environment variable - ``TNS_ADMIN`` to that directory name. + :func:`dpiContext_createWithParams()`. + + Alternatively, set the environment variable ``TNS_ADMIN`` to that directory + name. Alternatively, create a ``network\admin`` subdirectory of Instant Client, if it does not exist. For example ``C:\oracle\instantclient_19_6\network\admin``. @@ -445,42 +453,72 @@ To run ODPI-C applications with Oracle Instant Client zip files: application architecture. Most applications use 64-bit. 2. Unzip the package into a single directory that is accessible to your - application. For example, in Terminal you could unzip in your home directory:: + application. For example, in Terminal you could unzip: + + .. code-block:: shell - cd ~ - unzip instantclient-basic-macos.x64-19.3.0.0.0dbru.zip + mkdir /opt/oracle + cd /opt/oracle + unzip /your/path/to/instantclient-basic-macos.x64-19.3.0.0.0dbru.zip + +3. There are several alternative ways to tell your application where your Oracle + Instant Client libraries are. + + * Use the extracted directory for the member + :member:`dpiContextCreateParams.oracleClientLibDir` in a call to + :func:`dpiContext_createWithParams()` + + * Alternatively, copy Oracle Instant Client to the directory containing the + ODPI-C module binary. For example, if ``libodpic.dylib`` (or your binary + containing the ODPI-C code) is in ``~/myprograms`` you can then run ``ln -s + ~/instantclient_19_3/libclntsh.dylib ~/myprograms``. You can also copy the + Instant Client libraries to that directory. + + * Alternatively, set ``DYLD_LIBRARY_PATH`` to the Instant Client directory. Note this + variable does not propagate to sub-shells. + + * Alternatively, you might decide to compile the ODPI-C library with an RPATH + option like ``-Wl,-rpath,/usr/local/lib``. Then you can link Oracle + Instant Client to this directory, for example:: -3. Either use this directory as the member - :member:`dpiContextCreateParams.oracleClientLibDir` is specified when calling - :func:`dpiContext_createWithParams()`, or do the following. + ln -s /opt/oracle/instantclient_19_3/libclntsh.dylib /usr/local/lib/ - Add a link to ``$HOME/lib`` or ``/usr/local/lib`` to enable applications to - find Instant Client. If the ``lib`` sub-directory does not exist, you can - create it. For example:: + Or, instead of a link you can copy the required OCI libraries. For example:: - mkdir ~/lib - ln -s ~/instantclient_19_3/libclntsh.dylib ~/lib/ + cp /opt/oracle/instantclient_19_3/{libclntsh.dylib.19.1,libclntshcore.dylib.19.1,libons.dylib,libnnz12.dylib,libociei.dylib} /usr/local/lib/ - If you now run ``ls -l ~/lib/libclntsh.dylib`` you will see something like:: + * Alternatively, on older versions of macOS, you could add a link to + ``$HOME/lib`` or ``/usr/local/lib`` to enable applications to find Instant + Client. If the ``lib`` sub-directory does not exist, you can create + it. For example: - lrwxr-xr-x 1 yourname staff 48 12 Nov 15:04 /Users/yourname/lib/libclntsh.dylib -> /Users/yourname/instantclient_19_3/libclntsh.dylib + .. code-block:: shell - Alternatively, copy the required OCI libraries. For example:: + mkdir ~/lib + ln -s ~/instantclient_19_3/libclntsh.dylib ~/lib/ - mkdir ~/lib - cp ~/instantclient_19_3/{libclntsh.dylib.19.1,libclntshcore.dylib.19.1,libons.dylib,libnnz12.dylib,libociei.dylib} ~/lib/ + Instead of linking, you can copy the required OCI libraries. For example: - For Instant Client 11.2, the OCI libraries must be copied. For example:: + .. code-block:: shell - mkdir ~/lib - cp ~/instantclient_11_2/{libclntsh.dylib.11.1,libnnz11.dylib,libociei.dylib} ~/lib/ + mkdir ~/lib + cp ~/instantclient_19_3/{libclntsh.dylib.19.1,libclntshcore.dylib.19.1,libnnz19.dylib,libociei.dylib} ~/lib/ + + For Instant Client 11.2, the OCI libraries must be copied. For example: + + .. code-block:: shell + + mkdir ~/lib + cp ~/instantclient_11_2/{libclntsh.dylib.11.1,libnnz11.dylib,libociei.dylib} ~/lib/ 4. If you use optional Oracle configuration files such as ``tnsnames.ora``, ``sqlnet.ora`` or ``oraaccess.xml``, put the files in an accessible directory. Then set the member :member:`dpiContextCreateParams.oracleClientConfigDir` when calling - :func:`dpiContext_createWithParams()`, or set the environment variable - ``TNS_ADMIN`` to that directory name. + :func:`dpiContext_createWithParams()`. + + Alternatively, set the environment variable ``TNS_ADMIN`` to that directory + name. Alternatively, create a ``network/admin`` subdirectory of Instant Client, if it does not exist. For example:: diff --git a/doc/src/releasenotes.rst b/doc/src/releasenotes.rst index 9b5a551e..b11bc79a 100644 --- a/doc/src/releasenotes.rst +++ b/doc/src/releasenotes.rst @@ -1,6 +1,19 @@ ODPI-C Release notes ==================== +Version 4.0.2 (August 31, 2020) +------------------------------- + +#) Adjusted check for GNU version of strerror_r() on Cygwin as suggested + (`issue 138 <https://github.com/oracle/odpi/issues/138>`__). +#) Up to 40 digits can be represented in an unconstrained Oracle number so + allow for that possibility (`cx_Oracle issue 459 + <https://github.com/oracle/python-cx_Oracle/issues/459>`__). +#) Correct double free error + (`issue 141 <https://github.com/oracle/odpi/issues/141>`__). +#) Improved documentation and adjusted test suite. + + Version 4.0.1 (June 26, 2020) ----------------------------- diff --git a/include/dpi.h b/include/dpi.h index f8d56051..b4130a4f 100644 --- a/include/dpi.h +++ b/include/dpi.h @@ -11,7 +11,7 @@ //----------------------------------------------------------------------------- // dpi.h -// Master include file for ODPI-C library. +// Include file for users of the ODPI-C library. //----------------------------------------------------------------------------- #ifndef DPI_PUBLIC @@ -57,7 +57,7 @@ extern "C" { // define ODPI-C version information #define DPI_MAJOR_VERSION 4 #define DPI_MINOR_VERSION 0 -#define DPI_PATCH_LEVEL 1 +#define DPI_PATCH_LEVEL 2 #define DPI_VERSION_SUFFIX #define DPI_STR_HELPER(x) #x diff --git a/src/dpiError.c b/src/dpiError.c index 59715ed5..f954afa3 100644 --- a/src/dpiError.c +++ b/src/dpiError.c @@ -256,7 +256,7 @@ int dpiError__setFromOS(dpiError *error, const char *action) char buffer[512]; int err = errno; -#if defined(__GLIBC__) +#if defined(__GLIBC__) || defined(__CYGWIN__) message = strerror_r(err, buffer, sizeof(buffer)); #else message = (strerror_r(err, buffer, sizeof(buffer)) == 0) ? buffer : NULL; diff --git a/src/dpiImpl.h b/src/dpiImpl.h index 44f01e4d..a62e8a9c 100644 --- a/src/dpiImpl.h +++ b/src/dpiImpl.h @@ -11,9 +11,9 @@ //----------------------------------------------------------------------------- // dpiImpl.h -// Master include file for implementation of ODPI-C library. The definitions -// in this file are subject to change without warning. Only the definitions in -// the file dpi.h are intended to be used publicly. +// Include file for implementation of ODPI-C library. The definitions in this +// file are subject to change without warning. Only the definitions in the file +// dpi.h are intended to be used publicly. //----------------------------------------------------------------------------- #ifndef DPI_IMPL @@ -88,7 +88,7 @@ extern unsigned long dpiDebugLevel; #define DPI_NUMBER_AS_TEXT_CHARS 172 // define maximum number of digits possible in an Oracle number -#define DPI_NUMBER_MAX_DIGITS 38 +#define DPI_NUMBER_MAX_DIGITS 40 // define maximum size in bytes supported by basic string handling #define DPI_MAX_BASIC_BUFFER_SIZE 32767 diff --git a/src/dpiSodaDb.c b/src/dpiSodaDb.c index 0e1605a3..86f97678 100644 --- a/src/dpiSodaDb.c +++ b/src/dpiSodaDb.c @@ -197,7 +197,7 @@ int dpiSodaDb_createCollection(dpiSodaDb *db, const char *name, //----------------------------------------------------------------------------- // dpiSodaDb_createDocument() [PUBLIC] // Create a SODA document that can be inserted in the collection or can be -// used to replace and existing document in the collection. +// used to replace an existing document in the collection. //----------------------------------------------------------------------------- int dpiSodaDb_createDocument(dpiSodaDb *db, const char *key, uint32_t keyLength, const char *content, uint32_t contentLength, diff --git a/src/dpiStmt.c b/src/dpiStmt.c index 7ec2d261..c88bb2ca 100644 --- a/src/dpiStmt.c +++ b/src/dpiStmt.c @@ -56,8 +56,8 @@ int dpiStmt__allocate(dpiConn *conn, int scrollable, dpiStmt **stmt, // Bind the variable to the statement using either a position or a name. A // reference to the variable will be retained. //----------------------------------------------------------------------------- -static int dpiStmt__bind(dpiStmt *stmt, dpiVar *var, int addReference, - uint32_t pos, const char *name, uint32_t nameLength, dpiError *error) +static int dpiStmt__bind(dpiStmt *stmt, dpiVar *var, uint32_t pos, + const char *name, uint32_t nameLength, dpiError *error) { dpiBindVar *bindVars, *entry = NULL; int found, dynamicBind, status; @@ -148,8 +148,7 @@ static int dpiStmt__bind(dpiStmt *stmt, dpiVar *var, int addReference, } // perform actual bind - if (addReference) - dpiGen__setRefCount(var, error, 1); + dpiGen__setRefCount(var, error, 1); entry->var = var; dynamicBind = stmt->isReturning || var->isDynamic; if (pos > 0) { @@ -368,6 +367,7 @@ static int dpiStmt__createBindVar(dpiStmt *stmt, dpiData *varData; dpiVar *tempVar; uint32_t size; + int status; // determine the type (and size) of bind variable to create size = 0; @@ -418,13 +418,11 @@ static int dpiStmt__createBindVar(dpiStmt *stmt, return DPI_FAILURE; // bind variable to statement - if (dpiStmt__bind(stmt, tempVar, 0, pos, name, nameLength, error) < 0) { - dpiVar__free(tempVar, error); - return DPI_FAILURE; - } - - *var = tempVar; - return DPI_SUCCESS; + status = dpiStmt__bind(stmt, tempVar, pos, name, nameLength, error); + dpiGen__setRefCount(tempVar, error, -1); + if (status == DPI_SUCCESS) + *var = tempVar; + return status; } @@ -1057,7 +1055,7 @@ static int dpiStmt__reExecute(dpiStmt *stmt, uint32_t numIters, continue; var = bindVar->var; bindVar->var = NULL; - if (dpiStmt__bind(stmt, var, 0, bindVar->pos, bindVar->name, + if (dpiStmt__bind(stmt, var, bindVar->pos, bindVar->name, bindVar->nameLength, error) < 0) { dpiGen__setRefCount(var, error, -1); return DPI_FAILURE; @@ -1094,7 +1092,7 @@ int dpiStmt_bindByName(dpiStmt *stmt, const char *name, uint32_t nameLength, DPI_CHECK_PTR_NOT_NULL(stmt, name) if (dpiGen__checkHandle(var, DPI_HTYPE_VAR, "bind by name", &error) < 0) return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); - status = dpiStmt__bind(stmt, var, 1, 0, name, nameLength, &error); + status = dpiStmt__bind(stmt, var, 0, name, nameLength, &error); return dpiGen__endPublicFn(stmt, status, &error); } @@ -1112,7 +1110,7 @@ int dpiStmt_bindByPos(dpiStmt *stmt, uint32_t pos, dpiVar *var) return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); if (dpiGen__checkHandle(var, DPI_HTYPE_VAR, "bind by pos", &error) < 0) return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); - status = dpiStmt__bind(stmt, var, 1, pos, NULL, 0, &error); + status = dpiStmt__bind(stmt, var, pos, NULL, 0, &error); return dpiGen__endPublicFn(stmt, status, &error); } @@ -1132,10 +1130,8 @@ int dpiStmt_bindValueByName(dpiStmt *stmt, const char *name, return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(stmt, name) DPI_CHECK_PTR_NOT_NULL(stmt, data) - if (dpiStmt__createBindVar(stmt, nativeTypeNum, data, &var, 0, name, - nameLength, &error) < 0) - return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); - status = dpiStmt__bind(stmt, var, 1, 0, name, nameLength, &error); + status = dpiStmt__createBindVar(stmt, nativeTypeNum, data, &var, 0, name, + nameLength, &error); return dpiGen__endPublicFn(stmt, status, &error); } @@ -1154,10 +1150,8 @@ int dpiStmt_bindValueByPos(dpiStmt *stmt, uint32_t pos, if (dpiStmt__check(stmt, __func__, &error) < 0) return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); DPI_CHECK_PTR_NOT_NULL(stmt, data) - if (dpiStmt__createBindVar(stmt, nativeTypeNum, data, &var, pos, NULL, 0, - &error) < 0) - return dpiGen__endPublicFn(stmt, DPI_FAILURE, &error); - status = dpiStmt__bind(stmt, var, 1, pos, NULL, 0, &error); + status = dpiStmt__createBindVar(stmt, nativeTypeNum, data, &var, pos, NULL, + 0, &error); return dpiGen__endPublicFn(stmt, status, &error); } diff --git a/test/TestConnProperties.c b/test/TestConnProperties.c index 1eec4076..4dee02b5 100644 --- a/test/TestConnProperties.c +++ b/test/TestConnProperties.c @@ -270,8 +270,9 @@ int dpiTest_407_withValidEncoding(dpiTestCase *testCase, dpiTestParams *params) return dpiTestCase_setFailedFromError(testCase); // get connection with just the encoding specified + if (dpiContext_initCommonCreateParams(context, &commonParams) < 0) + return dpiTestCase_setFailedFromError(testCase); commonParams.encoding = charSet; - commonParams.nencoding = NULL; if (dpiConn_create(context, params->mainUserName, params->mainUserNameLength, params->mainPassword, params->mainPasswordLength, params->connectString, @@ -290,7 +291,8 @@ int dpiTest_407_withValidEncoding(dpiTestCase *testCase, dpiTestParams *params) return dpiTestCase_setFailedFromError(testCase); // get connection with just the nencoding specified - commonParams.encoding = NULL; + if (dpiContext_initCommonCreateParams(context, &commonParams) < 0) + return dpiTestCase_setFailedFromError(testCase); commonParams.nencoding = charSet; if (dpiConn_create(context, params->mainUserName, params->mainUserNameLength, params->mainPassword, diff --git a/test/TestDataTypes.c b/test/TestDataTypes.c index ad04cf60..506fa6dd 100644 --- a/test/TestDataTypes.c +++ b/test/TestDataTypes.c @@ -1350,6 +1350,10 @@ int dpiTest_1206_verifyNumDataTypeWithDiffValues(dpiTestCase *testCase, "0", "92999999999999999999999999999999999999", "-92999999999999999999999999999999999999", + "999999999999999999999999999999999999999", + "-999999999999999999999999999999999999999", + "9999999999999999999999999999999999999999", + "-9999999999999999999999999999999999999999", "900000000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000", "-90000000000000000000000000000000000000000000000000000000000000000000" @@ -1367,6 +1371,10 @@ int dpiTest_1206_verifyNumDataTypeWithDiffValues(dpiTestCase *testCase, "0", "92999999999999999999999999999999999999", "-92999999999999999999999999999999999999", + "999999999999999999999999999999999999999", + "-999999999999999999999999999999999999999", + "9999999999999999999999999999999999999999", + "-9999999999999999999999999999999999999999", "9E+125", "-9E+125", "3.0123456789012345678901234567890123456", @@ -1453,8 +1461,8 @@ int dpiTest_1207_verifyInvalidValues(dpiTestCase *testCase, "-1E+126", "1E-131", "-1E-131", - "999999999999999999999999999999999999999", - "-999999999999999999999999999999999999999", + "99999999999999999999999999999999999999999", + "-99999999999999999999999999999999999999999", "www.json.org", "1.2.3", "a", diff --git a/test/TestPoolProperties.c b/test/TestPoolProperties.c index 2412cf80..44e7f476 100644 --- a/test/TestPoolProperties.c +++ b/test/TestPoolProperties.c @@ -280,8 +280,9 @@ int dpiTest_606_encodingInfo(dpiTestCase *testCase, dpiTestParams *params) return dpiTestCase_setFailedFromError(testCase); // create pool with just the encoding specified + if (dpiContext_initCommonCreateParams(context, &commonParams) < 0) + return dpiTestCase_setFailedFromError(testCase); commonParams.encoding = charSet; - commonParams.nencoding = NULL; if (dpiPool_create(context, params->mainUserName, params->mainUserNameLength, params->mainPassword, params->mainPasswordLength, params->connectString, @@ -300,7 +301,8 @@ int dpiTest_606_encodingInfo(dpiTestCase *testCase, dpiTestParams *params) return dpiTestCase_setFailedFromError(testCase); // create pool with just the nencoding specified - commonParams.encoding = NULL; + if (dpiContext_initCommonCreateParams(context, &commonParams) < 0) + return dpiTestCase_setFailedFromError(testCase); commonParams.nencoding = charSet; if (dpiPool_create(context, params->mainUserName, params->mainUserNameLength, params->mainPassword, diff --git a/test/TestSodaColl.c b/test/TestSodaColl.c index 2b7f3596..059af163 100644 --- a/test/TestSodaColl.c +++ b/test/TestSodaColl.c @@ -768,7 +768,8 @@ int dpiTest_2609_verifyFind(dpiTestCase *testCase, dpiTestParams *params) //----------------------------------------------------------------------------- int dpiTest_2610_testInvalidJson(dpiTestCase *testCase, dpiTestParams *params) { - const char *expectedErrors[] = { "ORA-02290:", "ORA-40479:", NULL }; + const char *expectedErrors[] = { "ORA-02290:", "ORA-40479:", "ORA-40780:", + NULL }; const char *content = "{\"test : 2610 content\"}"; const char *collName = "ODPIC_COLL_2610"; dpiSodaColl *coll; @@ -1153,7 +1154,8 @@ int dpiTest_2614_verifyInsertManyWorksAsExpected(dpiTestCase *testCase, int dpiTest_2615_testInsertManyWithInvalidJson(dpiTestCase *testCase, dpiTestParams *params) { - const char *expectedErrors[] = { "ORA-02290:", "ORA-40479:", NULL }; + const char *expectedErrors[] = { "ORA-02290:", "ORA-40479:", "ORA-40780:", + NULL }; const char *contents[5] = { "{\"test1\" : \"2615 content1\"}", "{\"test2\" : \"2615 content2\"}",