summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--connectivity/source/drivers/firebird/PreparedStatement.cxx34
-rw-r--r--connectivity/source/drivers/firebird/Util.hxx16
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)