Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCI-22060: dpiObject_getAttributeValue for PLS_INTEGER #112

Closed
tgulacsi opened this issue Aug 17, 2019 · 9 comments
Closed

OCI-22060: dpiObject_getAttributeValue for PLS_INTEGER #112

tgulacsi opened this issue Aug 17, 2019 · 9 comments
Labels
bug patch available Awaiting inclusion in official release

Comments

@tgulacsi
Copy link

I'm calling

C.dpiObject_getAttributeValue(O.dpiObject, attr.dpiObjectAttr, data.NativeTypeNum, data.dpiData) 

for

TYPE rec_typ IS RECORD (int PLS_INTEGER, num NUMBER, vc VARCHAR2(1000), c CHAR(1000), dt DATE);

's "INT" attribute,

with

obj_test.go:141: getAttributeValue("INT", obj=BRUNO_OWNER.REC_TYP, attr=&{typeDef:0x898c40 checkInt:3933035998 refCount:1 env:0x1eaddb0 belongsToType:0x1f1c2c0 name:0x1f05a60 nameLength:3 typeInfo:{oracleTypeNum:2009 defaultNativeTypeNum:3000 ociTypeCode:266 dbSizeInBytes:0 clientSizeInBytes:0 sizeInChars:0 precision:0 scale:0 fsPrecision:0 objectType:<nil>}}, typ=3000):

and get

ORA-22060: OCI-22060: argument [2] is an invalid or uninitialized number INT

debug log:

ODPI [32483] 2019-08-17 07:49:09.515: fn start dpiObject_getAttributeValue(0x1f8c850)
ODPI [32483] 2019-08-17 07:49:09.531: OCI error OCI-22060: argument [2] is an invalid or uninitialized number (dpiObject_getAttributeValue / number to integer)

What am I doing wrong?

The documentation of getAttributeValue says only NUMBER types need a destination buffer, all other types are managed.

This sort-of works (returns nil instead of error) when I replace PLS_INTEGER with INTEGER.

Thanks in advance.

@cjbj cjbj added the question label Aug 17, 2019
@tgulacsi
Copy link
Author

Just to emphasize, this is on a 19c database, and the type live in the package header, only!
(It can be deduced from the field's type, but I wanted to clarify).

@anthony-tuininga
Copy link
Member

Can you provide a full example? The error appears to be occurring after the value has been acquired from the database and is being converted to an integer -- so probably isn't something you are doing wrong directly (but see below). I see that I don't have a sample for manipulating records, but there are test cases that you can examine -- if that will help!

One possibility: if you create a record you must set all of the attributes or you may end up with unusual behaviour or even segfaults (due to a bug in the Oracle Client libraries). If the record was acquired from the database it should be fine, though. I'll see if there is some way to do this automatically when needed -- and avoid doing it when it is not needed.

tgulacsi added a commit to go-goracle/goracle that referenced this issue Aug 24, 2019
@tgulacsi
Copy link
Author

A concrete (go) example is https://github.com/go-goracle/goracle/blob/master/z_plsql_types_test.go#L708

I've sprinkled it with Object.ResetAttributes (which sets each attribute with NULL), without help.

The strange thing is that the first object (which is populated from go code) is there and the set PLS_INTEGER value is there and retreived, too.
But the second is appended in PL/SQL, and that produces the

z_plsql_types_test.go:718: getAttributeValue("INT", obj=BRUNO_OWNER.REC_TYP, attr=&{typeDef:0x89ec40 checkInt:3933035998 refCount:1 env:0x23caaf0 belongsToType:0x244a990 name:0x7f27f8040a60 nameLength:3 typeInfo:{oracleTypeNum:2009 defaultNativeTypeNum:3000 ociTypeCode:266 dbSizeInBytes:0 clientSizeInBytes:0 sizeInChars:0 precision:0 scale:0 fsPrecision:0 objectType:<nil>}}, typ=3000): ORA-22060: OCI-22060: argument [2] is an invalid or uninitialized number INT

error.

@anthony-tuininga
Copy link
Member

So it turns out that PLS_INTEGER is stored as int32_t and not as OCINumber as I originally thought. I will be correcting this and adding some more (or perhaps better!) test cases.

@tgulacsi
Copy link
Author

Sorry, some side questions regarding objects:

  1. Where are the objects created with dpiObjectType_createObject? Server-side or client-side?
    As I've met with strange (disconnect) errors after setting too long values to attributes only on execute, I'd day they're on client side till use, but I may be wrong.

  2. On which level are dpiObjects? Context or connection? If objects are client-side, then they may be at context level, but I don't know for sure as creating (finding) them needs a connection (dpiConn_getObjectType).

Thanks again for your great work, and if these questions should be asked somewhere else, please advise so!

@anthony-tuininga
Copy link
Member

Where are the objects created with dpiObjectType_createObject? Server-side or client-side?
As I've met with strange (disconnect) errors after setting too long values to attributes only on execute, I'd day they're on client side till use, but I may be wrong.

Yes. Objects are created and attributes set on the client side only.

On which level are dpiObjects? Context or connection? If objects are client-side, then they may be at context level, but I don't know for sure as creating (finding) them needs a connection (dpiConn_getObjectType).

Objects are indeed client side but they require a "session" (aka connection) where they are stored in an object cache. The "session" is also used to acquire type information, if necesary.

@anthony-tuininga anthony-tuininga added the patch available Awaiting inclusion in official release label Aug 27, 2019
@cjbj
Copy link
Member

cjbj commented Aug 27, 2019

It's worth noting that getting object type info is a round trip. In node-oracledb @anthony-tuininga implemented a type info cache, using the FQN as the key. This reduces round trips when user apps don't explicitly keep a reference to the type. To take advantage of the driver cache, users need to be encouraged to use FQNs.

@anthony-tuininga
Copy link
Member

Just to be clear, the type info cache was only implemented in the node-oracledb driver. No such cache has (yet) been implemented at the ODPI-C level. But in order to take advantage of a (potentially future) implementation that does cache the type information, use the fully qualified names whenever getting type information, or retain the object type directly yourself.

@anthony-tuininga
Copy link
Member

This was included in ODPI-C 3.2.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug patch available Awaiting inclusion in official release
Projects
None yet
Development

No branches or pull requests

3 participants