Skip to content

reading RAW fields is truncating at byte 0 #59

@c-bik

Description

@c-bik

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.
    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));
  2. 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)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions