Coder Social home page Coder Social logo

vrogier / ocilib Goto Github PK

View Code? Open in Web Editor NEW
314.0 41.0 116.0 17.38 MB

OCILIB (C and C++ Drivers for Oracle) - Open source C and C++ library for accessing Oracle databases

Home Page: http://www.ocilib.net

License: Apache License 2.0

Shell 11.30% C 61.37% C++ 21.54% Makefile 4.47% M4 0.30% Batchfile 0.01% CSS 0.93% HTML 0.08%
ocilib oracle-database oci sql driver api oracle

ocilib's Introduction

OCILIB - C and C++ Drivers for Oracle

Build Status Code Analysis

1. About

OCILIB is an open source and cross platform Oracle Driver that delivers efficient access to Oracle databases.

The OCILIB library :

  • offers a rich, full featured and easy to use API
  • runs on all Oracle platforms
  • is written in pure ISO C99 code with native ISO C Unicode support
  • provides also a C++ API written in standard C++03 with support for some C++11 features
  • Enables high productivity
  • encapsulates OCI (Oracle Call Interface)
  • is the most complete available OCI wrapper

OCILIB is developed by Vincent Rogier. Get the latest package, install and enjoy it!

2. License

The source code is free source code licensed under Apache License, Version 2.0 - see LICENSE file

3. Features

  • ISO C API
  • ISO C ++ API
  • Full ANSI and Unicode support on all platforms (ISO C wide strings or UTF8 strings)
  • Full 32/64 bits compatibility
  • Compatible with all Oracle version >= 8.0
  • Automatic adaptation to the runtime Oracle client version
  • Runtime loading of Oracle libraries
  • Built-in error handling (global and thread context)
  • Full support for SQL API and Object API
  • Full support for ALL Oracle SQL and PL/SQL datatypes (scalars, objects, refs, collections, ..)
  • Full support for PL/SQL (blocks, cursors, Index by Tables and Nested tables)
  • Support for non scalar datatype with trough library objects
  • Oracle Pooling (connections and sessions pools)
  • Oracle XA connectivity (X/Open Distributed Transaction Processing XA interface)
  • Oracle AQ (Advanced Queues)
  • Oracle TAF (Transparent Application Failover) and HA (High availability) support
  • Binding array Interface
  • Returning DML feature
  • Scrollable statements
  • Statement cache
  • Direct Path loading
  • Remote Instances Startup/Shutdown
  • Oracle Database Change notification / Continuous Query Notification
  • Oracle warnings support
  • Global and local transactions
  • Describe database schema objects
  • Hash tables API
  • Portable Threads and mutexes API

5. Installation

Windows platforms

  • unzip the archive
  • copy ocilib\include\ocilib.h to any place located in your include’s path
  • copy ocilib\lib32|64\ocilib[x].lib to any place located in your libraries path
  • copy ocilib\lib32|64\ocilib[x].dll to any place located in your windows path

GNU (Unix / Linux) platforms

  • untar the archive
  • $ cd ocilib-x.y.z
  • $ ./configure
  • $ make
  • $ make install (you might need to su to make install)

Make sure Oracle and OCILIB libraries paths are defined in your shared library environment variable You need to provide extra configure parameters when using Instant Clients – see Installation section)

6. Examples

Example of a minimal OCILIB C application

#include "ocilib.h"
 
int main(int argc, char *argv[])
{
    OCI_Connection* cn;
    OCI_Statement* st;
    OCI_Resultset* rs;
 
    OCI_Initialize(NULL, NULL, OCI_ENV_DEFAULT);
 
    cn = OCI_ConnectionCreate("db", "usr", "pwd", OCI_SESSION_DEFAULT);
    st = OCI_StatementCreate(cn);
 
    OCI_ExecuteStmt(st, "select intcol, strcol from table");
 
    rs = OCI_GetResultset(st);
 
    while (OCI_FetchNext(rs))
    {
        printf("%i - %s\n", OCI_GetInt(rs, 1), OCI_GetString(rs,2));
    }
 
    OCI_Cleanup();
 
    return EXIT_SUCCESS;
}

Example of a minimal OCILIB C++ application

#include "ocilib.hpp"
 
using namespace ocilib;
 
int main(void)
{
    try
    {
        Environment::Initialize();
 
        Connection con("db", "usr", "pwd");
 
        Statement st(con);
        st.Execute("select intcol, strcol from table");
 
        Resultset rs = st.GetResultset();
        while (rs.Next())
        {
            std::cout << rs.Get<int>(1) << " - " <<  rs.Get<ostring>(2) << std::endl;
        }
    }
    catch(std::exception &ex)
    {
         std::cout << ex.what() << std::endl;
    }
 
    Environment::Cleanup();
 
    return EXIT_SUCCESS;
}

ocilib's People

Contributors

meastp avatar vrogier avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ocilib's Issues

How use External Credentials with OCI_POOL_SESSION?

Hi Vicent,

When I use the external credentials (Oracle Wallet) with OCI_POOL_CONNECTION my code run OK,

OCI_Initialize(NULL, NULL, OCI_ENV_DEFAULT | OCI_ENV_CONTEXT | OCI_ENV_THREADED )
OCI_PoolCreate(g_config.tns,
NULL,
NULL,
OCI_POOL_CONNECTION,
OCI_SESSION_DEFAULT,
g_config.min_conn,
g_config.max_conn,
g_config.inc_conn);

**in this case, I can only see level TCP / IP, an open socket **

...
But I use with OCI_POOL_SESSION my code not running.

Note:
** when I use OCI POOL SESSION with User/Password explicit running OK,
and in this case, I can see the level of TCP / IP, 'N' open sockets **

...
I use ocilib-4.2.1 and Oracle 12c ( oracle oci 12.1)
...

What can be happening?

Thank's
JM

OCI_Break has no effect when called under linux

I have an app that is compiled for both windows 64bit and linux (centos 6.5) 32bit.
OCI_Break only works on windows (I call it from a separate thread).
On linux it is definitely called, and definitely from a thread, but the thread which is locked up by ocilib call never unlocks upon OCI_Break's execution an continues to hang until DB connection is reestablished.

P.S. I tried on both ocilib 3.x and the latest one from repo

Bulk insert calls when ExecutePrepared () function, which leads to the block for a long time

Why I simulate add 50000 records, in ExecutePrepared () function call block at least 5 minutes.
Below is my test example, platform is Windows 10 oracle11g

typedef struct _User
{
int nID;
int nAge;
}User;

int main(void)
{
ostringstream oss;
vector vtrBlob;

InitEnvironment();

oss << "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=" << "127.0.0.1" <<")(PORT="<< "1521" <<"))(CONNECT_DATA=(SERVICE_NAME="<<"orcl"<<")))";
ostring strConn = oss.str();
Connection conn(strConn.c_str(), "test", "test"/*,Environment::SessionSysDba*/);
try
{
    Blob blob(conn);
    User user;
    user.nID = 1;
    user.nAge = 10;
    Raw raw((unsigned char*)&user,(unsigned char*)&user+sizeof(User));
    blob.Write(raw);

    int nItem = 0;
    vtrBlob.reserve(50000);
    for(;nItem < 50000;nItem++)
    {
        vtrBlob.push_back(blob);
    }
    Statement st(conn);
    try
    {
        ostring insertSql = "insert into test_blob (data) values (:data)";
        st.Prepare(insertSql);
        st.SetBindArraySize(vtrBlob.size());
        st.Bind(OTEXT(":data"),vtrBlob,BindInfo::In);
        st.ExecutePrepared();
    }
    catch(Exception &ex)
    {
        std::cout << ex.GetOracleErrorCode() << " " << ex.what() << std::endl;
    }

    conn.Commit();
}
catch(Exception &ex)
{
     std::cout << ex.what() << std::endl;
}
conn.Close();
UnInitEnvironment();
return EXIT_SUCCESS;

}

The latest version has a memory leak (Ver4.2)

Ocilib is using a static compilation mode,

Test C and C + + has a memory leak,
A total of five memory leak,
four are caused :OCI_MemAllocOracleClient, OCI_MemReallocOracleClient, OCI_MemFreeOracleClient,

The test code:

define TEST_CPP

include "vld.h"

ifdef TEST_CPP

#include "ocilib.hpp"
using namespace ocilib;

else

#include "ocilib.h"

endif

//static Connection con;
void err_handler(OCI_Error *err)
{
int err_type = OCI_ErrorGetType(err);
}

int main(int argc, char* argv[])
{

ifdef TEST_CPP

Environment::Initialize(Environment::Threaded);
Environment::Cleanup();

else

OCI_Initialize(err_handler, NULL, OCI_ENV_DEFAULT | OCI_ENV_THREADED | OCI_ENV_CONTEXT);
OCI_Cleanup();

endif

return 0;

}


Visual Leak Detector detected 5 memory leaks (1452 bytes).
Largest number used: 327702 bytes.
Total allocations: 327702 bytes.
Visual Leak Detector is now exiting.

ps:

WARNING: Visual Leak Detector detected memory leaks!
---------- Block 11 at 0x0000000074D46FE0: 40 bytes ----------
Leak Hash: 0x6F125A85, Count: 1, Total 40 bytes
Call Stack (TID 17252):
0x0000000007201E70 (File and line number not available): MSVCR120D.dll!malloc
c:\projects\consoleapplication2\consoleapplication2\ocilib\memory.c (70): ConsoleApplication2.exe!OCI_MemAlloc + 0xB bytes
c:\projects\consoleapplication2\consoleapplication2\ocilib\memory.c (426): ConsoleApplication2.exe!OCI_MemAllocOracleClient
0x00000000755D3680 (File and line number not available): OraOCIEI11.dll!kpufhndl0 + 0xF162 bytes
0x0000000075834A0D (File and line number not available): OraOCIEI11.dll!kpeDbgHdlPostop + 0x16AB bytes
0x0000000075833AC5 (File and line number not available): OraOCIEI11.dll!kpeDbgHdlPostop + 0x763 bytes
0x0000000076DFAE16 (File and line number not available): OraOCIEI11.dll!nlstdgg + 0x3EAE bytes
0x0000000076DF8870 (File and line number not available): OraOCIEI11.dll!nlstdgg + 0x1908 bytes
0x0000000076DF72B0 (File and line number not available): OraOCIEI11.dll!nlstdgg + 0x348 bytes
0x0000000076EF70E1 (File and line number not available): OraOCIEI11.dll!ztub64d + 0x26683 bytes
0x0000000075834704 (File and line number not available): OraOCIEI11.dll!kpeDbgHdlPostop + 0x13A2 bytes
0x0000000075833C07 (File and line number not available): OraOCIEI11.dll!kpeDbgHdlPostop + 0x8A5 bytes
0x00000000755D48E2 (File and line number not available): OraOCIEI11.dll!kpummTLSGET1 + 0x68 bytes
0x00000000758334A6 (File and line number not available): OraOCIEI11.dll!kpeDbgHdlPostop + 0x144 bytes
0x00000000755D2A44 (File and line number not available): OraOCIEI11.dll!kpufhndl0 + 0xE526 bytes
0x00000000755CF39D (File and line number not available): OraOCIEI11.dll!kpufhndl0 + 0xAE7F bytes
0x000000007643087E (File and line number not available): OraOCIEI11.dll!OCIEnvCreate + 0x6A bytes
0x0000000080019211 (File and line number not available): OCI.dll!OCIEnvCreate + 0xB9 bytes
c:\projects\consoleapplication2\consoleapplication2\ocilib\library.c (1395): ConsoleApplication2.exe!OCI_Initialize + 0x48 bytes
c:\projects\consoleapplication2\consoleapplication2\ocilib\ocilib_impl.hpp (1146): ConsoleApplication2.exe!ocilib::Environment::SelfInitialize + 0x33 bytes
c:\projects\consoleapplication2\consoleapplication2\ocilib\ocilib_impl.hpp (918): ConsoleApplication2.exe!ocilib::Environment::Initialize
c:\projects\consoleapplication2\consoleapplication2\consoleapplication2.cpp (22): ConsoleApplication2.exe!main + 0x38 bytes
f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c (626): ConsoleApplication2.exe!__tmainCRTStartup + 0x19 bytes
f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c (466): ConsoleApplication2.exe!mainCRTStartup
0x00000000394B8102 (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x22 bytes
0x0000000039BAC2E4 (File and line number not available): ntdll.dll!RtlUserThreadStart + 0x34 bytes
Data:
FF FF FF FF 28 00 00 00 43 3A 5C 55 73 65 72 73 ....(... C:\Users
5C 63 6D 6C 5C 4F 72 61 63 6C 65 5C 6F 72 61 64 \cml\Ora cle\orad
69 61 67 5F 63 6D 6C 00 iag_cml. ........

Can't upload test project, directory as follows
20160107162040
One of the leak is out here:
20160107162453

Connection was obtained from the connection pool wait time is very long

From the connection pool for a link to wait a long time when, but into a single link to connection speed is quite fast

my test platform
window 10, qt 4.6.2 ,

test code:
int main()
{
char strTNS[] = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl)))";
Environment::Initialize(Environment::Default | Environment::Threaded);
Environment::EnableWarnings(true);
Pool connPool;
Connection conn;
cout << "Oracle Connection Start Time: "<< time(NULL)<< std::endl;
conn.Open(strTNS,"test","test");
cout << "Oracle Connection Start Time: "<< time(NULL)<< std::endl;
conn.Close();
connPool.OpenOpen(strTNS,"test","test",Pool::ConnectionPool,1,5);
cout << "Oracle Pool Get Connection Start Time: "<< time(NULL)<< std::endl;
Connection poolConn = connPool.GetConnection();
cout << "Oracle Pool Get Connection End Time: "<< time(NULL)<< std::endl;
poolConn.Close;

 Environment::Cleanup();

 return 0;

}

