Create Table:
create table raw_clob(col_raw raw(2000))
Note: data is corrupted when read through select!
StmtInsert = OciSession:prep_sql(<<"insert into raw_clob (col_raw) values (:col_raw)">>).
ok = StmtInsert:bind_vars([{<<":col_raw">>, 'SQLT_BIN'}]).
Data = <<1,2,3,4,0,0,0,5,6,7,8>>,
{rowids, [_]} = StmtInsert:exec_stmt([{Data}]).
SelStmt = OciSession:prep_sql("select col_raw from raw_clob").
> {cols, _} = SelStmt:exec_stmt().
{cols,[{<<"COL_RAW">>,'SQLT_BIN',2000,0,0}]}
> SelStmt:fetch_rows(100).
{{rows,[[<<1,2,3,4>>]]},true}
Root Cause
cur_clm.dlen + 1 is used to allocate buffer for RAW which is always (for the raw_clob table above) 2000.
|
case SQLT_BIN: // RAW |
|
cur_clm.row_valp = new unsigned char[cur_clm.dlen + 1]; |
|
memset(cur_clm.row_valp, 0, (cur_clm.dlen + 1)*sizeof(unsigned char)); |
|
cur_clm.rtype = LCL_DTYPE_NONE; |
|
OCIDEF(SQLT_BIN, "SQLT_BIN"); |
|
break; |
due to incorrect use of OCIAttrGet(OCI_DTYPE_PARAM, OCI_ATTR_DATA_SIZE) API to get the value in cur_clm.dlen
|
checkerr(&r, OCIAttrGet((dvoid*) mypard, (ub4) OCI_DTYPE_PARAM, |
|
(dvoid*) &(cur_clm.dlen), (ub4 *)0, (ub4)OCI_ATTR_DATA_SIZE, |
|
(OCIError*)_errhp)); |
- Eventually hoever,
strlen is used in
|
case SQLT_BIN: |
|
case SQLT_RID: |
|
case SQLT_AFC: |
|
case SQLT_STR: { |
|
size_t str_len = strlen((char*)(_columns[i]->row_valp)); |
|
(*intf.append_string_to_list)((char*)(_columns[i]->row_valp), str_len, row); |
|
memset(_columns[i]->row_valp, 0, str_len); |
|
break; |
|
} |
to determine real data length causing the truncation when binary contains 0 (\0 as string termination character)
Create Table:
Note: data is corrupted when read through select!
Root Cause
cur_clm.dlen + 1is used to allocate buffer for RAW which is always (for theraw_clobtable above) 2000.erloci/c_src/erloci_lib/ocistmt.cpp
Lines 479 to 484 in 49557db
OCIAttrGet(OCI_DTYPE_PARAM, OCI_ATTR_DATA_SIZE)API to get the value incur_clm.dlenerloci/c_src/erloci_lib/ocistmt.cpp
Lines 398 to 400 in 49557db
strlenis used inerloci/c_src/erloci_lib/ocistmt.cpp
Lines 974 to 982 in 49557db
\0as string termination character)