Oracle ODBC fixes

This commit is contained in:
Alex Fabijanic 2017-10-26 12:54:04 -05:00
parent bbf30dc674
commit 494579542f
8 changed files with 33 additions and 34 deletions

View File

@ -158,7 +158,6 @@ private:
bool _prepared; bool _prepared;
mutable std::size_t _affectedRowCount; mutable std::size_t _affectedRowCount;
bool _canCompile; bool _canCompile;
bool _isPostgres;
bool _insertHint; bool _insertHint;
}; };

View File

@ -99,9 +99,7 @@ public:
Preparator(const StatementHandle& rStmt, Preparator(const StatementHandle& rStmt,
const std::string& statement, const std::string& statement,
std::size_t maxFieldSize, std::size_t maxFieldSize,
DataExtraction dataExtraction, DataExtraction dataExtraction);
bool isPostgres
);
/// Creates the Preparator. /// Creates the Preparator.
Preparator(const Preparator& other); Preparator(const Preparator& other);

View File

@ -135,18 +135,11 @@ void ODBCMetaColumn::init()
case SQL_NUMERIC: case SQL_NUMERIC:
case SQL_DECIMAL: case SQL_DECIMAL:
if (0 == _columnDesc.decimalDigits) // Oracle has no INTEGER type - it's essentially NUMBER with 38 whole and
{ // 0 fractional digits. It also does not recognize SQL_BIGINT type,
#ifdef POCO_64_BIT // so the workaround here is to hardcode it to 32 bit integer
setType(MetaColumn::FDT_INT64); if (0 == _columnDesc.decimalDigits) setType(MetaColumn::FDT_INT32);
#else else setType(MetaColumn::FDT_DOUBLE);
setType(MetaColumn::FDT_INT32);
#endif
}
else
{
setType(MetaColumn::FDT_DOUBLE);
}
break; break;
case SQL_REAL: case SQL_REAL:

View File

@ -45,7 +45,6 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
_prepared(false), _prepared(false),
_affectedRowCount(0), _affectedRowCount(0),
_canCompile(true), _canCompile(true),
_isPostgres(false),
_insertHint(false) _insertHint(false)
{ {
int queryTimeout = rSession.queryTimeout(); int queryTimeout = rSession.queryTimeout();
@ -64,7 +63,6 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
std::string serverString; std::string serverString;
serverString.resize(static_cast<std::size_t>(t) + 2); serverString.resize(static_cast<std::size_t>(t) + 2);
r = Poco::Data::ODBC::SQLGetInfo(_rConnection, SQL_DRIVER_NAME, &serverString[0], SQLSMALLINT((serverString.length() - 1) * sizeof(serverString[0])), &t); r = Poco::Data::ODBC::SQLGetInfo(_rConnection, SQL_DRIVER_NAME, &serverString[0], SQLSMALLINT((serverString.length() - 1) * sizeof(serverString[0])), &t);
_isPostgres = (!Utility::isError(r) && Poco::toUpperInPlace(serverString).find("PSQLODBC") == 0);
} }
} }
@ -152,7 +150,7 @@ bool ODBCStatementImpl::addPreparator(bool addAlways)
std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize")); std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));
prep = new Preparator(_stmt, statement, maxFieldSize, ext, _isPostgres); prep = new Preparator(_stmt, statement, maxFieldSize, ext);
} }
else else
prep = new Preparator(*_preparations[0]); prep = new Preparator(*_preparations[0]);
@ -307,14 +305,13 @@ bool ODBCStatementImpl::nextResultSet()
if (SQL_NO_DATA == ret) if (SQL_NO_DATA == ret)
return false; return false;
if (Utility::isError(ret)) { if (Utility::isError(ret))
throw StatementException(_stmt, "SQLMoreResults()"); throw StatementException(_stmt, "SQLMoreResults()");
}
// need to remove old bindings, as Sybase doesn't like old ones // need to remove old bindings, as Sybase doesn't like old ones
if (Utility::isError(SQLFreeStmt(_stmt, SQL_UNBIND))) { if (Utility::isError(SQLFreeStmt(_stmt, SQL_UNBIND)))
throw StatementException(_stmt, "SQLFreeStmt(SQL_UNBIND)"); throw StatementException(_stmt, "SQLFreeStmt(SQL_UNBIND)");
}
return true; return true;
} }

View File