output result:
Oracle Connection Start Time: 1465606583
Oracle Connection End Time:1465606583
Oracle Pool Get Connection Start Time: 1465606583
Oracle Pool Get Connection End Time: 1465606592

Problem using BigInts as output parameters from procedure calls.

There is a problem using BinInt typed items to return OUT parameters of stored procedures.

Example procedure:
create or replace procedure test_big_int(value_in in number, value_out out number) is
begin
value_out := value_in;
end;

Example C code:

big_int bi = 0;
OCI_Prepare(st, "begin test_big_int(45, :1); end;");
OCI_BindBigInt(st, ":1", &bi);
OCI_Execute(st);

With the procedure call in the form shown above ("begin proc(...); end;") the bi variable is updated.

However, if the procedure call is changed to the otherwise equivalent "call proc(...)" the bi variable is not updated.

About OCI_MemAllocOracleClient caused by the memory leak

A memory leak has been resolved in 6b60250f6b62d4f96d380cde539cba5a83a718fb,
But VLD can still detect the leakage of memory in 4 places., which is normal?

Cause the place is:filename:library.c
call_status = OCI_SUCCESSFUL(OCIEnvCreate(&OCILib.env, oci_mode,
(dvoid ) &OCILib,
OCI_MemAllocOracleClient,
OCI_MemReallocOracleClient,
OCI_MemFreeOracleClient,
(size_t) 0, (dvoid *
) NULL));

Enabled by OCI_MemAllocOracleClient, OCI_MemReallocOracleClient, OCI_MemFreeOracleClient will cause leakage, in the early version of the 3.X, no use, the value is NULL is normal,This problem is in #25 ,
OCI_MemAlloc ?
In the wndows system, using the ocilib and test examples files together to compile and lead VLD can be found.
ConsoleApplication2.exe!ocilib::Environment::Initialize->Environment::SelfInitialize>-OCI_Initialize>OCI.dll!OCIEnvCreate-> OraOCIEI11.dll!LhtIntCreate()->ConsoleApplication2.exe!OCI_MemAllocOracleClient->ConsoleApplication2.exe!OCI_MemAlloc

xshot-0003

compatibility Oracle8i

my plan is to use ocilib for an big/old software-project which right now use Oracle8 (8.1.7) as DB.
so i plan to use ocilib in the beginning with the existing Oracle8 and in the end with an actual Oracle12.

But i run into several problems to use ocilib with oracle8.

Additional Informations:
ocilib version: version 4.2.0 (2015-09-21)
OS: openSuSE 13.2 x64
configure-command: ./configure --prefix=/home/sd1/tmp/ocilib/install/ --build=i686-pc-linux-gnu "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32"
(atm it's a 32bit project).

this problems i discoverd:

  1. not all headerfiles are located in $ORACLE_HOME/rdbms/public, there are a couple of files located in $ORACLE_HOME/rdbms/demo ... so i created soft-links in $ORACLE_HOME/rdbms/public to ../demo/

  2. more important:
    i was not able to build ocilib and/or example for ocilib (the minimal c-example from here: http://vrogier.github.io/ocilib/doc/)

I just commented source so that i was able to compile/link.
that files need modifications:
./src/interval.c
eg.: interval.c:158:43: error: ‘IntervalTypeValues’ undeclared (first use in this function)
OCI_CHECK_ENUM_VALUE(con, NULL, type, IntervalTypeValues, OTEXT("Interval type"));

./src/statement.c
eg.: statement.c:3102:18: error: ‘code’ undeclared (first use in this function)
OCI_NOT_USED(code)
statement.c:3276:49: error: ‘LobTypeValues’ undeclared (first use in this function)
OCI_CHECK_ENUM_VALUE(stmt->con, stmt, type, LobTypeValues, OTEXT("Lob type"))

./src/column.c

./src/lob.c

./src/dirpath.c
eg.: undefined reference to `OCIDirPathColArrayEntrySet'

i try to add the files to that report (just add .txt so that it's accepted to upload) ... all changes should be marked with 'KONNI' or 'konni'
but will work ocilib correct with 'just' commend that parts of the source-code?
so can i use ocilib with oracle8 in productive enviroment? (with that changes?)

Hopefully that informations are helpfull for you, maybe there is a answer (or fix?) for Oracle8i?
Greetings from Austria, Markus

column.c.txt
dirpath.c.txt
interval.c.txt
lob.c.txt
statement.c.txt

Columns with varrays never gets NULL while fetching

Hi Vincent,
i fetch data from a table which contains a column with an "varray(10) of integer".
For some rows the column with the int-array is set to NULL.
If I now fetch the data with different settings of "OCI_SetFetchSize(st, 10)" i get different results:

  • OCI_IsNull() never gets TRUE even if the column with the int-array is definitly null
    
  • the first array fetch gives correct data for the size of the int-array (OCI_CollGetSize is 0)
    
  • the following array fetches didnt clean the previous results, so arrays which are NULL will have a size and data from the previous fetch
    

affected Version: 4.2.1
sourcecode is attached

Regards
Herbert Metzdorf
testcoll.zip

oculib and openssl have type conflicts

my c++ code is :

#include <stdio.h>

#include <ocilib.h>
#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>

int main(int argc, char *argv[])
{
    printf("Hello, world\n");

    return 0;
}

Compile error is :
In file included from /usr/include/openssl/objects.h:960,
from /usr/include/openssl/evp.h:98,
from /usr/include/openssl/x509.h:73,
from /usr/include/openssl/ssl.h:156,
from ocitest.c:5:
/usr/include/openssl/asn1.h:526: error: multiple types in one declaration
/usr/include/openssl/asn1.h:526: error: declaration does not declare anything

I found that /usr/include/openssl/asn1.h:526 boolean variable is conflicts with ocilib.h:#define boolean int

I replace it to OCIBoolean, and than is Compile successfully.

Poor English, please forgive me.
thx!

Connection leak at Oracle server end

Connection leaks are happening at oracle server end whenever there are timeout happens.
We have configured following parameters at sqlnet.ora for send/recv/connect timeout which is working fine.

SQLNET.SEND_TIMEOUT = 60
SQLNET.RECV_TIMEOUT = 60
TCP.CONNECT_TIMEOUT = 60
SQLNET.INBOUND_CONNECT_TIMEOUT = 60

Our code snippet:

if(!OCI_ExecuteStmt(st,query))
{
err = OCI_GetLastError();
debugLogging(ERRLOG,DEBUG_LEVEL,"SE,%s,%s",OCI_ErrorGetString(err),stCallCDR.msgId);
OCI_StatementFree(st);
OCI_ConnectionFree(cn);

                            continue;
                    }

Application Error Logging:

09-08-2016 15:05:04:077,SE,ORA-12609: TNS: Receive timeout occurred,147073525815394422530

Connection at our end:

    4 active connection (ESTABLISED state)

Connection at server end:

192  connection from our node.

Issue & Resolutions:

    No further insertion or operations are happening on server. Need to kill the server end connections.

problem about OCI_ElemInit()

Hi,vrogier
IN the lastest version , OCI_IterFree() now works well, and the memory retention problem has been resolved, thanks for your excellent work!
But now, I have anothoer problem. I use OCI_ElemSetDouble() function,and then I use OCI_CollGetElem() and OCI_ElemGetDouble() to get the value of element, the result is wrong.
My test code like this:

void testocilib(std::string dburl, std::string username, std::string password, std::string tablename)
{
OCI_Connection *cn;
OCI_Statement *st;
OCI_Coll *coll_ord;
OCI_Elem *elem_ord;
OCI_TypeInfo *tif_ord;
int i;
int elemnum = 4;

int isSus = OCI_Initialize(0, 0, OCI_ENV_CONTEXT);
cn = OCI_ConnectionCreate(dburl.c_str(), username.c_str(), password.c_str(), OCI_SESSION_DEFAULT);
st = OCI_StatementCreate(cn);

/* retreive type info */
tif_ord = OCI_TypeInfoGet(cn, "MDSYS.SDO_ORDINATE_ARRAY", OCI_TIF_TYPE);

/* create sub arrays */
coll_ord = OCI_CollCreate(tif_ord);

/* create sub array element accessors */
elem_ord = OCI_ElemCreate(tif_ord);


/* build ordinates collection with test values */
for (i = 0; i < elemnum; i++)
{
    OCI_ElemSetDouble(elem_ord, ((double) i + 0.123456));
    OCI_CollAppend(coll_ord, elem_ord);
    OCI_ElemSetDouble(elem_ord, ((double) i + 0.789000));
    OCI_CollAppend(coll_ord, elem_ord);
}


for (i = 1; i <= OCI_CollGetSize(coll_ord);i++)
{
    OCI_Elem* cur_elem = OCI_CollGetElem(coll_ord,i);
    double elem_value = OCI_ElemGetDouble(cur_elem);
    printf("The %d Elem is %lf\n",i,elem_value);
}

/* free local objects */
OCI_CollFree(coll_ord);
OCI_ElemFree(elem_ord);

//statement
if (0 != st)
{
    OCI_StatementFree(st);
    st = 0;
}
//connection
if (0 != cn)
{
    OCI_ConnectionFree(cn);
    cn = 0;
}
OCI_Cleanup();

}

the output is : all elements are zero!
My platform is VS2010, Oracle 11g, OCI_CHARSET_ANSI.
I check the element.c file , I found that : In the lastest release version, in element.c file, OCI_ElemInit has been modified, the code
case OCI_CDT_NUMERIC:
{
if (!elem->handle)
{
elem->handle = (OCINumber *) OCI_MemAlloc(OCI_IPC_VOID, sizeof(OCINumber), 1, TRUE);
}
break;
}
has been commented out,
and in OCI_ElemFree():

if ((OCI_OBJECT_ALLOCATED == elem->hstate) && (OCI_CDT_NUMERIC == elem->typinf->cols[0].datatype))
{
    OCI_FREE(elem->handle)
}

has also been commented out.
I add the two section of codes in the element.c again, and now the result is correct.

So , I think these two sections of code should not been commented out.
Would you check the element.c again? Thanks!

ResultSet::next() crashes!!!

hi , I met an occi problem, I want to get interval value from oracle, but it was crashed ,why?
the stack is:
`
favorite
#0 0x0000003d7e432925 in raise () from /lib64/libc.so.6
#1 0x0000003d7e43408d in abort () from /lib64/libc.so.6
#2 0x00007ff601e3ba55 in os::abort(bool) () from /usr/java/jdk1.7.0_67-cloudera/jre/lib/amd64/server/libjvm.so
#3 0x00007ff601fbbf87 in VMError::report_and_die() () from /usr/java/jdk1.7.0_67-cloudera/jre/lib/amd64/server/libjvm.so
#4 0x00007ff601e4096f in JVM_handle_linux_signal () from /usr/java/jdk1.7.0_67-cloudera/jre/lib/amd64/server/libjvm.so
#5
#6 0x00007ff5fe8f218e in LdiInterFromArray () from /home/zhaojuan/project/DataType/thirdparty/occi-11.2/lib/libclntsh.so.11.1
#7 0x00007ff5ff85a1eb in kpcceiyd2iyd () from /home/zhaojuan/project/DataType/thirdparty/occi-11.2/lib/libclntsh.so.11.1
#8 0x00007ff600138c1d in ttccfpg () from /home/zhaojuan/project/DataType/thirdparty/occi-11.2/lib/libclntsh.so.11.1
#9 0x00007ff600136e90 in ttcfour () from /home/zhaojuan/project/DataType/thirdparty/occi-11.2/lib/libclntsh.so.11.1
#10 0x00007ff5fe5c45f3 in kpufcpf () from /home/zhaojuan/project/DataType/thirdparty/occi-11.2/lib/libclntsh.so.11.1
#11 0x00007ff5fe5c2872 in kpufch0 () from /home/zhaojuan/project/DataType/thirdparty/occi-11.2/lib/libclntsh.so.11.1
#12 0x00007ff5fe5c110f in kpufch () from /home/zhaojuan/project/DataType/thirdparty/occi-11.2/lib/libclntsh.so.11.1
#13 0x00007ff5fe556a03 in OCIStmtFetch () from /home/zhaojuan/project/DataType/thirdparty/occi-11.2/lib/libclntsh.so.11.1
#14 0x00007ff600a29b33 in oracle::occi::ResultSetImpl::next(unsigned int) () from /home/zhaojuan/project/DataType/thirdparty/occi-11.2/lib/libocci.so.11.1
#15 0x0000000000c6f481 in xcloud::xos::OracleLoader::RunLoadMain (this=0x78e6680) at /home/zhaojuan/project/DataType/be/src/exec_xos/OracleLoader.cpp:366'

setbuffer code:
if (ttype == oracle::occi::OCCI_SQLT_INTERVAL_YM) { LOG(INFO) << "set YM buffer"; m_res->setDataBuffer(i + 1, m_colBuf[i], ttype, 5, &(m_resultInfos[i].fieldLens[0]), &(m_resultInfos[i].fieldFlags[0]), &(m_resultInfos[i].fieldRCs[0])); } else if (ttype == oracle::occi::OCCI_SQLT_INTERVAL_DS) { m_res->setDataBuffer(i + 1, m_colBuf[i], ttype, 11, &(m_resultInfos[i].fieldLens[0]), &(m_resultInfos[i].fieldFlags[0]), &(m_resultInfos[i].fieldRCs[0])); }
m_res is a type of oracle::occi::ResultSet*
m_colBuf[i] is alloc(colWidth[i] * fetchsize)
and it was crashed at:
if (0 == m_res->next(m_fetchSize)) { LOG(INFO) << "Oracle Fetch finished!"; break; }

error.c can't use calloc and OCI_FREE

The memory allocated

OCI_Error *err = (OCI_Error *) calloc(1, sizeof(*err));

but deleted with

OCI_FREE(err)

Either the allocation must be changed or the free function must be called instead of OCI_FREE since OCI_FREE tries to free the memory pointer - sizeof(*mem_block) instead of the allocated memory using calloc

Build problem

Greetings i have configured the library with

./configure --with-oracle_home=/opt/oracle/instantclient --with-oracle_headers_path=/opt/oracle/instantclient/include --with-oracle_lib_path=/opt/oracle/instantclient

everything goes ok but when i invoke make the following is returned

configure.ac:24: the top level
configure:10484: error: possibly undefined macro: LT_MAJOR
If this token and others are legitimate, please use m4_pattern_allow.
See the Autoconf documentation.
make: *** [configure] Error 1

I tried

autoreconf -fi

but the following is returned

../libtool: line 478: CDPATH: command not found
libtool: Version mismatch error. This is libtool 2.4.2 Debian-2.4.2-1.7ubuntu1, but the
libtool: definition of this LT_INIT comes from an older release.
libtool: You should recreate aclocal.m4 with macros from libtool 2.4.2 Debian-2.4.2-1.7ubuntu1
libtool: and run autoconf again.
make[2]: *** [libocilib_la-array.lo] Error 63

Thank you in advance.

Issue with OCI_DirPathSetColumn() and custom format numeric columns

Reporting an issue found by an ocilib user and reported on sourceforge mailing list

Hello everybody,

I am new to OCILIB (4.2.0 on Linux) and I try to extend and run the example ocilib_demo.c
I want to test a NUMBER(10,2) column.
So I extend the test table and add some code to the test program:

#define NUMFORM "9999999.99" 

OCI_DirPathSetColumn(dp,1,"VAL_INT", SIZE_COL1,NULL);
OCI_DirPathSetColumn(dp,2,"VAL_STR", SIZE_COL2,NULL);
OCI_DirPathSetColumn(dp,3,"VAL_DATE", SIZE_COL3,"YYYYMMDD");
OCI_DirPathSetColumn(dp,4,"VAL_FLOAT", SIZE_COL4,NUMFORM);      <- new  e.g. #define NUMFORM    "%f"

And:

sprintf(val1, "%4d",i + (i*100));
sprintf(val2, "value %05d",j + (i*100));
sprintf(val3, "%04d%02d%02d",(j%23)+1+2000, (j%11)+1, (j%23)+1);
sprintf(val4, "%4.2f",1.01);                                            <-new

OCI_DirPathSetEntry(dp,j,1,val1,(unsigned int) strlen(val1),TRUE);
OCI_DirPathSetEntry(dp,j,2,val2,(unsigned int) strlen(val2),TRUE);
OCI_DirPathSetEntry(dp,j,3,val3,(unsigned int) strlen(val3),TRUE);
OCI_DirPathSetEntry(dp,j,4,val4,(unsigned int) strlen(val4),TRUE);      <- new

I try a lot of different things but the column in the database is always NULL. With the help of a debugger I see that
the function OCI_NumberToString doesn’t return something in its output (out_value, out_value_size)

What’s wrong?

Thank you in advance

Meaning of call_status inverted in OCI_Fetch(First|Next|Prev|Last) functions

For example, in resultset.c:1119, the address of the call_status variable is passed to OCI_FetchData() as its formal parameter err. Without further modification, the value of call_status is then passed to OCI_ContextCallExit() as its formal parameter named success (see line 1164, inside macro OCI_LIB_CALL_EXIT() and library.c:686). This parameter only matters if err->type != OCI_UNKNOWN (0), which is why successful executions without warnings are not affected by the bug. The net effect is that warnings are escalated to errors and true errors are suppressed.

Of all callers of OCI_FetchData(), only OCI_FetchCustom() appears to be unaffected, because it doesn't use the value and just passes it back to its caller. The other four (OCI_FetchFirst|Next|Prev|Last) pass it unchanged to OCI_ContextCallExit(), effectively inverting its meaning.

Can't set prefetch size to 0

I want to disable prefetch, so I do:

Statement st(cn);
st.SetPrefetchSize(0);
st.SetPrefetchMemory(0);
st.Execute("SELECT * from my_table");
auto p = st.GetPrefetchSize(); // returns 20
auto m = st.GetPrefetchMemory();

but it uses default value(20)

Compile on VS2010

Please help about compilation of last version (commit on Jun 3, 2016) on VS2010

Procedures:
OCI_NumberAdd
OCI_NumberSub
OCI_NumberMultiply
OCI_NumberDivide

Gives src\number.c(872): error C2275: 'OCINumber': illegal use of this type as an expression

Cppcheck findings

[src/connection.c:196]: (error) Possible null pointer dereference: con
[src/memory.c:116]: (error) Common realloc mistake: 'mem_block' nulled but not freed upon failure

connection.c

Line 194 should be (but probably there will be an error before if item=NULL which probably will crash the application)
if (res && con)

if item still is NULL, then it fails (following a NULL pointer):

 90     OCI_Connection *con  = NULL;
 91     OCI_Item       *item = NULL;
 92     boolean         res  = TRUE;
 93 
 94     /* create connection object */
 95 
 96     item = OCI_ListAppend(OCILib.cons, sizeof(*con));
 97 
 98     if (item)
 99     {

190     }
191 
192     /* update internal status */
193 
194     if (res)
195     {
196         con->cstate = OCI_CONN_ALLOCATED;
197     }

memory.c

115     {
116         mem_block = (OCI_MemoryBlock *)realloc(mem_block, size);
117 

if realloc fails, the return value is NULL, but the memory still exist and now the old memory pointer is overwritten and therefore the memory is lost.

test ccilib/demo/pool.cpp error

char db[] = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl)))";
Pool pool(db,"usr","pwd",Pool::ConnectionPool,1,10);

