[Libreoffice-commits] core.git: connectivity/source

Tamás Bunth btomi96 at gmail.com
Mon Jan 30 14:58:13 UTC 2017


 connectivity/source/drivers/firebird/DatabaseMetaData.cxx  |   35 ++++++-------
 connectivity/source/drivers/firebird/ResultSet.cxx         |   15 ++++-
 connectivity/source/drivers/firebird/ResultSetMetaData.cxx |    6 +-
 connectivity/source/drivers/firebird/Util.cxx              |   16 ++++-
 connectivity/source/drivers/firebird/Util.hxx              |    4 -
 5 files changed, 49 insertions(+), 27 deletions(-)

New commits:
commit 4a193d39fb785c75668c977cf6b40d11b0ef4afe
Author: Tamás Bunth <btomi96 at gmail.com>
Date:   Sun Jan 29 14:26:16 2017 +0100

    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 at mamane.lu>
    Tested-by: Tamás Bunth <btomi96 at gmail.com>

diff --git a/connectivity/source/drivers/firebird/DatabaseMetaData.cxx b/connectivity/source/drivers/firebird/DatabaseMetaData.cxx
index 66d9783..e773e09 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 4aebf25..fb3e726 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 79262d8..498bbae 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 bd84bba..e30a7a9 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 b37b871..dd0faf7 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


More information about the Libreoffice-commits mailing list