diff options
-rw-r--r-- | connectivity/source/drivers/firebird/PreparedStatement.cxx | 34 | ||||
-rw-r--r-- | connectivity/source/drivers/firebird/Util.hxx | 16 |
2 files changed, 36 insertions, 14 deletions
diff --git a/connectivity/source/drivers/firebird/PreparedStatement.cxx b/connectivity/source/drivers/firebird/PreparedStatement.cxx index 737875e96b5a..69ce91f42da1 100644 --- a/connectivity/source/drivers/firebird/PreparedStatement.cxx +++ b/connectivity/source/drivers/firebird/PreparedStatement.cxx @@ -420,34 +420,44 @@ void SAL_CALL OPreparedStatement::setDouble(sal_Int32 nIndex, double nValue) ensurePrepared(); XSQLVAR* pVar = m_pInSqlda->sqlvar + (nIndex - 1); - int dType = (pVar->sqltype & ~1); // drop flag bit for now - - // take decimal places into account, later on they are removed in makeNumericString - // minus because firebird stores scale as a negative number - int nDecimalCount = -pVar->sqlscale; - sal_Int64 nDecimalCountExp = pow10Integer(nDecimalCount); - - nValue = static_cast<double>(nValue * nDecimalCountExp); + short dType = (pVar->sqltype & ~1); // drop flag bit for now + short dSubType = pVar->sqlsubtype; + // Assume it is a sub type of a number. + if(dSubType < 0 || dSubType > 2) + { + ::dbtools::throwSQLException( + "Incorrect number sub type", + ::dbtools::StandardSQLState::INVALID_SQL_DATA_TYPE, + *this); + } + // firebird stores scale as a negative number + ColumnTypeInfo columnType{ dType, dSubType, + static_cast<short>(-pVar->sqlscale) }; // Caller might try to set an integer type here. It makes sense to convert // it instead of throwing an error. - switch(dType) + switch(columnType.getSdbcType()) { - case SQL_SHORT: + case DataType::SMALLINT: setValue< sal_Int16 >(nIndex, static_cast<sal_Int16>(nValue), dType); break; - case SQL_LONG: + case DataType::INTEGER: setValue< sal_Int32 >(nIndex, static_cast<sal_Int32>(nValue), dType); break; - case SQL_INT64: + case DataType::BIGINT: setValue< sal_Int64 >(nIndex, static_cast<sal_Int64>(nValue), dType); break; + case DataType::NUMERIC: + case DataType::DECIMAL: + // take decimal places into account, later on they are removed in makeNumericString + setObjectWithInfo(nIndex,Any{nValue}, columnType.getSdbcType(), columnType.getScale()); + break; default: setValue< double >(nIndex, nValue, SQL_DOUBLE); // TODO: SQL_D_FLOAT? } diff --git a/connectivity/source/drivers/firebird/Util.hxx b/connectivity/source/drivers/firebird/Util.hxx index 26929a9de162..f380ab6caab5 100644 --- a/connectivity/source/drivers/firebird/Util.hxx +++ b/connectivity/source/drivers/firebird/Util.hxx @@ -34,8 +34,10 @@ namespace connectivity Image = -9546 }; - // Numeric and decimal types can be identified by their subtype - // 1 for NUMERIC, 2 for DECIMAL + /** + * Numeric and decimal types can be identified by their subtype in + * Firebird API. 1 for NUMERIC, 2 for DECIMAL. + */ enum class NumberSubType { Other = 0, Numeric = 1, @@ -49,6 +51,16 @@ private: short m_nScale; OUString m_sCharsetName; public: + /** + * @param tType SQL type of column defined by Firebird (e.g. + * SQL_DOUBLE) + * @param aSubType SQL sub type as in firebird API. See + * NumberSubType. + * @param scale: Scale of the number. It is ignored in case it's not + * a number. Scale obtained from the Firebird API is negative, so + * that should be negated before passing to this constructor. + * + */ explicit ColumnTypeInfo( short aType, short aSubType = 0, short nScale = 0, const OUString& sCharset = OUString() ) : m_aType(aType) |