summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTamás Bunth <btomi96@gmail.com>2017-01-29 14:26:16 +0100
committerTamás Bunth <btomi96@gmail.com>2017-01-30 14:57:40 +0000
commit4a193d39fb785c75668c977cf6b40d11b0ef4afe (patch)
tree626c25dc18f925d948b67c2e9eedf392837cd057
parenttdf#105548 fix incorrect DATEDIF result. (diff)
downloadcore-4a193d39fb785c75668c977cf6b40d11b0ef4afe.tar.gz
core-4a193d39fb785c75668c977cf6b40d11b0ef4afe.zip
tdf#105101 check scale to determine subtype
For computed decimal/numeric values firebird's subtype remains 0. In this case we check for the scale of column. If it is not 0 (negative), than imply numeric. Change-Id: Ie5a023d165852fe402b3b4cac817b0bbef58e7cd Reviewed-on: https://gerrit.libreoffice.org/33660 Reviewed-by: Lionel Elie Mamane <lionel@mamane.lu> Tested-by: Tamás Bunth <btomi96@gmail.com>
-rw-r--r--connectivity/source/drivers/firebird/DatabaseMetaData.cxx35
-rw-r--r--connectivity/source/drivers/firebird/ResultSet.cxx15
-rw-r--r--connectivity/source/drivers/firebird/ResultSetMetaData.cxx6
-rw-r--r--connectivity/source/drivers/firebird/Util.cxx16
-rw-r--r--connectivity/source/drivers/firebird/Util.hxx4
5 files changed, 49 insertions, 27 deletions
diff --git a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
index 66d9783ba9cd..e773e09b41eb 100644
--- a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
+++ b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
@@ -857,7 +857,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
// SQL_TEXT
aRow[1] = new ORowSetValueDecorator(OUString("CHAR"));
- aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TEXT, 0));
+ aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TEXT, 0, 0));
aRow[3] = new ORowSetValueDecorator(sal_Int16(32765)); // Prevision = max length
aRow[6] = new ORowSetValueDecorator(OUString("length")); // Create Params
aRow[9] = new ORowSetValueDecorator(
@@ -869,7 +869,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
// SQL_VARYING
aRow[1] = new ORowSetValueDecorator(OUString("VARCHAR"));
- aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_VARYING, 0));
+ aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_VARYING, 0, 0));
aRow[3] = new ORowSetValueDecorator(sal_Int16(32765)); // Prevision = max length
aRow[6] = new ORowSetValueDecorator(OUString("length")); // Create Params
aRow[9] = new ORowSetValueDecorator(
@@ -890,17 +890,17 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
}
// SQL_SHORT
aRow[1] = new ORowSetValueDecorator(OUString("SMALLINT"));
- aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_SHORT, 0));
+ aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_SHORT, 0, 0));
aRow[3] = new ORowSetValueDecorator(sal_Int16(5)); // Prevision
aResults.push_back(aRow);
// SQL_LONG
aRow[1] = new ORowSetValueDecorator(OUString("INTEGER"));
- aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_LONG, 0));
+ aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_LONG, 0, 0));
aRow[3] = new ORowSetValueDecorator(sal_Int16(10)); // Precision
aResults.push_back(aRow);
// SQL_INT64
aRow[1] = new ORowSetValueDecorator(OUString("BIGINT"));
- aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_INT64, 0));
+ aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_INT64, 0, 0));
aRow[3] = new ORowSetValueDecorator(sal_Int16(20)); // Precision
aResults.push_back(aRow);
@@ -930,22 +930,22 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
aRow[6] = new ORowSetValueDecorator(); // Create Params
// SQL_FLOAT
aRow[1] = new ORowSetValueDecorator(OUString("FLOAT"));
- aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_FLOAT, 0));
+ aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_FLOAT, 0, 0));
aRow[3] = new ORowSetValueDecorator(sal_Int16(7)); // Precision
aRow[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
aRow[15] = new ORowSetValueDecorator(sal_Int16(7)); // Max scale
aResults.push_back(aRow);
// SQL_DOUBLE
aRow[1] = new ORowSetValueDecorator(OUString("DOUBLE PRECISION"));
- aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_DOUBLE, 0));
+ aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_DOUBLE, 0, 0));
aRow[3] = new ORowSetValueDecorator(sal_Int16(15)); // Precision
aRow[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
aRow[15] = new ORowSetValueDecorator(sal_Int16(15)); // Max scale
aResults.push_back(aRow);
// // SQL_D_FLOAT
-// aRow[1] = new ORowSetValueDecorator(getColumnTypeNameFromFBType(SQL_D_FLOAT, 0));
-// aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_D_FLOAT, 0));
+// aRow[1] = new ORowSetValueDecorator(getColumnTypeNameFromFBType(SQL_D_FLOAT, 0, 0));
+// aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_D_FLOAT, 0, 0));
// aRow[3] = new ORowSetValueDecorator(sal_Int16(15)); // Precision
// aRow[14] = new ORowSetValueDecorator(sal_Int16(1)); // Minimum scale
// aRow[15] = new ORowSetValueDecorator(sal_Int16(15)); // Max scale
@@ -955,7 +955,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
// SQL_TIMESTAMP
// TODO: precision?
aRow[1] = new ORowSetValueDecorator(OUString("TIMESTAMP"));
- aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TIMESTAMP, 0));
+ aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TIMESTAMP, 0, 0));
aRow[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
aRow[6] = new ORowSetValueDecorator(); // Create Params
aRow[9] = new ORowSetValueDecorator(
@@ -968,7 +968,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
// SQL_TYPE_TIME
// TODO: precision?
aRow[1] = new ORowSetValueDecorator(OUString("TIME"));
- aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TYPE_TIME, 0));
+ aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TYPE_TIME, 0, 0));
aRow[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
aRow[6] = new ORowSetValueDecorator(); // Create Params
aRow[9] = new ORowSetValueDecorator(
@@ -981,7 +981,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
// SQL_TYPE_DATE
// TODO: precision?
aRow[1] = new ORowSetValueDecorator(OUString("DATE"));
- aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TYPE_DATE, 0));
+ aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_TYPE_DATE, 0, 0));
aRow[3] = new ORowSetValueDecorator(sal_Int32(8)); // Prevision = max length
aRow[6] = new ORowSetValueDecorator(); // Create Params
aRow[9] = new ORowSetValueDecorator(
@@ -994,7 +994,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
// SQL_BLOB
// TODO: precision?
aRow[1] = new ORowSetValueDecorator(OUString("BLOB"));
- aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_BLOB, 0));
+ aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_BLOB, 0, 0));
aRow[3] = new ORowSetValueDecorator(sal_Int32(0)); // Prevision = max length
aRow[6] = new ORowSetValueDecorator(); // Create Params
aRow[9] = new ORowSetValueDecorator(
@@ -1007,7 +1007,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo()
// SQL_BOOLEAN
// TODO FIXME precision
aRow[1] = new ORowSetValueDecorator(OUString("BOOLEAN"));
- aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_BOOLEAN, 0));
+ aRow[2] = new ORowSetValueDecorator(getColumnTypeFromFBType(SQL_BOOLEAN, 0, 0));
aRow[3] = new ORowSetValueDecorator(sal_Int32(1)); // Prevision = max length
aRow[6] = new ORowSetValueDecorator(); // Create Params
aRow[9] = new ORowSetValueDecorator(
@@ -1180,9 +1180,10 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumns(
// 5. Datatype
short aType = getFBTypeFromBlrType(xRow->getShort(6));
short aSubType = xRow->getShort(7);
- aCurrentRow[5] = new ORowSetValueDecorator(getColumnTypeFromFBType(aType, aSubType));
+ short aScale = xRow->getShort(10);
+ aCurrentRow[5] = new ORowSetValueDecorator(getColumnTypeFromFBType(aType, aSubType, aScale));
// 6. Typename (SQL_*)
- aCurrentRow[6] = new ORowSetValueDecorator(getColumnTypeNameFromFBType(aType, aSubType));
+ aCurrentRow[6] = new ORowSetValueDecorator(getColumnTypeNameFromFBType(aType, aSubType, aScale));
// 7. Column Sizes
{
@@ -1216,7 +1217,7 @@ uno::Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumns(
// 9. Decimal digits (scale)
// fb stores a negative number
- aCurrentRow[9] = new ORowSetValueDecorator( (sal_Int16) -(xRow->getShort(10)) );
+ aCurrentRow[9] = new ORowSetValueDecorator( (sal_Int16) -(aScale) );
// 11. Nullable
if (xRow->getShort(11))
diff --git a/connectivity/source/drivers/firebird/ResultSet.cxx b/connectivity/source/drivers/firebird/ResultSet.cxx
index 4aebf25e810a..fb3e72675fab 100644
--- a/connectivity/source/drivers/firebird/ResultSet.cxx
+++ b/connectivity/source/drivers/firebird/ResultSet.cxx
@@ -447,6 +447,13 @@ ORowSetValue OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_S
// Basically we just have to map to the correct direct request and
// ORowSetValue does the rest for us here.
int nSqlSubType = m_pSqlda->sqlvar[nColumnIndex-1].sqlsubtype;
+
+ // TODO Firebird 3.0 does not set subtype (i.e. set to 0) for computed numeric/decimal value.
+ // It may change in the future.
+ // Imply numeric data type when subtype is 0 and scale is negative
+ if( nSqlSubType == 0 && m_pSqlda->sqlvar[nColumnIndex-1].sqlscale < 0 )
+ nSqlSubType = 1;
+
switch (m_pSqlda->sqlvar[nColumnIndex-1].sqltype & ~1)
{
case SQL_TEXT:
@@ -577,9 +584,11 @@ OUString OResultSet::retrieveValue(const sal_Int32 nColumnIndex, const ISC_SHORT
aLength,
RTL_TEXTENCODING_UTF8);
}
- else if ((aSqlType == SQL_SHORT || aSqlType == SQL_LONG
- || aSqlType == SQL_DOUBLE || aSqlType == SQL_INT64)
- && (aSqlSubType == 1 || aSqlSubType == 2))
+ else if ((aSqlType == SQL_SHORT || aSqlType == SQL_LONG ||
+ aSqlType == SQL_DOUBLE || aSqlType == SQL_INT64)
+ && (aSqlSubType == 1 ||
+ aSqlSubType == 2 ||
+ (aSqlSubType == 0 && m_pSqlda->sqlvar[nColumnIndex-1].sqlscale < 0) ) )
{
// decimal and numeric types
switch(aSqlType)
diff --git a/connectivity/source/drivers/firebird/ResultSetMetaData.cxx b/connectivity/source/drivers/firebird/ResultSetMetaData.cxx
index 79262d8f1d70..498bbaee3087 100644
--- a/connectivity/source/drivers/firebird/ResultSetMetaData.cxx
+++ b/connectivity/source/drivers/firebird/ResultSetMetaData.cxx
@@ -62,8 +62,9 @@ sal_Int32 SAL_CALL OResultSetMetaData::getColumnType(sal_Int32 column)
short aType = m_pSqlda->sqlvar[column-1].sqltype;
short aSubType = m_pSqlda->sqlvar[column-1].sqlsubtype;
+ short aScale = m_pSqlda->sqlvar[column-1].sqlscale;
- return getColumnTypeFromFBType(aType, aSubType);
+ return getColumnTypeFromFBType(aType, aSubType, aScale);
}
sal_Bool SAL_CALL OResultSetMetaData::isCaseSensitive(sal_Int32 column)
@@ -113,8 +114,9 @@ OUString SAL_CALL OResultSetMetaData::getColumnTypeName(sal_Int32 column)
short aType = m_pSqlda->sqlvar[column-1].sqltype;
short aSubType = m_pSqlda->sqlvar[column-1].sqlsubtype;
+ short aScale = m_pSqlda->sqlvar[column-1].sqlscale;
- return getColumnTypeNameFromFBType(aType, aSubType);
+ return getColumnTypeNameFromFBType(aType, aSubType, aScale);
}
OUString SAL_CALL OResultSetMetaData::getColumnLabel(sal_Int32 column)
diff --git a/connectivity/source/drivers/firebird/Util.cxx b/connectivity/source/drivers/firebird/Util.cxx
index bd84bba0c9a9..e30a7a9b41f8 100644
--- a/connectivity/source/drivers/firebird/Util.cxx
+++ b/connectivity/source/drivers/firebird/Util.cxx
@@ -64,10 +64,15 @@ void firebird::evaluateStatusVector(const ISC_STATUS_ARRAY& rStatusVector,
}
}
-sal_Int32 firebird::getColumnTypeFromFBType(short aType, short aSubType)
+sal_Int32 firebird::getColumnTypeFromFBType(short aType, short aSubType, short aScale)
{
aType &= ~1; // Remove last bit -- it is used to denote whether column
// can store Null, not needed for type determination
+
+ // if scale is set without subtype then imply numeric
+ if(aSubType == 0 && aScale < 0)
+ aSubType = 1;
+
switch (aType)
{
case SQL_TEXT:
@@ -134,11 +139,16 @@ sal_Int32 firebird::getColumnTypeFromFBType(short aType, short aSubType)
}
}
-OUString firebird::getColumnTypeNameFromFBType(short aType, short aSubType)
+OUString firebird::getColumnTypeNameFromFBType(short aType, short aSubType, short aScale)
{
aType &= ~1; // Remove last bit -- it is used to denote whether column
// can store Null, not needed for type determination
- switch (aType)
+
+ // if scale is set without subtype than imply numeric
+ if(aSubType == 0 && aScale < 0)
+ aSubType = 1;
+
+ switch (aType)
{
case SQL_TEXT:
return OUString("SQL_TEXT");
diff --git a/connectivity/source/drivers/firebird/Util.hxx b/connectivity/source/drivers/firebird/Util.hxx
index b37b8718e9b8..dd0faf720b52 100644
--- a/connectivity/source/drivers/firebird/Util.hxx
+++ b/connectivity/source/drivers/firebird/Util.hxx
@@ -62,8 +62,8 @@ namespace connectivity
const ::rtl::OUString& aCause,
const css::uno::Reference< css::uno::XInterface >& _rxContext);
- sal_Int32 getColumnTypeFromFBType(short aType, short aSubType);
- ::rtl::OUString getColumnTypeNameFromFBType(short aType, short aSubType);
+ sal_Int32 getColumnTypeFromFBType(short aType, short aSubType, short aScale);
+ ::rtl::OUString getColumnTypeNameFromFBType(short aType, short aSubType, short aScale);
/**
* Internally (i.e. in RDB$FIELD_TYPE) firebird stores the data type