The Show oracle error:
ORA-24404: connection pool does not exist

The problem how to solve

Binding CLOB/BLOB as OUT parameter of a PL/SQL procedure can lead to an Oracle error / Segfault

When binding a OCI_Lob C handle (Clob or Blob object in C++) using OCI_BDM_OUT (BindInfo::Out in C++) to an OUT CLOB/NCLOB/BLOB parameter of a PL/SQL procedure can lead to:

  • unexpected result (segmentation fault)
  • Oracle error if the parameter of the procedure is IN OUT

This is a bug in the internal method OCI_BindCheck() of the C API.
In case of OCI_BDM_OUT only bind direction mode, the method does not set the content of the loblocator handle pointer passed to Oracle client.
Then the Oracle client is trying to set the content of that pointer to the value returned from the procedure. As the pointer is NULL, a segfault occurs !

C++ API Bind ostring has a memory leak

Bind ostring ,Visual Leak Detector detected a memory leak. in st.Bind(":1", test, 0, BindInfo::In); why? Bind use is not right? not Call ClearBinds()?
CODE:

int main()
{
    try
    {
        Environment::Initialize();
        Connection con;
        con.Open(dbs, usr, pwd, Environment::SessionDefault);
        ostring test= "test";
        Statement st(con);
        st.Prepare("declare v_ename varchar2(10); begin v_ename:= :1 ; end;");
        st.Bind(":1", test, 0, BindInfo::In);
        st.ExecutePrepared();
        con.Close();
    }
    catch (std::exception &ex)
    {
        std::cout << ex.what() << std::endl;
    }
    Environment::Cleanup();
    return EXIT_SUCCESS;
}

Korean Characters & C++

Hi,

i need to write Korean Characters (example: 구결/口訣) into an Oracle database via a C++ Middleware that is using the OCILIB.
It is already possible to write and save these characters with a C# Service that uses the Oracle-Libs, which means that the Database should be configured correctly.

The C++ Middleware runs on Linux and we set the NLS_LANG to GERMAN_GERMANY.AL32UTF8.
I am able to see the characters in the console/log but if i try to write them into the database via an Object that accepts the values as parameters they turn to '¿¿¿¿'.

The C#-Service uses the same Objects to write the data.

The values are bound as strings (std::string) in the C++ Middleware.
Do i need to adjust anything else than the NLS_LANG to make this work?
For example the Binding?

I could not find anything that matters in the OCILIB C Documentation and there aren't any examples for C++ for cases with special characters.

We tried for days but the characters ultimately end up as '¿¿¿¿' in the database tables if we write them via the C++ Middleware.

Thanks for your help!

Support of Oracle native VARCHAR2 as Pascal-like strings (C-like strings are lossy for some cases)

Oracle allows to store strings which contain 0x0 character in the middle, it could be shown in the sample query below:

SELECT value, LENGTH(VALUE), dump(VALUE) FROM (
  SELECT 'test' || chr(0) || 'me' VALUE FROM dual
)

ocilib is not able to handle such strings, part after 0x0 character is being lost, so it will be better to implement support of Oracle native OCI_Varchar2 complex datatype (with will contain data length and pointer to data), OCI_GetVarchar2(), OCI_BindVarchar2() in addition to otext, OCI_GetString(), OCI_BindString(). It need to be implemented as enhancement, not as replacement - the same string value might be accessed different ways.

Direct Path API also need to be extended to handle the OCI_Varchar2 type.

Initially the data loss issue was detected in code which replicates tables (ETL task) between production databases. The #0 symbol was initially introduced as data separator, CSV like, in third-party solution, so it's not possible to avoid such case.

Problem in OCI_CollFree()

Hi vrogier,
When I use function OCI_CollFree(), I find it does not work well. I check the source code, in the file
collection.c : line 147:
/* free data element /
if (coll->elem)
{
coll->elem->hstate = OCI_OBJECT_FETCHED_DIRTY;
OCI_ElemFree(coll->elem);
coll->elem = NULL;
}
I guess the coll handle only free one elem, not free all elem in the collection, it may lead to memory leak.
I write some sample code like this:
OCI_Object
GEOMETRY = NULL;
OCI_TypeInfo* obj_type = OCI_TypeInfoGet(connection, "MDSYS.SDO_GEOMETRY", OCI_TIF_TYPE);
OCI_TypeInfo* coll_type = OCI_TypeInfoGet(connection, "MDSYS.SDO_ORDINATE_ARRAY", OCI_TIF_TYPE);
while(1)
{
OCI_Coll* sdo_ordinate_array = OCI_CollCreate(coll_type);
OCI_CollFree(sdo_ordinate_array);
}

   Memory leak happens.
  I suggest the source code maybe modify like this:
    /* free data element */

for(int i = 0; i < OCI_CollGetSize(coll); ++i)
{
OCI_Elem elem = OCI_CollGetElem(coll,i);
if (elem)
{
elem ->hstate = OCI_OBJECT_FETCHED_DIRTY;
OCI_ElemFree(elem);
elem = NULL;
}
}

Subscription.Register crashes if subscribtion files

Running example code from "Database notifications" will cause crash if Register fails

  Subscription sub;
  sub.Register(con, "sub-00", Subscription::AllChanges, EventHandler, 5468, 0);

Tested both running on Red Hat Enterprise Linux Server release 6.5 (Santiago) and Oracle Solaris 10 8/11 s10s_u10wos_17b SPARC using GCC 4.9.2 compiler.

Running sample code
Step 1
Step 2
Step 3
Step 4
Step 5
Step 6
Step 7
Step 8
*** glibc detected *** ./eventTest: double free or corruption (!prev): 0x000000000191d030 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3edb475e66]
/lib64/libc.so.6[0x3edb4789b3]
/vobs/thirdparty/ocilib/installed/linux/lib/libocilib.so.4(OCI_StatementFree+0x4e)[0x7f087aab85ae]
./eventTest[0x409641]
./eventTest[0x409868]
./eventTest[0x40c1ce]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x3edb41ed5d]
./eventTest[0x404211]

Connected to:

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, Automatic Storage Management, OLAP, Data Mining
and Real Application Testing options

Running with gdb
Program received signal SIGABRT, Aborted.
0x0000003edb432625 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
64 return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);
(gdb) bt
#0 0x0000003edb432625 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1 0x0000003edb433e05 in abort () at abort.c:92
#2 0x0000003edb470537 in __libc_message (do_abort=2, fmt=0x3edb558820 " glibc detected %s: %s: 0x%s **\n")
at ../sysdeps/unix/sysv/linux/libc_fatal.c:198
#3 0x0000003edb475e66 in malloc_printerr (action=3, str=0x3edb558bb0 "double free or corruption (!prev)",
ptr=<value optimized="" out="">) at malloc.c:6336
#4 0x0000003edb4789b3 in _int_free (av=0x3edb78fe80, p=0x6fd030, have_lock=0) at malloc.c:4832
#5 0x00007ffff7dd85ae in OCI_StatementFree () from /vobs/thirdparty/ocilib/installed/linux/lib/libocilib.so.4
#6 0x0000000000409641 in ocilib::HandleHolder<OCI_Statement*>::SmartHandle::~SmartHandle() ()
at /home/kornefab/ocilib/linux/include/ocilib_impl.hpp:702
#7 0x0000000000409868 in ocilib::HandleHolder<OCI_Statement*>::SmartHandle::Release(ocilib::HandleHolder<OCI_Statement*>) ()
at /home/kornefab/ocilib/linux/include/ocilib_impl.hpp:710
#8 0x000000000040c1ce in main () at eventTest.cpp:38

