Skip to content
This repository has been archived by the owner on May 16, 2020. It is now read-only.

Missing support for DPI_NATIVE_TYPE_ROWID #117

Closed
acautin opened this issue Jul 16, 2019 · 5 comments · Fixed by #121
Closed

Missing support for DPI_NATIVE_TYPE_ROWID #117

acautin opened this issue Jul 16, 2019 · 5 comments · Fixed by #121
Assignees
Labels
enhancement New feature or request

Comments

@acautin
Copy link
Contributor

acautin commented Jul 16, 2019

Support for this type is required for dderl as we use it as the base for data manipulation.

@c-bik
Copy link
Member

c-bik commented Jul 27, 2019

These are an example call sequence for retrieving and using RowIDs using DPI:

Get Row ID

    // 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);

Use Row ID

    // 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?

@acautin
Copy link
Contributor Author

acautin commented Jul 28, 2019

@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 ?

@c-bik
Copy link
Member

c-bik commented Jul 29, 2019

@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;

@c-bik
Copy link
Member

c-bik commented Jul 29, 2019

@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

image

It looks the same and no rowID datatype transformation necessary as it is already a string!

@acautin
Copy link
Contributor Author

acautin commented Jul 29, 2019

@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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants