From 43195651afa9897a746b863d73af887331771a76 Mon Sep 17 00:00:00 2001 From: Alex Fabijanic Date: Fri, 20 Oct 2017 22:14:07 -0500 Subject: [PATCH] Poco::Data ODBC impl doesn't bind to unsigned numeric types properly #1683 --- .../include/Poco/Data/ODBC/ODBCMetaColumn.h | 3 ++ Data/ODBC/src/ODBCMetaColumn.cpp | 41 ++++++++++++++----- Data/ODBC/src/SessionImpl.cpp | 4 ++ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/Data/ODBC/include/Poco/Data/ODBC/ODBCMetaColumn.h b/Data/ODBC/include/Poco/Data/ODBC/ODBCMetaColumn.h index 8b5b09797..cc9df6d36 100644 --- a/Data/ODBC/include/Poco/Data/ODBC/ODBCMetaColumn.h +++ b/Data/ODBC/include/Poco/Data/ODBC/ODBCMetaColumn.h @@ -50,6 +50,9 @@ public: /// null-termination byte that ends the character string. /// This information is returned from the SQL_DESC_LENGTH record field of the IRD. + bool isUnsigned() const; + /// Returns true if column is unsigned or a non-numeric data type. + private: ODBCMetaColumn(); diff --git a/Data/ODBC/src/ODBCMetaColumn.cpp b/Data/ODBC/src/ODBCMetaColumn.cpp index 87359045e..65bd62a5f 100644 --- a/Data/ODBC/src/ODBCMetaColumn.cpp +++ b/Data/ODBC/src/ODBCMetaColumn.cpp @@ -58,6 +58,23 @@ void ODBCMetaColumn::getDescription() } +bool ODBCMetaColumn::isUnsigned() const +{ + SQLLEN val = 0; + if (Utility::isError(Poco::Data::ODBC::SQLColAttribute(_rStmt, + (SQLUSMALLINT)position() + 1, // ODBC columns are 1-based + SQL_DESC_UNSIGNED, + 0, + 0, + 0, + &val))) + { + throw StatementException(_rStmt); + } + return (val == SQL_TRUE); +} + + void ODBCMetaColumn::init() { getDescription(); @@ -94,23 +111,27 @@ void ODBCMetaColumn::init() case SQL_WVARCHAR: case SQL_WLONGVARCHAR: setType(MetaColumn::FDT_WSTRING); break; - + case SQL_TINYINT: - setType(MetaColumn::FDT_INT8); break; - + setType(isUnsigned() ? MetaColumn::FDT_UINT8 : MetaColumn::FDT_INT8); + break; + case SQL_SMALLINT: - setType(MetaColumn::FDT_INT16); break; - + setType(isUnsigned() ? MetaColumn::FDT_UINT16 : MetaColumn::FDT_INT16); + break; + case SQL_INTEGER: - setType(MetaColumn::FDT_INT32); break; - + setType(isUnsigned() ? MetaColumn::FDT_UINT32 : MetaColumn::FDT_INT32); + break; + case SQL_BIGINT: - setType(MetaColumn::FDT_INT64); break; - + setType(isUnsigned() ? MetaColumn::FDT_UINT64 : MetaColumn::FDT_INT64); + break; + case SQL_DOUBLE: case SQL_FLOAT: setType(MetaColumn::FDT_DOUBLE); break; - + case SQL_NUMERIC: case SQL_DECIMAL: if (0 == _columnDesc.decimalDigits) diff --git a/Data/ODBC/src/SessionImpl.cpp b/Data/ODBC/src/SessionImpl.cpp index 44360c17d..99e7ff340 100644 --- a/Data/ODBC/src/SessionImpl.cpp +++ b/Data/ODBC/src/SessionImpl.cpp @@ -222,7 +222,11 @@ bool SessionImpl::canTransact() void SessionImpl::setTransactionIsolation(Poco::UInt32 ti) { +#if POCO_PTR_IS_64_BIT + Poco::UInt64 isolation = 0; +#else Poco::UInt32 isolation = 0; +#endif if (ti & Session::TRANSACTION_READ_UNCOMMITTED) isolation |= SQL_TXN_READ_UNCOMMITTED;