source code
#include <iostream>
#include "ocilib.hpp"
#include <unistd.h>

using namespace ocilib;
using namespace std;
#ifdef _WINDOWS
#define sleep(x) Sleep(x*1000)
#endif
#define WaitForEvents()   sleep(5)
#define WaitForDatabase() sleep(60)
static std::map<unsigned int, ostring> EventTypes;
static std::map<unsigned int, ostring> ObjectEvents;
void EventHandler(Event &evt);
void SetupNames();
int main(int argc, char* argv[])
{
   if (argc != 4) // Check number of arguments
   {
      cout << "eventTest user pwd connection" << endl;
      return -1;
   }
   string user(argv[1]);
   string pwd(argv[2]);
   string connect(argv[3]);
   int count=0;
   SetupNames();
   cerr << "Step " << (++count) << endl;
   try
   {
      Environment::Initialize(Environment::Events);
   cerr << "Step " << (++count) << endl;
      //Connection con("db", "usr", "pwd");
      Connection con(connect, user, pwd);
   cerr << "Step " << (++count) << endl;
      con.SetAutoCommit(true);
   cerr << "Step " << (++count) << endl;
      Statement st(con);
   cerr << "Step " << (++count) << endl;
      st.Execute("create table table1(code number)");
   cerr << "Step " << (++count) << endl;
      st.Execute("create table table2(str varchar2(10))");
   cerr << "Step " << (++count) << endl;
      Subscription sub;
   cerr << "Step " << (++count) << endl;
      sub.Register(con, "sub-00", Subscription::AllChanges, EventHandler, 5468, 0);
   cerr << "Step " << (++count) << endl;
      sub.Watch("select * from table1");
   cerr << "Step " << (++count) << endl;
      sub.Watch("select * from table2");
   cerr << "Step " << (++count) << endl;
      st.Execute("alter table table1 add price number");
   cerr << "Step " << (++count) << endl;
      WaitForEvents();
   cerr << "Step " << (++count) << endl;
      st.Execute("insert into table1 values(1, 10.5)");
   cerr << "Step " << (++count) << endl;
      st.Execute("insert into table2 values('shoes')");
   cerr << "Step " << (++count) << endl;
      WaitForEvents();
   cerr << "Step " << (++count) << endl;
      st.Execute("update table1 set price = 13.5 where code = 1");
   cerr << "Step " << (++count) << endl;
      st.Execute("delete from table2 ");
   cerr << "Step " << (++count) << endl;
      WaitForEvents();
   cerr << "Step " << (++count) << endl;
      st.Execute("drop table table1");
   cerr << "Step " << (++count) << endl;
      st.Execute("drop table table2");
   cerr << "Step " << (++count) << endl;
      WaitForEvents();
   cerr << "Step " << (++count) << endl;
      con.Close();
   cerr << "Step " << (++count) << endl;
      /* start remote instance */
   cerr << "Step " << (++count) << endl;
      Environment::StartDatabase("db", "sys_usr", "sys_pwd", Environment::StartForce, Environment::StartFull);
   cerr << "Step " << (++count) << endl;
      /* shutdown remote instance */
      Environment::ShutdownDatabase("db", "sys_usr", "sys_pwd", Environment::ShutdownAbort, Environment::ShutdownFull);
   cerr << "Step " << (++count) << endl;
      WaitForDatabase();
   cerr << "Step " << (++count) << endl;
      sub.Unregister();
   cerr << "Step " << (++count) << endl;
   }
   catch (std::exception &ex)
   {
      std::cout << ex.what() << std::endl;
   }
   Environment::Cleanup();
}
void SetupNames()
{
   EventTypes[Event::DatabaseStart] = "Startup";
   EventTypes[Event::DatabaseShutdown] = "Shutdown";
   EventTypes[Event::DatabaseShutdownAny] = "Shutdown Any";
   EventTypes[Event::DatabaseDrop] = "Drop Database";
   EventTypes[Event::Unregister] = "Unregister";
   EventTypes[Event::ObjectChanged] = "Object Changed";
   ObjectEvents[Event::ObjectInserted] = "Insert";
   ObjectEvents[Event::ObjectUpdated] = "Update";
   ObjectEvents[Event::ObjectDeleted] = "Delete";
   ObjectEvents[Event::ObjectAltered] = "Alter";
   ObjectEvents[Event::ObjectDropped] = "Drop";
   ObjectEvents[Event::ObjectGeneric] = "Generic";
}
void EventHandler(Event &evt)
{
   static int count=0;
   cerr << "EventHandler " << (++count) << endl;
   std::cout << "** Notification : " << evt.GetSubscription().GetName() << std::endl;
   std::cout << "** Database     : " << evt.GetDatabaseName() << std::endl;
   std::cout << "** Event        : " << EventTypes[evt.GetType()] << std::endl;
   if (evt.GetType() == Event::ObjectChanged)
   {
      std::cout << ".... Object : " << evt.GetObjectName() << std::endl;
      std::cout << ".... Action : " << ObjectEvents[evt.GetObjectEvent()] << std::endl;
      std::cout << ".... RowID  : " << evt.GetRowID() << std::endl;
   }
   std::cout << std::endl;
}

Cursors not removed when register out variable for insert statement

We get the exception "ORA-01000, maximum open cursors exceeded is thrown in the log" after a number of INSERT with RETURNING xxx INTO. We are using the c++ interface in ocilib 4.2.1.
I do not know if it is our uasage of ocilib that is wrong oe if it is a bug in ocilib.

The code we use look something like this:

std::string sql = "INSERT INTO xxx (y0, y1, y2, y3, ... y14) VALUES (Sequence.nextval, :1, :2,:3, ... :14) RETURNING zz INTO :15);
Statement m_statement(connection);
m_statement.Prepare(sql);
m_statement.Register<big_uint>(15);
m_statement.Bind(1, ...);
...
m_statement.Bind((15, ...);
m_statement.ExecutePrepared();
ResultSet rs = m_statement.GetResultset();
if (rs++)
{
ret64 = rs.Get<big_uint>(1);
}
int affected = m_statement.GetAffectedRows();
connection.Commit();

OCI_IsNull OCI_GetObject strange behaviour

I'm using version 4.2.1 downloaded sources released under "releases" section.

SQL File to generate problem: create_table.sql
Code to generate problem: test_case.cpp

Using staticcaly liked c++ ocilibfiles with this preprocessor defines:
OCI_CHARSET_ANSI
OCI_IMPORT_RUNTIME

IDE/Compiler: Visual Studio 2010

Symptoms:
1 wrong OCI_IsNull return value when (FIELD01 = 31 and FIELD02 = 00015)
2 hangs immediately after that

Stranges:
If I change "order by FIELD01,FIELD02" with "order by FIELD02" all goes right.

I suspect the problem is noly presenting when object type columns are used (as MDSYS.SDO_GEOMETRY).

test_files.zip

Thanks for your precious work.

If a user's password is about to expire (say in 3 days), OCI_ConnPoolGetConnection doesn't return ORA-28002

When my oracle user password is about to expire in 3 days, with the following sample code, I got error
MSG: ORA-00001: unique constraint (%s.%s) violated.

What I expect is,
ORA-28002: the password will expire within 3 days

include "ocilib.h"

include

int main(int argc, char* argv[])
{
if (!OCI_Initialize(NULL, NULL, OCI_ENV_DEFAULT | OCI_ENV_THREADED | OCI_ENV_CONTEXT))
{
wprintf(L"OCI_Initialize error\n");
return 1;
}

   OCI_ConnPool* ConnPool = OCI_ConnPoolCreate(L"ORCL",
        L"user", 
        L"pw",
        OCI_POOL_CONNECTION,
        OCI_SESSION_DEFAULT, 
        3, 
        1);

if(ConnPool == NULL)
{
              OCI_Error* err = OCI_GetLastError();
              int error = OCI_ErrorGetOCICode(err);      

              wprintf(L"MSG: %s\n", OCI_ErrorGetString(err));
              wprintf(L"OCI_ConnPoolCreate error\n");
              return 1;
}

//wait for an available connection if the pool is saturated
if(!OCI_ConnPoolSetNoWait(ConnPool, false))
{
        wprintf(L"OCI_ConnPoolSetNoWait error\n");
        return 1;
}

OCI_Connection* conn = OCI_ConnPoolGetConnection(ConnPool);
if(conn == NULL)
{
             //error happens here
             wprintf(L"OCI_ConnPoolGetConnection error\n");

             OCI_Error* err = OCI_GetLastError();
             int error = OCI_ErrorGetOCICode(err);

             //error code is 1
             wprintf(L"error: %d\n", error);

             //OCI_ErrorGetString seems not working either.
              wprintf(L"MSG: %s\n", OCI_ErrorGetString(err));

              return 1;
}

OCI_Statement* Statement = OCI_StatementCreate(conn);
OCI_ConnectionFree(conn);

wprintf(L"Press any key to exit...\n");
getchar(); 
return 0;

}

Optional support of Oracle substitution variables

In SQL*Plus code (as well as for some IDEs, and libraries, like DevArt ODAC) it's possible to specify "substitition" variables, like shown below

SELECT * FROM DUAL WHERE &subval

where subval can be presented as remaining part of SQL text, lile text " NOT EXISTS (SELECT NULL FROM ... " and so on. Most close analogue are C macroses.

Those variables are well-described here: https://blogs.oracle.com/opal/entry/sqlplus_101_substitution_varia

we need to implement such optional support for ocilib as well (it MUST be disabled by default for compatibility reason).

Oracle's OCI level seems does not support those substitition variables, from my understanding such support could be implemented at client level only

OCI_BindArrayOf not working in version 4.1.2

I use some adapter to wrap my internal datastructures into oci(lib) structures. Inside such a wrapper function I already used successfully the follwing snippet with ocilib version 3.12:

OCI_SetBindAllocation( _st, OCI_BAM_INTERNAL);

// Set array size for allocation
OCI_BindArraySetSize( _st, chunkSize );

OCI_BindArrayOfInts( _st, key.c_str(), NULL, 0);

When I try to use 4.1.2 or 4.2.0 of the library I get the follwing error:
"A null boolean pointer has been provided"

I could detect that this doesn't come from ORACLE but from orclib.

With some research I guess the following macro (in statement.c) has a typo:

#define OCI_BIND_CALL(stmt, name, data, check, type, func) 

should be

#define OCI_BIND_CALL(stmt, name, data, type, check, func) 

Direct Path API need to support Oracle native datatypes, not strings only

OCI_DirPathSetEntry by default is able to handle string values only; DATE, TIMESTAMP, NUMBER values must be passed as C-like strings only, with further conversion.

That is not true for general case, such conversion can lead to data loss issues and has some performance drabacks.

Moreover - string conversion does not allow to convert/pass some values:

  • DATE value, which is presented by all zeroed bytes in DUMP(), those can be found in PL/SQL Profiler tables);
  • some DATE values which is produced by JDBC the same way (JDBC client passes all zeroes in buffer, but some conversion still happens);
  • TIMESTAMP WITH TIMEZONE values with textual timezone info, like Europe/Moscow - those values will be silently converted into absolute offset, -03:00, losing textual part, it's known OCI limitation

Main goal is to be able to SELECT DUMP(x, 16) values from source database, covert them from textual hexadecimal back to native binary format and to pass to Direct path API calls AS-IS - that way it will be possible pass practically any value which is valid from source database point of view.

Taking values from OCI_Date and OCI_Timestamp is not an option - Oracle converts DATE values when passes them to client, and for TIMESTAMP values it's not possible to lookup into raw buffer - only handles are visible.

As result there is no need to extend list of existing OCILIB functions. We can extend existing ones next backward compatible way:

