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;
mutable std::size_t _affectedRowCount;
bool _canCompile;
bool _isPostgres;
bool _insertHint;
};

View File

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

View File

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

View File

@ -45,7 +45,6 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
_prepared(false),
_affectedRowCount(0),
_canCompile(true),
_isPostgres(false),
_insertHint(false)
{
int queryTimeout = rSession.queryTimeout();
@ -64,7 +63,6 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
std::string serverString;
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);
_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"));
prep = new Preparator(_stmt, statement, maxFieldSize, ext, _isPostgres);
prep = new Preparator(_stmt, statement, maxFieldSize, ext);
}
else
prep = new Preparator(*_preparations[0]);
@ -307,14 +305,13 @@ bool ODBCStatementImpl::nextResultSet()
if (SQL_NO_DATA == ret)
return false;
if (Utility::isError(ret)) {
if (Utility::isError(ret))
throw StatementException(_stmt, "SQLMoreResults()");
}
// 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)");
}
return true;
}

View File

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

View File

@ -41,7 +41,7 @@ using Poco::DynamicAny;
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_SERVER POCO_ODBC_TEST_DATABASE_SERVER
#define ORACLE_PORT "1521"
@ -775,13 +775,22 @@ void ODBCOracleTest::recreateStringsTable()
void ODBCOracleTest::recreateFloatsTable()
{
dropObject("TABLE", ExecUtil::strings());
try { *_pSession << "CREATE TABLE " << ExecUtil::strings() <<" (str NUMBER)", now; }
dropObject("TABLE", ExecUtil::floats());
try { *_pSession << "CREATE TABLE " << ExecUtil::floats() <<" (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::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()
{
dropObject("TABLE", ExecUtil::tuples());
@ -815,10 +824,13 @@ void ODBCOracleTest::recreateAnysTable()
void ODBCOracleTest::recreateNullsTable(const std::string& notNull)
{
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), now; }
notNull), now;
}
catch(ConnectionException& ce){ std::cout << ce.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 recreateIntsTable();
void recreateFloatsTable();
void recreateDoublesTable();
void recreateTuplesTable();
void recreateVectorsTable();
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;
fail ("must fail");
}catch (StatementException& se)
}
catch (StatementException& se)
{
//double check if we're failing for the right reason
//default sqlState value is "23502"; some drivers report "HY???" codes