pacman82 / odbc-api

ODBC (Open Database Connectivity) bindings for Rust.
MIT License
129 stars 23 forks source link

Missing Oracle Timestamp Milliseconds. Need for Extended Type Support. #635

Closed yjhong79 closed 1 week ago

yjhong79 commented 1 week ago

While working with Oracle, I encountered an issue where the milliseconds in Oracle Timestamps are not being retrieved correctly. I compared this behavior with other ODBC projects and found a difference.

In nano-odbc, after calling SQLDescribeCol, there is an additional step where the type is converted to an extended type before calling SQLBindCol. This logic helps to properly handle detailed types, including millisecond precision. However, this implementation is currently missing in odbc-api.

Without this additional logic, it seems that the sub-millisecond precision of Oracle Timestamps cannot be retrieved correctly.

https://github.com/nanodbc/nanodbc/blob/29d0f3dfcb0c692d0c92f927a65f3cbae34f0482/nanodbc/nanodbc.cpp#L3911

nano-odbc implementation:

using namespace std; // if int64_t is in std namespace (in c++11)
switch (col.sqltype_)
{
    case SQL_BIT:
    case SQL_TINYINT:
    case SQL_SMALLINT:
    case SQL_INTEGER:
    case SQL_BIGINT:
        col.ctype_ = SQL_C_SBIGINT;
        col.clen_ = sizeof(int64_t);
        break;
    case SQL_DOUBLE:
    case SQL_FLOAT:
    case SQL_REAL:
        col.ctype_ = SQL_C_DOUBLE;
        col.clen_ = sizeof(double);
        break;
    // ... more cases for handling various SQL types ...
    case SQL_TIMESTAMP:
    case SQL_TYPE_TIMESTAMP:
        col.ctype_ = SQL_C_TIMESTAMP;
        col.clen_ = sizeof(timestamp);
        break;
    // ... additional type handling logic ...
}

Could support for extended types be added to address this issue?

yjhong79 commented 1 week ago

After reviewing the code further, it seems that this issue should be addressed in arrow-odbc.

I solved it by using OdbcReaderBuilder::with_schema in arrow-odbc