OCI_DirPathSetColumn() - if maxsize will be set to 0 and format to NULL - that can set mode to proceed with binary/no-conversion way for further OCI_DirPathSetEntry() calls;
for DATE, TIMESTAMP WITH TIME ZONE, TIMESTAMP WITH LOCAL TIME ZONE and TIMESTAMP the
dbcol->sqlcode should be set to SQLT_DAT, SQLT_TIMESTAMP_TZ, SQLT_TIMESTAMP_LTZ and... suddenly, 180, instead of SQLT_TIMESTAMP (I don't know why but it works that way only), respectively

where

OCI_DirPathSetEntry() - will take value as void pointer which we can point it to source buffer, which was built from source hexadecimal DUMP(x, 16) database function output.

Please note - for DATE values the buffer is practically always 7 byte structure
For TIMESTAMP values it can be either 11 or 7 byte structure, it depends on part which encodes fractional part of second. The same is true for TIMESTAMP WITH LOCAL TIME ZONE
For TIMESTAMP WITH TIMEZONE value size is always 13 byte structure, as I see.
For NUMBER values buffer size varies, up to 22 bytes in total.

But size of exact value is derived from database, so OCI_DirPathSetEntry() must always take into account user specified size argument

Using OCI_SetFetchMode(st, OCI_SFM_SCROLLABLE); with long column type

If I use OCI_SetFetchMode(st, OCI_SFM_SCROLLABLE);
and try to read a table with a long column type, the call
OCI_FetchLast does not work.

If I remove the column DATA_DEFAULT, it will work.

If I remove OCI_SetFetchMode(st, OCI_SFM_SCROLLABLE), the program will work but I will not really know the number of row return until I fetch them all but I need to know it prior to fetch them.

What I want is the number of rows return from the select even if they are more than 20 rows...
So I fetch the last record to get the number of row. Is there a better way?

Here is the program:

include "ocilib.h"

int main(int argc, char *argv[])
{
    OCI_Connection* cn;
    OCI_Statement* st;
    OCI_Resultset* rs;

    OCI_Initialize(NULL, NULL, OCI_ENV_DEFAULT | OCI_ENV_CONTEXT);

    cn = OCI_ConnectionCreate(...)
    st = OCI_StatementCreate(cn);
    OCI_SetFetchMode(st, OCI_SFM_SCROLLABLE);

    OCI_ExecuteStmt(st, "SELECT COLUMN_NAME,DATA_DEFAULT  FROM ALL_TAB_COLUMNS WHERE OWNER='B2BTRUST' and TABLE_NAME='ADNOVE_CAMPAGNES' ORDER BY COLUMN_ID");

    rs = OCI_GetResultset(st);
    OCI_FetchNext(rs);
    fprintf(stderr, "1 row=%d\n", OCI_GetRowCount(rs));
    OCI_FetchLast(rs);
    fprintf(stderr, "2 row=%d\n", OCI_GetRowCount(rs));
    OCI_FetchFirst(rs);


    do {
        printf("v1 %s\n", OCI_GetString(rs,1));
    } while (OCI_FetchNext(rs));

    OCI_Cleanup();

    return EXIT_SUCCESS;
}

Set Fetch\Prefetch not working with Execute

Hi I noticed that when I do this:

  Statement st(cn);
  st.SetFetchSize(2);
  st.SetPrefetchSize(5);
  st.Execute("SELECT * from mytable");

getters returns values I set, however rows fetched using default values(20, 20) I used wireshark to confirm that.

But when I do this:

  Statement st(cn);
  st.Prepare("SELECT * from mytable");
  st.SetFetchSize(2);
  st.SetPrefetchSize(5);
  st.ExecutePrepared();

it fetch rows as expected. It think this should be fixed, or at least doc for setters should notice they should be called after prepare and getters should return actual values used.

Can I set a NULL value to a bind variable using C++ interface?

I have not found any way to tell the Oracle database that I want to insert a record consists of some values and some NULL values using C++ interface.

Shouldn't there we a function in Statement that sets a column to NULL ?
i,e, BindToNull(ostring name);

Memory leak in Collection binds

I've found an huge memory leak using collections in prepared statement with the C++ API (version 4.2.0, platform linux 64bit, compiler gcc 4.8.3).

Here is a simple program that cause the problem.

#include <iostream>
#include "ocilib.hpp"

using namespace ocilib;

int main(int argc, char *argv[])
{
    Environment::Initialize(ocilib::Environment::Default | ocilib::Environment::Threaded);
    Environment::EnableWarnings(true);
    int iterations = 2000;

    if  (argc > 1 && atoi(argv[1]) > 0)
        iterations = atoi(argv[1]);

    try {
        Pool pool;
        pool.Open("dbname", "dbuser", "dbpwd", Pool::SessionPool, 5, 20); 
        Connection con = pool.GetConnection();
        Statement st(con);  
        TypeInfo ti(con, "myarray", TypeInfo::Type);

        for (int i = 1; i < iterations; ++i) {
            Collection<ostring> lvc(ti);

            lvc.Append("T0100101");
/*
            This block is commented since it's not needed to cause the leak

            lvc.Append("T0100102");

            st.Prepare("SELECT lane FROM vehicle_t WHERE lane MEMBER OF :v");
            st.Bind(":v", lvc,  BindInfo::In);
            st.ExecutePrepared();

            Resultset rs = st.GetResultset();

            while (rs.Next()) 
                if (!rs.IsColumnNull(1)) 
                    std::cerr << '.';
*/
        }
    }
    catch (Exception &e) { 
        std::cerr << "OCILib exception: " << e.what() << "\n";
    } catch (...) {
        std::cerr << "Unknown exception!\n";
    }
    Environment::Cleanup();
}

PS: Updated with the changes in the comments

OCI_GetStruct calculates incorrect offset when a properly aligned Double is followed by an Int

The existing OCI_GetStruct alignment calculation needs to be updated.

Summary:

For the table:
create table test_fetch_struct2(val_char_1 varchar2(30),val_char_2 varchar2(30),val_double number,val_long number(10),val_char_3 varchar2(30));

Expected C structure:
struct product_t
{
char *val_char_1; // offset 0
char *val_char_2; // offset 4
double val_double; // offset 8 :: column is natually aligned - no adjustment needed
int val_long; // offset 16
char *val_char_3; // offset 20
char *extra; // offset 24 :: don't abend on buffer overflow
} prd;

Actual C structure needed for OCI_GetStruct:
struct product2_t
{
char *val_char_1; // offset 0
char *val_char_2; // offset 4
char *bad_align; // offset 8 :: structure alignment calculation is skipping 4 extra bytes
float val_double; // offset 12 :: cheat to get the alignment being calculated
float val_double2; // offset 16
int val_long; // offset 20
char *val_char_3; // offset 24
char *extra; // offset 28 :: don't abend on buffer overflow
} prd2;


Details:

New OCI_GetStruct function:

/* --------------------------------------------------------------------------------------------- *

  • OCI_GetStruct
  • --------------------------------------------------------------------------------------------- */

boolean OCI_API OCI_GetStructNew
(
OCI_Resultset *rs,
void *row_struct,
void *row_struct_ind
)
{
char *ptr = NULL;
boolean *inds = NULL;

size_t alignOffset;

// size_t alignForMax = 0;

OCI_LIB_CALL_ENTER(boolean, FALSE)

OCI_CHECK_PTR(OCI_IPC_RESULTSET, rs)
OCI_CHECK_PTR(OCI_IPC_VOID, row_struct)

call_status = TRUE;

ptr  = (char    *) row_struct;
inds = (boolean *) row_struct_ind;

// ptr should start at a proper double (8 byte) alignment
if (ptr)
{
size_t structSize = 0;
size_t size1 = 0;
size_t align1 = 0;
ub4 i;

    for (i = 1; i <= rs->nb_defs; i++)
    {
        OCI_Column *col1 = &rs->defs[i-1].col;

        boolean is_not_null = OCI_DefineIsDataNotNull(&rs->defs[i-1]);

        OCI_ColumnGetAttrInfo(col1, rs->nb_defs, i-1, &size1, &align1);

    // ensure the pointer is properly aligned for this column
        if (align1) // avoid divide by zero
        {

// if (alignForMax < align1)
// {
// alignForMax = align1; // remember the largest alignment for this structure
// }

            alignOffset = structSize % align1;  // how far off is the alignment?
            if (alignOffset)
            {
            // adjust the pointer for this field
                size_t alignDelta = (align1 - alignOffset);

                ptr        += alignDelta;
                structSize += alignDelta;
            }
        }

        memset(ptr, 0, size1);

        if (is_not_null)
        {
            switch (col1->datatype)
            {
                case OCI_CDT_NUMERIC:
                {
                    OCI_DefineGetNumber(rs, i, ptr, col1->subtype, (uword) size1);

                    break;
                }
                case OCI_CDT_TEXT:
                {
                    *((otext **) ptr) =  (otext * ) OCI_GetString(rs, i);
                    break;
                }
                case OCI_CDT_RAW:
                {
                    *((void **) ptr) = OCI_DefineGetData(&rs->defs[i]);
                    break;
                }
                case OCI_CDT_LONG:
                {
                    *((OCI_Long **) ptr) = OCI_GetLong(rs, i);
                    break;
                }
                case OCI_CDT_DATETIME:
                {
                    *((OCI_Date **) ptr) = OCI_GetDate(rs, i);
                    break;
                }
                case OCI_CDT_CURSOR:
                {
                    *((OCI_Statement **) ptr) = OCI_GetStatement(rs, i);
                    break;
                }
                case OCI_CDT_LOB:
                {
                    *((OCI_Lob **) ptr) = OCI_GetLob(rs, i);
                    break;
                }
                case OCI_CDT_FILE:
                {
                    *((OCI_File **) ptr) = OCI_GetFile(rs, i);
                    break;
                }
                case OCI_CDT_TIMESTAMP:
                {
                    *((OCI_Timestamp **) ptr) = OCI_GetTimestamp(rs, i);

                    break;
                }
                case OCI_CDT_INTERVAL:
                {
                    *((OCI_Interval **) ptr) = OCI_GetInterval(rs, i);
                    break;
                }
                case OCI_CDT_OBJECT:
                {
                    *((OCI_Object **) ptr) = OCI_GetObject(rs, i);
                    break;
                }
                case OCI_CDT_COLLECTION:
                {
                    *((OCI_Coll **) ptr) = OCI_GetColl(rs, i);
                    break;
                }
                case OCI_CDT_REF:
                {
                    *((OCI_Ref **) ptr) = OCI_GetRef(rs, i);
                    break;
                }
            }
        }

        structSize += size1;
        ptr        += size1;

        if (inds)
        {
            *inds = is_not_null;

            inds++;
        }
    }

// ensure the structure is properly aligned for array processing

// if (alignForMax)
// {
// alignOffset = ptr % alignForMax; // how far off is the alignment?
// if (alignOffset)
// {
// ptr += (alignForMax - alignOffset); // adjust the pointer for this field
// }
// }
}

call_retval = call_status = TRUE;

OCI_LIB_CALL_EXIT()

}


Test Code:
/*-----------

  • test_setup
    -----------/
    int test_setup (OCI_Connection *ociConn, OCI_Statement *ociStmt, OCI_Resultset *ociRset)
    {
    int retval = 0;
    otext *sqlString;

    prnlog("\n- test setup...\n");

    sqlString = OTEXT("create table test_fetch_struct2")
    OTEXT("(val_char_1 varchar2(30)")
    OTEXT(",val_char_2 varchar2(30)")
    OTEXT(",val_double number")
    OTEXT(",val_long number(10)")
    OTEXT(",val_char_3 varchar2(30)")
    OTEXT(")")
    ;
    prnlog("\nExecute: %s\n", sqlString);
    OCI_ExecuteStmt(ociStmt, sqlString);

    sqlString = OTEXT("insert into test_fetch_struct2 (val_char_1, val_char_2, val_double, val_long, val_char_3) ")
    OTEXT("values ('col1 row1', 'col2 row1', 123.45, 1, 'col5 row1')")
    ;
    prnlog("\nExecute: %s\n", sqlString);
    OCI_ExecuteStmt(ociStmt, sqlString);

    sqlString = OTEXT("insert into test_fetch_struct2 (val_char_1, val_char_2, val_double, val_long, val_char_3) ")
    OTEXT("values ('col1 row1', 'col2 row2', 234.56, 2, 'col5 row2')")
    ;
    prnlog("\nExecute: %s\n", sqlString);
    OCI_ExecuteStmt(ociStmt, sqlString);

    sqlString = OTEXT("insert into test_fetch_struct2 (val_char_1, val_char_2, val_double, val_long, val_char_3) ")
    OTEXT("values ('col1 row1', 'col2 row3', 345.67, 3, 'col5 row3')")
    ;
    prnlog("\nExecute: %s\n", sqlString);
    OCI_ExecuteStmt(ociStmt, sqlString);

    OCI_Commit(ociConn);

    OCI_ReleaseResultsets(ociStmt);

    return(retval);
    }

/*-------------

  • test cleanup
    -------------/
    int test_cleanup (OCI_Connection *ociConn, OCI_Statement *ociStmt, OCI_Resultset *ociRset)
    {
    int retval = 0;

    prnlog("\n- test cleanup...\n");

    oci_nofail = 1; /* ignore errors */

    OCI_ExecuteStmt(ociStmt, OTEXT("drop table test_fetch_struct2"));

    OCI_ReleaseResultsets(ociStmt);
    oci_nofail = 0;

    return(retval);
    }

