Closed acautin closed 5 years ago
These are an example call sequence for retrieving and using RowIDs using DPI:
// perform first query to get rowid
if (dpiTestCase_getConnection(testCase, &conn) < 0)
return DPI_FAILURE;
if (dpiConn_prepareStmt(conn, 0, sqlQuery1, strlen(sqlQuery1), NULL, 0,
&stmt1) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiStmt_execute(stmt1, 0, NULL) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiStmt_fetch(stmt1, &found, &bufferRowIndex) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (!found)
return dpiTestCase_setFailed(testCase,
"row not found for first query!");
if (dpiStmt_getQueryValue(stmt1, 1, &nativeTypeNum, &queryValue) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiRowid_getStringValue(queryValue->value.asRowid, &rowidAsString,
&rowidAsStringLength) < 0)
return dpiTestCase_setFailedFromError(testCase);
// perform second query to get row using rowid
if (dpiConn_prepareStmt(conn, 0, sqlQuery2, strlen(sqlQuery2), NULL, 0,
&stmt2) < 0)
return dpiTestCase_setFailedFromError(testCase);
dpiData_setBytes(&bindValue, (char*) rowidAsString, rowidAsStringLength);
if (dpiStmt_bindValueByPos(stmt2, 1, DPI_NATIVE_TYPE_BYTES,
&bindValue) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiStmt_execute(stmt2, 0, NULL) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiStmt_fetch(stmt2, &found, &bufferRowIndex) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (!found)
return dpiTestCase_setFailed(testCase,
"row not found for second query!");
if (dpiStmt_getQueryValue(stmt2, 1, &nativeTypeNum, &queryValue) < 0)
return dpiTestCase_setFailedFromError(testCase);
if (dpiTestCase_expectUintEqual(testCase, queryValue->value.asInt64,
7) < 0)
return dpiTestCase_setFailedFromError(testCase);
@acautin can you please remark if it can be implemented this way for oranif
?
@c-bik certainly it would be possible to implement it like that, but it would be simpler if it can be added to the switch case here https://github.com/K2InformaticsGmbH/oranif/blob/master/c_src/dpiData_nif.c#L276 to make the interface in dderloci more transparent regarding types. Is that not supported on the odpi side ?
@KarlKeiser Will this work?
case DPI_NATIVE_TYPE_ROWID:
{
const char *rowidAsString;
uint32_t rowidAsStringLength;
RAISE_EXCEPTION_ON_DPI_ERROR(
context,
dpiRowid_getStringValue(data->value.asRowid, &rowidAsString, , &rowidAsString, &rowidAsStringLength)
);
ErlNifBinary bin;
enif_alloc_binary(rowidAsStringLength, &bin);
memcpy(bin.data, rowidAsString, rowidAsStringLength);
dataRet = enif_make_binary(env, &bin);
}
break;
@acautin Can you use ROWIDTOCHAR when you are injecting Row ID into statements instead? For example:
select * from test1
will transform into
select ROWIDTOCHAR(rowid), t.* from test1 t
It looks the same and no rowID datatype transformation necessary as it is already a string!
@c-bik this workaround will solve our usage of rowid injections and will use it for now to continue, but nothing is preventing the users from typing select rowid, somecol from sometable
in a query window so we still need to support it.
Support for this type is required for dderl as we use it as the base for data manipulation.