K2InformaticsGmbH / erloci

Erlang Oracle native driver - DEPRECATED, see https://github.com/K2InformaticsGmbH/oranif instead
Apache License 2.0
37 stars 11 forks source link

reading RAW fields is truncating at byte 0 #59

Open c-bik opened 6 years ago

c-bik commented 6 years ago

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

  1. cur_clm.dlen + 1 is used to allocate buffer for RAW which is always (for the raw_clob table above) 2000. https://github.com/K2InformaticsGmbH/erloci/blob/49557dbe09fe8541f04bc5d6f899e27c09849f7b/c_src/erloci_lib/ocistmt.cpp#L479-L484 due to incorrect use of OCIAttrGet(OCI_DTYPE_PARAM, OCI_ATTR_DATA_SIZE) API to get the value in cur_clm.dlen https://github.com/K2InformaticsGmbH/erloci/blob/49557dbe09fe8541f04bc5d6f899e27c09849f7b/c_src/erloci_lib/ocistmt.cpp#L398-L400
  2. Eventually hoever, strlen is used in https://github.com/K2InformaticsGmbH/erloci/blob/49557dbe09fe8541f04bc5d6f899e27c09849f7b/c_src/erloci_lib/ocistmt.cpp#L974-L982 to determine real data length causing the truncation when binary contains 0 (\0 as string termination character)