/*------------------

  • test OCI_GetStruct :: verify structure alignment calculation error when a properly aligned double is followed by an int
    ------------------/
    int test_fetch_struct_bad (OCI_Connection *ociConn, OCI_Statement *ociStmt, OCI_Resultset *ociRset)
    {
    int retval = 0;
    int iCnt;

// define the structure expected for the retrieval
struct product_t
{
char *val_char_1; // offset 0
char *val_char_2; // offset 4
double val_double; // offset 8 :: column is natually aligned - no adjustment needed
int val_long; // offset 16
char *val_char_3; // offset 20
char *extra; // offset 24 :: don't abend on buffer overflow
} prd;

// define the structure as mapped by the OCI_GetStruct function
struct product2_t
{
char *val_char_1; // offset 0
char *val_char_2; // offset 4
char *bad_align; // offset 8 :: structure alignment calculation is skipping 4 extra bytes
float val_double; // offset 12 :: cheat to get the alignment being calculated
float val_double2; // offset 16
int val_long; // offset 20
char *val_char_3; // offset 24
char *extra; // offset 28 :: don't abend on buffer overflow
} prd2;

struct prodind_t
    {
    boolean   val_char_1;
    boolean   val_char_2;
    boolean   val_double;
    boolean   val_long;
    boolean   val_char_3;
    } ind;

prnlog("\n- Test fetch struct bad: prd...\n"
         "  This shows the val_long, and val_char_3, values shifted to the next column\n");

OCI_ExecuteStmtFmt(ociStmt, OTEXT("select val_char_1, val_char_2, val_double, val_long, val_char_3 from test_fetch_struct2"));

ociRset = OCI_GetResultset(ociStmt);

OCI_SetStructNumericType(ociRset, 3, OCI_NUM_DOUBLE);
OCI_SetStructNumericType(ociRset, 4, OCI_NUM_INT);

iCnt = 0;
while (OCI_FetchNext(ociRset))
{
    prd.extra = 0;

    OCI_GetStruct(ociRset, &prd, &ind);
    iCnt++;

    prnlog("\nrow %d\n", iCnt);
    prnlog("  > val_char_1 : %08X: %s\n", prd.val_char_1, prd.val_char_1);
    prnlog("  > val_char_2 : %08X: %s\n", prd.val_char_2, prd.val_char_2);
    prnlog("  > val_double : %Lf\n",      prd.val_double);
    prnlog("  > val_long : %d\n",         prd.val_long);
    prnlog("  > val_char_3 : %08X\n",     prd.val_char_3);
    prnlog("  > extra      : %08X: %s\n", prd.extra, prd.extra);
    prnlog("\n");
}
prnlog("  + %d row(s) fetched\n", OCI_GetRowCount(ociRset));

OCI_ReleaseResultsets(ociStmt);

// //////////////////////////

prnlog("\n- test fetch struct bad: prd2...\n"
         "  This shows the structure as mapped by the OCI_GetStruct logic\n");

OCI_ExecuteStmtFmt(ociStmt, OTEXT("select val_char_1, val_char_2, val_double, val_long, val_char_3 from test_fetch_struct2"));

ociRset = OCI_GetResultset(ociStmt);

OCI_SetStructNumericType(ociRset, 3, OCI_NUM_DOUBLE);
OCI_SetStructNumericType(ociRset, 4, OCI_NUM_INT);

iCnt = 0;
while (OCI_FetchNext(ociRset))
{
    prd2.extra = 0;

    OCI_GetStruct(ociRset, &prd2, &ind);
    iCnt++;

    prnlog("\nrow %d\n", iCnt);
    prnlog("  > val_char_1 : %08X: %s\n", prd2.val_char_1, prd2.val_char_1);
    prnlog("  > val_char_2 : %08X: %s\n", prd2.val_char_2, prd2.val_char_2);
    prnlog("  > val_double : %Lf\n",      *(double *)&(prd2.val_double));
    prnlog("  > val_long : %d\n",         prd2.val_long);
    prnlog("  > val_char_3 : %08X: %s\n", prd2.val_char_3, prd2.val_char_3);
    prnlog("  > extra      : %08X:\n",    prd2.extra);
    prnlog("\n");
}
prnlog("  + %d row(s) fetched\n", OCI_GetRowCount(ociRset));

OCI_ReleaseResultsets(ociStmt);

retval = oci_rc;

return(retval);

}
/*------------------

  • test_fetch_struct
    ------------------/
    int test_fetch_struct_new (OCI_Connection *ociConn, OCI_Statement *ociStmt, OCI_Resultset *ociRset)
    {
    int retval = 0;
    int iCnt;

    struct product_t
    {
    char *val_char_1; // offset 0
    char *val_char_2; // offset 4
    double val_double; // offset 8
    int val_long; // offset 16
    char *val_char_3; // offset 20
    char *extra; // don't abend on overflow
    } prd;

    struct prodind_t
    {
    boolean val_char_1;
    boolean val_char_2;
    boolean val_double;
    boolean val_long;
    boolean val_char_3;
    } ind;

    prnlog("\n- test fetch struct new: prd...\n"
    " This shows the structure properly mapped by the updated logic\n");

    OCI_ExecuteStmtFmt(ociStmt, OTEXT("select val_char_1, val_char_2, val_double, val_long, val_char_3 from test_fetch_struct2"));

    ociRset = OCI_GetResultset(ociStmt);

    OCI_SetStructNumericType(ociRset, 3, OCI_NUM_DOUBLE);
    OCI_SetStructNumericType(ociRset, 4, OCI_NUM_INT);

    iCnt = 0;
    while (OCI_FetchNext(ociRset))
    {
    prd.extra = 0;

    OCI_GetStructNew(ociRset, &prd, &ind);
    iCnt++;
    
    prnlog("\nrow %d\n", iCnt);
    prnlog("  > val_char_1 : %08X: %s\n", prd.val_char_1, prd.val_char_1);
    prnlog("  > val_char_2 : %08X: %s\n", prd.val_char_2, prd.val_char_2);
    prnlog("  > val_double : %Lf\n",      prd.val_double);
    prnlog("  > val_long : %d\n",         prd.val_long);
    prnlog("  > val_char_3 : %08X : %s\n",prd.val_char_3, prd.val_char_3);
    prnlog("  > extra      : %08X\n",     prd.extra);
    
    prnlog("\n");
    

    }
    prnlog(" + %d row(s) fetched\n", OCI_GetRowCount(ociRset));

    OCI_ReleaseResultsets(ociStmt);

    retval = oci_rc;

    return(retval);
    }


Test output:

OCI Test

  • Arguments:
    Oracle User : xxxxxxxx
    Oracle DBName : myOraDB
    Connect Role :
  • Verify Settings
  • OCI Initialize
  • Processing OCI request...
  • Begin OCIThread-00B81C78
  • test cleanup...
    INFO-ORA-00942: table or view does not exist
  • test setup...

Execute: create table test_fetch_struct2(val_char_1 varchar2(30),val_char_2 varchar2(30),val_double number,val_long number(10),val_char_3 varchar2(30))

Execute: insert into test_fetch_struct2 (val_char_1, val_char_2, val_double, val_long, val_char_3) values ('col1 row1', 'col2 row1', 123.45, 1, 'col5 row1')

Execute: insert into test_fetch_struct2 (val_char_1, val_char_2, val_double, val_long, val_char_3) values ('col1 row1', 'col2 row2', 234.56, 2, 'col5 row2')

Execute: insert into test_fetch_struct2 (val_char_1, val_char_2, val_double, val_long, val_char_3) values ('col1 row1', 'col2 row3', 345.67, 3, 'col5 row3')

  • Test fetch struct bad: prd...
    This shows the val_long, and val_char_3, values shifted to the next column

row 1

val_char_1 : 007FB3C0: col1 row1
val_char_2 : 007FCC50: col2 row1
val_double : -92559641157289301000000000000000000000000000000000000000000000.000000
val_long : 1079958732
val_char_3 : 00000001
extra : 00A31FE8: col5 row1

row 2

val_char_1 : 007FB439: col1 row1
val_char_2 : 007FCCC9: col2 row2
val_double : -0.000000
val_long : 1080906219
val_char_3 : 00000002
extra : 00A32061: col5 row2

row 3

val_char_1 : 007FB4B2: col1 row1
val_char_2 : 007FCD42: col2 row3
val_double : 427698049712232160000000000000000000000000000000000000000000000000000000000000000000000.000000
val_long : 1081449144
val_char_3 : 00000003
extra : 00A320DA: col5 row3

  • 3 row(s) fetched
  • test fetch struct bad: prd2...
    This shows the structure as mapped by the OCI_GetStruct logic

row 1

val_char_1 : 00A32348: col1 row1
val_char_2 : 007FB088: col2 row1
val_double : 123.450000
val_long : 1
val_char_3 : 007FD0E8: col5 row1
extra : 00000000:

row 2

val_char_1 : 00A323C1: col1 row1
val_char_2 : 007FB101: col2 row2
val_double : 234.560000
val_long : 2
val_char_3 : 007FD161: col5 row2
extra : 00000000:

row 3

val_char_1 : 00A3243A: col1 row1
val_char_2 : 007FB17A: col2 row3
val_double : 345.670000
val_long : 3
val_char_3 : 007FD1DA: col5 row3
extra : 00000000:

  • 3 row(s) fetched
  • test fetch struct new: prd...
    This shows the structure properly mapped by the updated logic

row 1

val_char_1 : 00A32348: col1 row1
val_char_2 : 007FB088: col2 row1
val_double : 123.450000
val_long : 1
val_char_3 : 007FD0E8 : col5 row1
extra : 00000000

row 2

val_char_1 : 00A323C1: col1 row1
val_char_2 : 007FB101: col2 row2
val_double : 234.560000
val_long : 2
val_char_3 : 007FD161 : col5 row2
extra : 00000000

row 3

val_char_1 : 00A3243A: col1 row1
val_char_2 : 007FB17A: col2 row3
val_double : 345.670000
val_long : 3
val_char_3 : 007FD1DA : col5 row3
extra : 00000000

  • 3 row(s) fetched
  • test cleanup...
  • OCI Disconnect: xxxxxxxx/***@myOraDB
  • End OCIThread-00B81C78
  • OCI Cleanup

OCILib Errors = 0
Oracle Errors = 0
Oracle Warnings= 0

Process getting hanged while using OCI_POOL_SESSION

gdbfull.txt
Hi

We are using ocilib 3.x version and using ocilib connection pool with following parameter with 20 thread. We are getting issue of process hanged while using OCI_POOL_SESSION.Same is working fine with OCI_POOL_CONNECTION

connPool = OCI_PoolCreate(SID,xxx,xxx, OCI_POOL_SESSION, OCI_SESSION_DEFAULT,5, 25, 1)

In worker thread following are pseudo code.

OCI_Connection *curConn = OCI_PoolGetConnection(connPool, NULL);
stmt = OCI_StatementCreate(curConn);
OCI_Prepare(stmt, dbQuery);
OCI_Execute(stmt)
OCI_StatementFree(stmt);
OCI_ConnectionFree(curConn);

After some time of running process getting hanged because of lock.Below are gdb trace of one of thread.

Thread 6 (Thread 0x7f44e6bfd700 (LWP 51769)):
#0 0x0000003da0a0e2e4 in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x0000003da0a09588 in _L_lock_854 () from /lib64/libpthread.so.0
#2 0x0000003da0a09457 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3 0x00007f450f76e2ef in sltsmna () from /home/oracle/app/oracle/product/11.2.0/client_1/lib/libclntsh.so.11.1
#4 0x00007f450e8c4854 in kpltMutexAcquire () from /home/oracle/app/oracle/product/11.2.0/client_1/lib/libclntsh.so.11.1
#5 0x00007f450e7affc9 in OCIThreadMutexAcquire () from /home/oracle/app/oracle/product/11.2.0/client_1/lib/libclntsh.so.11.1
#6 0x00007f4510017e69 in OCI_MutexAcquire (mutex=0x21ae0b0) at mutex.c:165
#7 0x00007f451001e809 in OCI_PoolGetConnection (pool=0x21acb30, tag=0x0) at pool.c:476

---Type to continue, or q to quit---
#8 0x000000000040390f in UpdateStatus (ptrUPIResp=0x7f44e6bfc5d0, connPool=0x21acb30) at ./src/RecvCreditReq.c:422
#9 0x00000000004037d0 in recvUPIResp (thread=0x22a4b30, data=0x21acb30) at ./src/RecvCreditReq.c:383
#10 0x0000003da0a07a51 in start_thread () from /lib64/libpthread.so.0
#11 0x0000003da06e896d in clone () from /lib64/libc.so.6

Please let us know what we are doing wrong.

Invalid copy of vector data block

The copy of data are using invalid length

(value.size() + 1) * sizeof(otext)

The vector is ending at value.size(), not value.size()+1, ocilib_impl.hpp:4179

Why is the length multiplied with sizeof(otext) ?
The definition of Raw is

typedef std::vector<unsigned char> Raw;

and otext is either

  typedef char              otext;

or

  typedef wchar_t           otext;

which leads to invalid length when compiling with OCI_CHAR_WIDE (2 times bigger size than allowed + 2 extra bytes).

The line 4179 must be

           memcpy(_data + (_elemSize * index), &value[0], value.size() );
template<>
inline void BindArray::BindArrayObject<Raw, unsigned char>::SetInData()
{
    if (_mode & OCI_BDM_IN)
    {
        std::vector<Raw>::iterator it, it_end;

        unsigned int index = 0;
        unsigned int currElemCount = Check(OCI_BindArrayGetSize(_pStatement));

        for (it = _vector.begin(), it_end = _vector.end(); it != it_end && index < _elemCount && index < currElemCount; ++it, ++index)
        {
            Raw & value = *it;

            if (value.size() > 0)
            {
===>             memcpy(_data + (_elemSize * index), &value[0], (value.size() + 1) * sizeof(otext));
            }
        }
    }
}

VS2010

With last version, if I open
\ocilib\ocilib-master\proj\dll\ocilib_dll_vs2010.sln
with vs2010 and compile, I take some errors.

Can you confirm that this compiler is supported? The version 4.0.0 works correctly.

Error example:
1>....\src\object.c(1184): error C2143: errore di sintassi: ';' mancante prima di 'tipo'
1>....\src\object.c(1184): error C2065: 'index': identificatore non dichiarato
1>....\src\object.c(1184): error C2065: 'index': identificatore non dichiarato
1>....\src\object.c(1184): error C2065: 'index': identificatore non dichiarato
1>....\src\object.c(1191): error C2143: errore di sintassi: '{' mancante prima di '*'
...

My compiler is Italian localized.

Unitialized variables causes unknown behavior

Trying to insert an array of Blob fails due to error in BindCheck (using C++ interface)

==30717== Conditional jump or move depends on uninitialised value(s)
==30717==    at 0x548B2E6: OCI_BindCheck (statement.c:297)
==30717==    by 0x548B758: OCI_ExecuteInternal (statement.c:1810)
==30717==    by 0x548B939: OCI_Execute (statement.c:2063)

The data used in OCI_BindCheck has unknown data which is allocated in:

template <class TObjectType, class TDataType>
inline void BindArray::BindArrayObject<TObjectType, TDataType>::AllocData()
{
    _data = new TDataType[_elemCount];
}

By adding memset, the problems with i.e. set an array of Blob disappears:

template <class TObjectType, class TDataType>
inline void BindArray::BindArrayObject<TObjectType, TDataType>::AllocData()
{
    _data = new TDataType[_elemCount];
    memset(_data, 0, sizeof(TDataType) * _elemCount);
}

Compile time appear multiple definition of `Number& Number::operator -- () '

in ocilib_impl.hpp

Number& Number::operator ++ ()
{
return *this += 1;
}

Number& Number::operator -- ()
{
return *this += 1;
}

Number Number::operator ++ (int)
{
return *this + 1;
}

Number Number::operator -- (int)
{
return *this - 1;
}

Modified to

inline Number& Number::operator ++ ()
{
return *this += 1;
}

**inline**Number& Number::operator -- ()
{
return *this += 1;
}

**inline**Number Number::operator ++ (int)
{
return *this + 1;
}

**inline**Number Number::operator -- (int)
{
return *this - 1;
}

Support of Oracle native NUMBER, to enable generic lossless data copying.

At the moment it's possible to access numeric data as native C datatypes only, as int, long, float, double and so on. But for generic task of data copying between databases, when number precision can vary, that way is not applicable due lossy nature of such conversion, especially for non-integer values.

Also Oracle allows to store special number values, like positive and negative invinity, which can't be handled using existing ocilib API:

SELECT 
  a.*,
  to_char("Positive Infinity"),
  to_char("Negative Infinity"),
  DUMP("Positive Infinity", 16),
  DUMP("Negative Infinity", 16)
FROM (SELECT 
  utl_raw.cast_to_number('FF65')  "Positive Infinity", 
  utl_raw.cast_to_number('00')    "Negative Infinity"  FROM dual
) a

So we need to implement support of Oracle native NUMBER datatype OCI_Number, OCI_GetNumber, OCI_BindNumber

Also the datatype need to be explicitly handled in Direct Path Insert API, not as the string to number conversion.

Memory leak in C++ Resultsets?

Hi vrogier,

I've been diagnosing a memory leak in an application I'm writing that uses C++ OCILIB. This is my minimal diagnostic program:

#ifdef OCI_CHARSET_ANSI
#undef OCI_CHARSET_ANSI
#endif
#ifndef OCI_CHARSET_WIDE
#define OCI_CHARSET_WIDE
#endif

#include <ocilib\ocilib.hpp>

#ifdef _MSC_VER

#if defined(OCI_CHARSET_WIDE)
#pragma comment(lib, "ocilibw.lib")
#elif defined(OCI_CHARSET_ANSI)
#pragma comment(lib, "ociliba.lib")
#endif

#endif

#ifndef OCI_SHARED_LIB
#if defined(_WINDOWS)
#if defined(OCI_CHARSET_WIDE)
#define OCI_SHARED_LIB                   "ocilibw.dll"
#else
#define OCI_SHARED_LIB                   "ociliba.dll"
#endif
#else
#define OCI_SHARED_LIB                   "libocilib.so"
#endif
#endif

using namespace ocilib;

void testDataRetrievalMemoryLeak()
{
    Environment::Initialize();
    Connection dbConnection1;
    dbConnection1.Open(service, usr, pwd);
    Statement st(dbConnection1);
    for (int i = 0; i < 10000; i++) {
        wstring sel = L"select 'test' from dual";
        st.Execute(sel);
        Resultset rs = st.GetResultset();
    }
    dbConnection1.Close();
    Environment::Cleanup();
}

int main(int argc, char *argv[])
{
    testDataRetrievalMemoryLeak();
    return 0;
}

I have found that without the line Resultset rs = st.GetResultset();, the test application's memory usage is flat. With it, it grows without bound.

I diagnosed with the Performance Monitor on a Windows Server 2012 machine to get a broad idea of memory growth.

From my own investigations, I noted that the C function OCI_ReleaseResultsets is never called from C++, which means neither is OCI_ResultsetFree, since Resultsets in C++ are created without a HandleFreeFunc function.

Any insight on this, or am I using OCILIB incorrectly?

SIGSEGV in oci_getraw for varbinary (variable binary[raw]) - timesten

hello
i received signal SIGSEGV when call fetch next on result of select query with varbinary column in timesten (direct|client) connection.
i was write a sample query in OCI (not ocilib) for "select * from my_table" and get my data in var binary format.

can fix this bug!

stack trace:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff33a14c5 in __intel_new_memset ()
from /opt/oracle/product/12.1.0/dbhome_1/lib/libclntsh.so.12.1
(gdb) bt
#0 0x00007ffff33a14c5 in __intel_new_memset ()

from /opt/oracle/product/12.1.0/dbhome_1/lib/libclntsh.so.12.1
#1 0x00007ffff339eed6 in _intel_fast_memset.J ()

from /opt/oracle/product/12.1.0/dbhome_1/lib/libclntsh.so.12.1
#2 0x00007ffff36ae690 in x10dfnInit2Stmt ()

from /opt/oracle/product/12.1.0/dbhome_1/lib/libclntsh.so.12.1
#3 0x00007ffff36a63b8 in x10allBundledStmt ()

from /opt/oracle/product/12.1.0/dbhome_1/lib/libclntsh.so.12.1
#4 0x00007ffff36a6801 in x10allBundled ()

from /opt/oracle/product/12.1.0/dbhome_1/lib/libclntsh.so.12.1
#5 0x00007ffff369913d in x10odr ()

from /opt/oracle/product/12.1.0/dbhome_1/lib/libclntsh.so.12.1
#6 0x00007ffff4563b3a in upirtrc ()

from /opt/oracle/product/12.1.0/dbhome_1/lib/libclntsh.so.12.1
#7 0x00007ffff456df46 in kpurcsc ()

from /opt/oracle/product/12.1.0/dbhome_1/lib/libclntsh.so.12.1
#8 0x00007ffff456b5a5 in kpufch0 ()

from /opt/oracle/product/12.1.0/dbhome_1/lib/libclntsh.so.12.1
#9 0x00007ffff4569c05 in kpufch ()

from /opt/oracle/product/12.1.0/dbhome_1/lib/libclntsh.so.12.1
#10 0x00007ffff278119b in OCIStmtFetch2 ()

from /opt/oracle/product/12.1.0/dbhome_1/lib/libclntsh.so.12.1
#11 0x00007ffff7b98f23 in OCI_FetchData (rs=rs@entry=0x857608, mode=mode@entry=2,

offset=offset@entry=0, success=success@entry=0x7fffffffdb8c) at resultset.c:520

#12 0x00007ffff7b99cca in OCI_FetchNext (rs=0x857608) at resultset.c:1100

Binding vector of RAW causes core dump

Program received signal SIGSEGV, Segmentation fault.

0x00007ffff7ddb559 in OCI_BindCheck () from /vobs/thirdparty/ocilib/installed/linux/lib/libocilib.so
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.132.el6.x86_64 libaio-0.3.107-10.el6.x86_64 libgcc-4.4.7-4.el6.x86_64
(gdb) where
#0  0x00007ffff7ddb559 in OCI_BindCheck () from /vobs/thirdparty/ocilib/installed/linux/lib/libocilib.so
#1  0x00007ffff7dde544 in OCI_ExecuteInternal () from /vobs/thirdparty/ocilib/installed/linux/lib/libocilib.so
#2  0x00007ffff7ddec58 in OCI_Execute () from /vobs/thirdparty/ocilib/installed/linux/lib/libocilib.so
#3  0x00000000004087d2 in ocilib::Statement::ExecutePrepared() () at /vobs/thirdparty/ocilib/installed/include/ocilib_impl.hpp:4518
#4  0x00000000004057a2 in main () at BigRaw.cpp:113
(gdb) info locals 
No symbol table info available.
(gdb) up
#1  0x00007ffff7dde544 in OCI_ExecuteInternal () from /vobs/thirdparty/ocilib/installed/linux/lib/libocilib.so
(gdb) info locals 
No symbol table info available.
(gdb) up
#2  0x00007ffff7ddec58 in OCI_Execute () from /vobs/thirdparty/ocilib/installed/linux/lib/libocilib.so
(gdb) info locals 
No symbol table info available.
(gdb) up
#3  0x00000000004087d2 in ocilib::Statement::ExecutePrepared() () at /vobs/thirdparty/ocilib/installed/include/ocilib_impl.hpp:4518
4518        Check(OCI_Execute(*this));
(gdb) info locals 
length_multiplier = 50
std::__ioinit = {static _S_refcount = 2, static _S_synced_with_stdio = true}

Test program

#include <iostream>
#include <iomanip>
#include <string>
#include <time.h>
#include <sstream>
#include <vector>

#include "ocilib.hpp"

using namespace ocilib;
using namespace std;

const int length_multiplier = 50; // 2

ostring v2s(const Raw & r)
{
   ostringstream ss;
   ss << "vector length=" << r.size() << endl;
   ss << setfill('0') << hex;
   int pos=0;
   for (auto v : r)
   {
      ss << setw(2) << (int)v;
      if (((++pos) % 16) == 15)
      {
     if ((pos % 64) == 63)
        ss << endl;
     else
        ss << ' ';
      }
   }
   ss << endl;
   return ss.str();
}

void setstmt(Statement & stmt, const ostring & line)
{
   stmt.Prepare(line);
}

ostring getCrateStmt()
{
   return "CREATE TABLE TEST_BIG (n NUMBER, v RAW(2000) )";
}

ostring getDropStmt()
{
   return "DROP TABLE TEST_BIG";
}

ostring getstmt()
{
   return "INSERT INTO TEST_BIG ( n, v) values ( :1, :2)";
}

unsigned char avalue(int x)
{
   return static_cast<unsigned char>((x + 132) % 256);
}

int main(int argc, char**argv)
{
   if (argc < 4)
   {
      cout << "user pwd dbcon" << endl;
      return 1;
   }
   try
   {
      Environment::Initialize();

      Connection con(argv[3], argv[1], argv[2]);
      try {
     Statement sc(con);
     sc.Prepare(getDropStmt());
     sc.ExecutePrepared();
      }
      catch (Exception & ex)
      {
     cout << "Ignored: " << ex.what() << endl;
      }
      {
     Statement sc(con);
     sc.Prepare(getCrateStmt());
     sc.ExecutePrepared();
      }

      {
     Statement st(con);
     st.Prepare(getstmt());
     vector<Raw> rvalues;
     vector<int> nvalues;
     for (int i=1; i<=10; i++)
     {
        nvalues.push_back(i);
        Raw v;
        int length=250+i*length_multiplier;
        cout << setw(2) << i << " length=" << length << endl;
        v.resize(length);
        for (int pos=0; pos<length; ++pos)
           v[pos] = avalue(pos);
        cout << "Store RAW:" << v2s(v) << endl;
        rvalues.push_back(v);
     }
     st.SetBindArraySize(static_cast<unsigned int>(rvalues.size()));
     cout << "Try to bind " << rvalues.size() << " values..." << endl;
     st.Bind(":1", nvalues, BindInfo::InOut);
     unsigned int maxsize=2000U;
     st.Bind<ocilib::Raw, unsigned int>(":2",
                        rvalues,
                        maxsize,
                        ocilib::BindInfo::InOut);
     st.ExecutePrepared();

     cout << "inserted 10 rows, affected rows= " << st.GetAffectedRows() << endl;

     con.Commit();
      }
      {
     Statement stmt(con);
     stmt.Execute("SELECT n, v from TEST_BIG");
     Resultset rs = stmt.GetResultset();
     while (rs++)
     {
        int n = rs.Get<int>(1);
        Raw v = rs.Get<Raw>(2);
        cout << setw(2) << n << " value length=" << v.size() << "   ";
        bool ok=true;
        int fail_pos=0;
        int length=250+n*length_multiplier;
        for (int pos=0; pos<length; ++pos)
        {
           if (v[pos] != avalue(pos))
           {
          ok = false;
          fail_pos=pos;
          break;
           }
        }
        if (ok)
        {
           cout << "ok" << endl;
        } else {
           cout << "failed at pos " << fail_pos
             << " expected " << hex << (int)static_cast<unsigned char>((fail_pos % 256) ^ 0xAA)
             << " got " << (int)v[fail_pos] << dec
             << v2s(v)
             << endl;
        }
     }
      }
   }
   catch (Exception & ex)
   {
      cerr << "OciLib::Exception" << endl;
      cerr << "Message     : " << ex.GetMessage() << endl;
      cerr << "Oracle error: " << ex.GetOracleErrorCode() << endl;
      cerr << "what        : " << ex.what() << endl;
      cerr << "Internal err: " << ex.GetInternalErrorCode() << endl;
   }
   catch (exception &ex)
   {
      cerr << "EXCEPTION:" << endl;
      cerr << ex.what() << endl;
   }

   Environment::Cleanup();

   return EXIT_SUCCESS;
}

Valgrind adds more information (line numbers differs from the the original source after adding some diagnostic lines)

==4880== Invalid write of size 1
==4880==    at 0x4A08CE8: memcpy (mc_replace_strmem.c:882)
==4880==    by 0x408054: ocilib::BindArray::BindArrayObject<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>::SetInData() (ocilib_impl.hpp:4180)
==4880==    by 0x407F3A: ocilib::BindArray::SetInData() (ocilib_impl.hpp:4085)
==4880==    by 0x408597: ocilib::BindsHolder::SetInData() (ocilib_impl.hpp:4395)
==4880==    by 0x408B67: ocilib::Statement::SetInData() (ocilib_impl.hpp:5394)
==4880==    by 0x4087BD: ocilib::Statement::ExecutePrepared() (ocilib_impl.hpp:4517)
==4880==    by 0x4057A1: main (BigRaw.cpp:113)
==4880==  Address 0x833884b is 5 bytes before a block of size 28 alloc'd
==4880==    at 0x4A069EE: malloc (vg_replace_malloc.c:270)
==4880==    by 0x4C4AB8C: OCI_MemAlloc (memory.c:70)
==4880==    by 0x4C5E23B: OCI_BindData (statement.c:805)
==4880==    by 0x4C631E7: OCI_BindArrayOfRaws (statement.c:2948)
==4880==    by 0x408A3A: void ocilib::Statement::Bind<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned int>(std::string const&, std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&, unsigned int, ocilib::Enum<ocilib::BindInfo::BindDirectionValues>) (ocilib_impl.hpp:5103)
==4880==    by 0x40577A: main (BigRaw.cpp:112)
==4880== 
==4880== Invalid write of size 8
==4880==    at 0x4A08D13: memcpy (mc_replace_strmem.c:882)
==4880==    by 0x408054: ocilib::BindArray::BindArrayObject<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>::SetInData() (ocilib_impl.hpp:4180)
==4880==    by 0x407F3A: ocilib::BindArray::SetInData() (ocilib_impl.hpp:4085)
==4880==    by 0x408597: ocilib::BindsHolder::SetInData() (ocilib_impl.hpp:4395)
==4880==    by 0x408B67: ocilib::Statement::SetInData() (ocilib_impl.hpp:5394)
==4880==    by 0x4087BD: ocilib::Statement::ExecutePrepared() (ocilib_impl.hpp:4517)
==4880==    by 0x4057A1: main (BigRaw.cpp:113)
==4880==  Address 0x8338840 is 16 bytes before a block of size 28 alloc'd
==4880==    at 0x4A069EE: malloc (vg_replace_malloc.c:270)
==4880==    by 0x4C4AB8C: OCI_MemAlloc (memory.c:70)
==4880==    by 0x4C5E23B: OCI_BindData (statement.c:805)
==4880==    by 0x4C631E7: OCI_BindArrayOfRaws (statement.c:2948)
==4880==    by 0x408A3A: void ocilib::Statement::Bind<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned int>(std::string const&, std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&, unsigned int, ocilib::Enum<ocilib::BindInfo::BindDirectionValues>) (ocilib_impl.hpp:5103)
==4880==    by 0x40577A: main (BigRaw.cpp:112)
==4880== 
==4880== Invalid write of size 1
==4880==    at 0x4A08DAF: memcpy (mc_replace_strmem.c:882)
==4880==    by 0x408054: ocilib::BindArray::BindArrayObject<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>::SetInData() (ocilib_impl.hpp:4180)
==4880==    by 0x407F3A: ocilib::BindArray::SetInData() (ocilib_impl.hpp:4085)
==4880==    by 0x408597: ocilib::BindsHolder::SetInData() (ocilib_impl.hpp:4395)
==4880==    by 0x408B67: ocilib::Statement::SetInData() (ocilib_impl.hpp:5394)
==4880==    by 0x4087BD: ocilib::Statement::ExecutePrepared() (ocilib_impl.hpp:4517)
==4880==    by 0x4057A1: main (BigRaw.cpp:113)
==4880==  Address 0x833904e is not stack'd, malloc'd or (recently) free'd
==4880== 
==4880== Invalid write of size 2
==4880==    at 0x4A08D74: memcpy (mc_replace_strmem.c:882)
==4880==    by 0x408054: ocilib::BindArray::BindArrayObject<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>::SetInData() (ocilib_impl.hpp:4180)
==4880==    by 0x407F3A: ocilib::BindArray::SetInData() (ocilib_impl.hpp:4085)
==4880==    by 0x408597: ocilib::BindsHolder::SetInData() (ocilib_impl.hpp:4395)
==4880==    by 0x408B67: ocilib::Statement::SetInData() (ocilib_impl.hpp:5394)
==4880==    by 0x4087BD: ocilib::Statement::ExecutePrepared() (ocilib_impl.hpp:4517)
==4880==    by 0x4057A1: main (BigRaw.cpp:113)
==4880==  Address 0x8339850 is not stack'd, malloc'd or (recently) free'd
==4880== 
==4880== Invalid read of size 8
==4880==    at 0x5BE37B0: __intel_new_memcpy (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6C60900: ttcacs (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6C2F5F4: ttcdrv (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BDD9B8: nioqwa (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BB95C6: upirtrc (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BC5155: kpurcsc (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BBE56B: kpuexec (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BBA06A: OCIStmtExecute (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x4C605DA: OCI_ExecuteInternal (statement.c:1923)
==4880==    by 0x4C60C57: OCI_Execute (statement.c:2149)
==4880==    by 0x4087D1: ocilib::Statement::ExecutePrepared() (ocilib_impl.hpp:4518)
==4880==    by 0x4057A1: main (BigRaw.cpp:113)
==4880==  Address 0x8338724 is 4 bytes inside a block of size 10 alloc'd
==4880==    at 0x4A07152: operator new[](unsigned long) (vg_replace_malloc.c:363)
==4880==    by 0x40E924: ocilib::BindArray::BindArrayObject<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>::AllocData() (ocilib_impl.hpp:4109)
==4880==    by 0x40C17B: ocilib::BindArray::BindArrayObject<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>::BindArrayObject(ocilib::Statement const&, std::string const&, std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&, unsigned int, unsigned int) (ocilib_impl.hpp:4097)
==4880==    by 0x40A410: void ocilib::BindArray::SetVector<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>(std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&, unsigned int, unsigned int) (ocilib_impl.hpp:4069)
==4880==    by 0x4089F7: void ocilib::Statement::Bind<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned int>(std::string const&, std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&, unsigned int, ocilib::Enum<ocilib::BindInfo::BindDirectionValues>) (ocilib_impl.hpp:5101)
==4880==    by 0x40577A: main (BigRaw.cpp:112)
==4880== 
==4880== Invalid read of size 8
==4880==    at 0x5BE2F43: __intel_new_memcpy (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6C60900: ttcacs (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6C2F5F4: ttcdrv (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BDD9B8: nioqwa (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BB95C6: upirtrc (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BC5155: kpurcsc (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BBE56B: kpuexec (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BBA06A: OCIStmtExecute (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x4C605DA: OCI_ExecuteInternal (statement.c:1923)
==4880==    by 0x4C60C57: OCI_Execute (statement.c:2149)
==4880==    by 0x4087D1: ocilib::Statement::ExecutePrepared() (ocilib_impl.hpp:4518)
==4880==    by 0x4057A1: main (BigRaw.cpp:113)
==4880==  Address 0x833872c is 2 bytes after a block of size 10 alloc'd
==4880==    at 0x4A07152: operator new[](unsigned long) (vg_replace_malloc.c:363)
==4880==    by 0x40E924: ocilib::BindArray::BindArrayObject<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>::AllocData() (ocilib_impl.hpp:4109)
==4880==    by 0x40C17B: ocilib::BindArray::BindArrayObject<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>::BindArrayObject(ocilib::Statement const&, std::string const&, std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&, unsigned int, unsigned int) (ocilib_impl.hpp:4097)
==4880==    by 0x40A410: void ocilib::BindArray::SetVector<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>(std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&, unsigned int, unsigned int) (ocilib_impl.hpp:4069)
==4880==    by 0x4089F7: void ocilib::Statement::Bind<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned int>(std::string const&, std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&, unsigned int, ocilib::Enum<ocilib::BindInfo::BindDirectionValues>) (ocilib_impl.hpp:5101)
==4880==    by 0x40577A: main (BigRaw.cpp:112)
==4880== 
==4880== Invalid read of size 8
==4880==    at 0x5BE2F5A: __intel_new_memcpy (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6C60900: ttcacs (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6C2F5F4: ttcdrv (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BDD9B8: nioqwa (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BB95C6: upirtrc (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BC5155: kpurcsc (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BBE56B: kpuexec (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BBA06A: OCIStmtExecute (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x4C605DA: OCI_ExecuteInternal (statement.c:1923)
==4880==    by 0x4C60C57: OCI_Execute (statement.c:2149)
==4880==    by 0x4087D1: ocilib::Statement::ExecutePrepared() (ocilib_impl.hpp:4518)
==4880==    by 0x4057A1: main (BigRaw.cpp:113)
==4880==  Address 0x8338730 is 6 bytes after a block of size 10 alloc'd
==4880==    at 0x4A07152: operator new[](unsigned long) (vg_replace_malloc.c:363)
==4880==    by 0x40E924: ocilib::BindArray::BindArrayObject<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>::AllocData() (ocilib_impl.hpp:4109)
==4880==    by 0x40C17B: ocilib::BindArray::BindArrayObject<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>::BindArrayObject(ocilib::Statement const&, std::string const&, std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&, unsigned int, unsigned int) (ocilib_impl.hpp:4097)
==4880==    by 0x40A410: void ocilib::BindArray::SetVector<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>(std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&, unsigned int, unsigned int) (ocilib_impl.hpp:4069)
==4880==    by 0x4089F7: void ocilib::Statement::Bind<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned int>(std::string const&, std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&, unsigned int, ocilib::Enum<ocilib::BindInfo::BindDirectionValues>) (ocilib_impl.hpp:5101)
==4880==    by 0x40577A: main (BigRaw.cpp:112)
==4880== Invalid read of size 8
==4880==    at 0x5BE3394: __intel_new_memcpy (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6C60900: ttcacs (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6C2F5F4: ttcdrv (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BDD9B8: nioqwa (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BB95C6: upirtrc (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BC5155: kpurcsc (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BBE56B: kpuexec (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BBA06A: OCIStmtExecute (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x4C605DA: OCI_ExecuteInternal (statement.c:1923)
==4880==    by 0x4C60C57: OCI_Execute (statement.c:2149)
==4880==    by 0x4087D1: ocilib::Statement::ExecutePrepared() (ocilib_impl.hpp:4518)
==4880==    by 0x4057A1: main (BigRaw.cpp:113)
==4880==  Address 0x8338740 is 22 bytes after a block of size 10 alloc'd
==4880==    at 0x4A07152: operator new[](unsigned long) (vg_replace_malloc.c:363)
==4880==    by 0x40E924: ocilib::BindArray::BindArrayObject<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>::AllocData() (ocilib_impl.hpp:4109)
==4880==    by 0x40C17B: ocilib::BindArray::BindArrayObject<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>::BindArrayObject(ocilib::Statement const&, std::string const&, std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&, unsigned int, unsigned int) (ocilib_impl.hpp:4097)
==4880==    by 0x40A410: void ocilib::BindArray::SetVector<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned char>(std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&, unsigned int, unsigned int) (ocilib_impl.hpp:4069)
==4880==    by 0x4089F7: void ocilib::Statement::Bind<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned int>(std::string const&, std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&, unsigned int, ocilib::Enum<ocilib::BindInfo::BindDirectionValues>) (ocilib_impl.hpp:5101)
==4880==    by 0x40577A: main (BigRaw.cpp:112)
==4880== 
==4880== Invalid read of size 8
==4880==    at 0x5BE3399: __intel_new_memcpy (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6C60900: ttcacs (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6C2F5F4: ttcdrv (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BDD9B8: nioqwa (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BB95C6: upirtrc (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BC5155: kpurcsc (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BBE56B: kpuexec (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BBA06A: OCIStmtExecute (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x4C605DA: OCI_ExecuteInternal (statement.c:1923)
==4880==    by 0x4C60C57: OCI_Execute (statement.c:2149)
==4880==    by 0x4087D1: ocilib::Statement::ExecutePrepared() (ocilib_impl.hpp:4518)
==4880==    by 0x4057A1: main (BigRaw.cpp:113)
==4880==  Address 0x8338750 is not stack'd, malloc'd or (recently) free'd
==4880== 
==4880== Invalid read of size 2
==4880==    at 0x5BE2B27: __intel_new_memcpy (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6C60900: ttcacs (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6C2F5F4: ttcdrv (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BDD9B8: nioqwa (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BB95C6: upirtrc (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BC5155: kpurcsc (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BBE56B: kpuexec (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x6BBA06A: OCIStmtExecute (in /vobs/thirdparty/oracle/instantclient/installed/instantclient_11_2/linux/libclntsh.so.11.1)
==4880==    by 0x4C605DA: OCI_ExecuteInternal (statement.c:1923)
==4880==    by 0x4C60C57: OCI_Execute (statement.c:2149)
==4880==    by 0x4087D1: ocilib::Statement::ExecutePrepared() (ocilib_impl.hpp:4518)
==4880==    by 0x4057A1: main (BigRaw.cpp:113)
==4880==  Address 0x833881c is 20 bytes after a block of size 152 alloc'd
==4880==    at 0x4A069EE: malloc (vg_replace_malloc.c:270)
==4880==    by 0x4C4AB8C: OCI_MemAlloc (memory.c:70)
==4880==    by 0x4C5E1FB: OCI_BindData (statement.c:793)
==4880==    by 0x4C631E7: OCI_BindArrayOfRaws (statement.c:2948)
==4880==    by 0x408A3A: void ocilib::Statement::Bind<std::vector<unsigned char, std::allocator<unsigned char> >, unsigned int>(std::string const&, std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >&, unsigned int, ocilib::Enum<ocilib::BindInfo::BindDirectionValues>) (ocilib_impl.hpp:5103)
==4880==    by 0x40577A: main (BigRaw.cpp:112)
==4880== 
...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.