@ -28,8 +28,7 @@ namespace ODBC {
Preparator::Preparator(const StatementHandle& rStmt, Preparator::Preparator(const StatementHandle& rStmt,
const std::string& statement, const std::string& statement,
std::size_t maxFieldSize, std::size_t maxFieldSize,
DataExtraction dataExtraction, DataExtraction dataExtraction) :
bool isPostgres) :
_rStmt(rStmt), _rStmt(rStmt),
_maxFieldSize(maxFieldSize), _maxFieldSize(maxFieldSize),
_dataExtraction(dataExtraction) _dataExtraction(dataExtraction)
@ -38,9 +37,8 @@ Preparator::Preparator(const StatementHandle& rStmt,
if (Utility::isError(Poco::Data::ODBC::SQLPrepare(_rStmt, pStr, (SQLINTEGER) statement.length()))) if (Utility::isError(Poco::Data::ODBC::SQLPrepare(_rStmt, pStr, (SQLINTEGER) statement.length())))
throw StatementException(_rStmt); throw StatementException(_rStmt);
// PostgreSQL error swallowing workaround: // PostgreSQL error swallowing workaround:
// Postgres may execute a statement with sintax error fine, // Postgres may execute a statement with syntax error fine,
// but would return error once num of columns requested! // but will return error later
if (isPostgres)
{ {
SQLSMALLINT t = 0; SQLSMALLINT t = 0;
SQLRETURN r = SQLNumResultCols(rStmt, &t); SQLRETURN r = SQLNumResultCols(rStmt, &t);

View File

@ -41,7 +41,7 @@ using Poco::DynamicAny;
using Poco::DateTime; using Poco::DateTime;
#define ORACLE_ODBC_DRIVER "Oracle in OraClient12Home1_32bit"//XE" #define ORACLE_ODBC_DRIVER "Oracle in OraDB12Home1"//XE"
#define ORACLE_DSN "PocoDataOracleTest" #define ORACLE_DSN "PocoDataOracleTest"
#define ORACLE_SERVER POCO_ODBC_TEST_DATABASE_SERVER #define ORACLE_SERVER POCO_ODBC_TEST_DATABASE_SERVER
#define ORACLE_PORT "1521" #define ORACLE_PORT "1521"
@ -775,13 +775,22 @@ void ODBCOracleTest::recreateStringsTable()
void ODBCOracleTest::recreateFloatsTable() void ODBCOracleTest::recreateFloatsTable()
{ {
dropObject("TABLE", ExecUtil::strings()); dropObject("TABLE", ExecUtil::floats());
try { *_pSession << "CREATE TABLE " << ExecUtil::strings() <<" (str NUMBER)", now; } try { *_pSession << "CREATE TABLE " << ExecUtil::floats() <<" (str NUMBER)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateFloatsTable()"); } catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateFloatsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateFloatsTable()"); } catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateFloatsTable()"); }
} }
void ODBCOracleTest::recreateDoublesTable()
{
dropObject("TABLE", ExecUtil::doubles());
try { *_pSession << "CREATE TABLE " << ExecUtil::doubles() << " (str NUMBER)", now; }
catch (ConnectionException& ce) { std::cout << ce.toString() << std::endl; fail("recreateFloatsTable()"); }
catch (StatementException& se) { std::cout << se.toString() << std::endl; fail("recreateFloatsTable()"); }
}
void ODBCOracleTest::recreateTuplesTable() void ODBCOracleTest::recreateTuplesTable()
{ {
dropObject("TABLE", ExecUtil::tuples()); dropObject("TABLE", ExecUtil::tuples());
@ -815,10 +824,13 @@ void ODBCOracleTest::recreateAnysTable()
void ODBCOracleTest::recreateNullsTable(const std::string& notNull) void ODBCOracleTest::recreateNullsTable(const std::string& notNull)
{ {
dropObject("TABLE", ExecUtil::nulltest()); dropObject("TABLE", ExecUtil::nulltest());
try { *_pSession << format("CREATE TABLE %s (i INTEGER %s, r NUMBER %s, v VARCHAR(30) %s)",ExecUtil::nulltest(), try
{
*_pSession << format("CREATE TABLE %s (i INTEGER %s, r NUMBER %s, v VARCHAR(30) %s)", ExecUtil::nulltest(),
notNull, notNull,
notNull, notNull,
notNull), now; } notNull), now;
}
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateNullsTable()"); } catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateNullsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateNullsTable()"); } catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateNullsTable()"); }
} }

View File

@ -65,6 +65,7 @@ private:
void recreateStringsTable(); void recreateStringsTable();
void recreateIntsTable(); void recreateIntsTable();
void recreateFloatsTable(); void recreateFloatsTable();
void recreateDoublesTable();
void recreateTuplesTable(); void recreateTuplesTable();
void recreateVectorsTable(); void recreateVectorsTable();
void recreateAnysTable(); void recreateAnysTable();

View File

@ -3015,7 +3015,8 @@ void SQLExecutor::notNulls(const std::string& sqlState)
{ {
session() << "INSERT INTO "<< ExecUtil::nulltest() << " (i,r,v) VALUES (?,?,?)", use(null), use(null), use(null), now; session() << "INSERT INTO "<< ExecUtil::nulltest() << " (i,r,v) VALUES (?,?,?)", use(null), use(null), use(null), now;
fail ("must fail"); fail ("must fail");
}catch (StatementException& se) }
catch (StatementException& se)
{ {
//double check if we're failing for the right reason //double check if we're failing for the right reason
//default sqlState value is "23502"; some drivers report "HY???" codes //default sqlState value is "23502"; some drivers report "HY???" codes