[Libreoffice-commits] .: Branch 'libreoffice-3-5' - 2 commits - dbaccess/source

Lionel Elie Mamane lmamane at kemper.freedesktop.org
Wed Jan 18 04:17:38 PST 2012


 dbaccess/source/core/api/CacheSet.cxx      |    2 
 dbaccess/source/core/api/KeySet.cxx        |   85 +++++++++++++++++++----------
 dbaccess/source/core/api/KeySet.hxx        |    5 +
 dbaccess/source/core/api/OptimisticSet.cxx |    2 
 4 files changed, 65 insertions(+), 29 deletions(-)

New commits:
commit dfcf55a9de3cc928e5612117d0f9f5f3783de2ff
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date:   Wed Jan 18 12:30:36 2012 +0100

    fdo#44813: make the refresh query filter NULL-safe

diff --git a/dbaccess/source/core/api/KeySet.cxx b/dbaccess/source/core/api/KeySet.cxx
index 17789ff..b41e68b 100644
--- a/dbaccess/source/core/api/KeySet.cxx
+++ b/dbaccess/source/core/api/KeySet.cxx
@@ -223,22 +223,56 @@ void OKeySet::findTableColumnsMatching_throw(   const Any& i_aTable,
 }
 SAL_WNODEPRECATED_DECLARATIONS_POP
 
+namespace
+{
+    void appendOneKeyColumnClause( const ::rtl::OUString &tblName, const ::rtl::OUString &colName, ::rtl::OUStringBuffer &o_buf )
+    {
+        static ::rtl::OUString s_sDot(RTL_CONSTASCII_USTRINGPARAM("."));
+        static ::rtl::OUString s_sParam0(RTL_CONSTASCII_USTRINGPARAM(" ( TRUE = ? AND "));
+        static ::rtl::OUString s_sParam1(RTL_CONSTASCII_USTRINGPARAM(" = ? OR TRUE = ? AND "));
+        static ::rtl::OUString s_sParam2(RTL_CONSTASCII_USTRINGPARAM(" IS NULL ) "));
+        o_buf.append(s_sParam0);
+        o_buf.append(tblName);
+        o_buf.append(s_sDot);
+        o_buf.append(colName);
+        o_buf.append(s_sParam1);
+        o_buf.append(tblName);
+        o_buf.append(s_sDot);
+        o_buf.append(colName);
+        o_buf.append(s_sParam2);
+    }
+}
+
+void OKeySet::setOneKeyColumnParameter( sal_Int32 &nPos, const Reference< XParameters > &_xParameter, const connectivity::ORowSetValue &_rValue, sal_Int32 _nType, sal_Int32 _nScale ) const
+{
+    if ( _rValue.isNull() )
+    {
+        _xParameter->setBoolean( nPos++, false );
+        // We do the full call so that the right sqlType is passed to setNull
+        setParameter( nPos++, _xParameter, _rValue, _nType, _nScale );
+        _xParameter->setBoolean( nPos++, true );
+    }
+    else
+    {
+        _xParameter->setBoolean( nPos++, true );
+        setParameter( nPos++, _xParameter, _rValue, _nType, _nScale );
+        _xParameter->setBoolean( nPos++, false );
+    }
+}
+
 ::rtl::OUStringBuffer OKeySet::createKeyFilter()
 {
     static ::rtl::OUString aAnd(RTL_CONSTASCII_USTRINGPARAM(" AND "));
     const ::rtl::OUString aQuote    = getIdentifierQuoteString();
     ::rtl::OUStringBuffer aFilter;
-    static ::rtl::OUString s_sDot(RTL_CONSTASCII_USTRINGPARAM("."));
-    static ::rtl::OUString s_sParam(RTL_CONSTASCII_USTRINGPARAM(" = ?"));
     // create the where clause
     Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
     SelectColumnsMetaData::iterator aPosEnd = m_pKeyColumnNames->end();
     for(SelectColumnsMetaData::iterator aPosIter = m_pKeyColumnNames->begin();aPosIter != aPosEnd;)
     {
-        aFilter.append(::dbtools::quoteTableName( xMeta,aPosIter->second.sTableName,::dbtools::eInDataManipulation));
-        aFilter.append(s_sDot);
-        aFilter.append(::dbtools::quoteName( aQuote,aPosIter->second.sRealName));
-        aFilter.append(s_sParam);
+        appendOneKeyColumnClause(::dbtools::quoteTableName( xMeta,aPosIter->second.sTableName,::dbtools::eInDataManipulation),
+                                 ::dbtools::quoteName( aQuote,aPosIter->second.sRealName),
+                                 aFilter);
         ++aPosIter;
         if(aPosIter != aPosEnd)
             aFilter.append(aAnd);
@@ -276,8 +310,6 @@ void OKeySet::construct(const Reference< XResultSet>& _xDriverSet,const ::rtl::O
     {
         static ::rtl::OUString aAnd(RTL_CONSTASCII_USTRINGPARAM(" AND "));
         const ::rtl::OUString aQuote    = getIdentifierQuoteString();
-        static ::rtl::OUString s_sDot(RTL_CONSTASCII_USTRINGPARAM("."));
-        static ::rtl::OUString s_sParam(RTL_CONSTASCII_USTRINGPARAM(" = ?"));
         const ::rtl::OUString* pIter = aSeq.getConstArray();
         const ::rtl::OUString* pEnd   = pIter + aSeq.getLength();
         for(;pIter != pEnd;++pIter)
@@ -294,12 +326,11 @@ void OKeySet::construct(const Reference< XResultSet>& _xDriverSet,const ::rtl::O
                 for(SelectColumnsMetaData::iterator aPosIter = (*m_pForeignColumnNames).begin();aPosIter != aPosEnd;++aPosIter)
                 {
                     // look for columns not in the source columns to use them as filter as well
-                        if ( aFilter.getLength() )
-                            aFilter.append(aAnd);
-                        aFilter.append(::dbtools::quoteName( aQuote,sSelectTableName));
-                        aFilter.append(s_sDot);
-                        aFilter.append(::dbtools::quoteName( aQuote,aPosIter->second.sRealName));
-                        aFilter.append(s_sParam);
+                    if ( aFilter.getLength() )
+                        aFilter.append(aAnd);
+                    appendOneKeyColumnClause(::dbtools::quoteName( aQuote,sSelectTableName),
+                                             ::dbtools::quoteName( aQuote,aPosIter->second.sRealName),
+                                             aFilter);
                 }
                 break;
             }
@@ -879,12 +910,12 @@ void OKeySet::tryRefetch(const ORowSetRow& _rInsertRow,bool bRefetch)
             connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aIter2 = m_aKeyIter->second.first->get().begin();
             SelectColumnsMetaData::const_iterator aPosIter = (*m_pKeyColumnNames).begin();
             SelectColumnsMetaData::const_iterator aPosEnd = (*m_pKeyColumnNames).end();
-            for(;aPosIter != aPosEnd;++aPosIter,++aIter2,++nPos)
-                setParameter(nPos,xParameter,*aIter2,aPosIter->second.nType,aPosIter->second.nScale);
+            for(;aPosIter != aPosEnd;++aPosIter,++aIter2)
+                setOneKeyColumnParameter(nPos,xParameter,*aIter2,aPosIter->second.nType,aPosIter->second.nScale);
             aPosIter = (*m_pForeignColumnNames).begin();
             aPosEnd = (*m_pForeignColumnNames).end();
-            for(;aPosIter != aPosEnd;++aPosIter,++aIter2,++nPos)
-                setParameter(nPos,xParameter,*aIter2,aPosIter->second.nType,aPosIter->second.nScale);
+            for(;aPosIter != aPosEnd;++aPosIter,++aIter2)
+                setOneKeyColumnParameter(nPos,xParameter,*aIter2,aPosIter->second.nType,aPosIter->second.nScale);
 
             m_xSet = m_xStatement->executeQuery();
             OSL_ENSURE(m_xSet.is(),"No resultset form statement!");
@@ -1340,12 +1371,12 @@ void SAL_CALL OKeySet::refreshRow() throw(SQLException, RuntimeException)
     connectivity::ORowVector< ORowSetValue >::Vector::const_iterator aIter = m_aKeyIter->second.first->get().begin();
     SelectColumnsMetaData::const_iterator aPosIter = (*m_pKeyColumnNames).begin();
     SelectColumnsMetaData::const_iterator aPosEnd = (*m_pKeyColumnNames).end();
-    for(;aPosIter != aPosEnd;++aPosIter,++aIter,++nPos)
-        setParameter(nPos,xParameter,*aIter,aPosIter->second.nType,aPosIter->second.nScale);
+    for(;aPosIter != aPosEnd;++aPosIter,++aIter)
+        setOneKeyColumnParameter(nPos,xParameter,*aIter,aPosIter->second.nType,aPosIter->second.nScale);
     aPosIter = (*m_pForeignColumnNames).begin();
     aPosEnd = (*m_pForeignColumnNames).end();
-    for(;aPosIter != aPosEnd;++aPosIter,++aIter,++nPos)
-        setParameter(nPos,xParameter,*aIter,aPosIter->second.nType,aPosIter->second.nScale);
+    for(;aPosIter != aPosEnd;++aPosIter,++aIter)
+        setOneKeyColumnParameter(nPos,xParameter,*aIter,aPosIter->second.nType,aPosIter->second.nScale);
 
     m_xSet = m_xStatement->executeQuery();
     OSL_ENSURE(m_xSet.is(),"No resultset form statement!");
diff --git a/dbaccess/source/core/api/KeySet.hxx b/dbaccess/source/core/api/KeySet.hxx
index 30afda2..196f159 100644
--- a/dbaccess/source/core/api/KeySet.hxx
+++ b/dbaccess/source/core/api/KeySet.hxx
@@ -143,6 +143,11 @@ namespace dbaccess
                                              const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>& i_xQueryColumns,
                                              ::std::auto_ptr<SelectColumnsMetaData>& o_pKeyColumnNames);
         SAL_WNODEPRECATED_DECLARATIONS_POP
+        void setOneKeyColumnParameter( sal_Int32 &nPos,
+                                       const ::com::sun::star::uno::Reference<  ::com::sun::star::sdbc::XParameters > &_xParameter,
+                                       const connectivity::ORowSetValue &_rValue,
+                                       sal_Int32 _nType,
+                                       sal_Int32 _nScale ) const;
         ::rtl::OUStringBuffer createKeyFilter();
         void tryRefetch(const ORowSetRow& _rInsertRow,bool bRefetch);
         void executeUpdate(const ORowSetRow& _rInsertRow ,const ORowSetRow& _rOrginalRow,const ::rtl::OUString& i_sSQL,const ::rtl::OUString& i_sTableName,const ::std::vector<sal_Int32>& _aIndexColumnPositions = ::std::vector<sal_Int32>());
commit ee1510922d7d0c5b8e111437d933078a62eda4b4
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date:   Mon Jan 16 19:38:01 2012 +0100

    fdo#44813: don't replace NULLs given by the database by type-default values
    
    It makes no sense, because non-nullable columns can have NULL value.
    E.g. in "foo LEFT JOIN bar ON condition", the non-nullable columns of "bar"
    when it has no row matching "condition".
    
    Even when we are about to insert/update a row, we should not put a
    hard-coded value (that just happens to be the one constructed by the
    C++ default constructor for that type) in non-nullable columns: there
    is no guarantee that this value makes sense in that database's context.
    The database may or may not have a default value set for that column.
    If it has, we should leave it up to the database to set it automatically.
    If it has not, an error *is* the right reaction.
    
    Another place where this substitution does damage is when we refresh a
    row. We use the values we have read from the primary key to select the
    row again. So we should not mangle those, else the select returns no
    row and we mistakingly think the row has been deleted.

diff --git a/dbaccess/source/core/api/CacheSet.cxx b/dbaccess/source/core/api/CacheSet.cxx
index 6f065d7..0b46c7a 100644
--- a/dbaccess/source/core/api/CacheSet.cxx
+++ b/dbaccess/source/core/api/CacheSet.cxx
@@ -427,7 +427,7 @@ void OCacheSet::fillValueRow(ORowSetRow& _rRow,sal_Int32 _nPosition)
     for(sal_Int32 i=1;aIter != aEnd;++aIter,++i)
     {
         aIter->setSigned(m_aSignedFlags[i-1]);
-        aIter->fill(i,m_aColumnTypes[i-1],m_aNullable[i-1],this);
+        aIter->fill(i, m_aColumnTypes[i-1], this);
     }
 }
 
diff --git a/dbaccess/source/core/api/KeySet.cxx b/dbaccess/source/core/api/KeySet.cxx
index 92d0d50..17789ff 100644
--- a/dbaccess/source/core/api/KeySet.cxx
+++ b/dbaccess/source/core/api/KeySet.cxx
@@ -762,7 +762,7 @@ void OKeySet::executeInsert( const ORowSetRow& _rInsertRow,const ::rtl::OUString
 #endif
                         SelectColumnsMetaData::iterator aFind = m_pKeyColumnNames->find(*aAutoIter);
                         if ( aFind != m_pKeyColumnNames->end() )
-                            (_rInsertRow->get())[aFind->second.nPosition].fill(i,aFind->second.nType,aFind->second.bNullable,xRow);
+                            (_rInsertRow->get())[aFind->second.nPosition].fill(i, aFind->second.nType, xRow);
                     }
                     bAutoValuesFetched = sal_True;
                 }
@@ -822,7 +822,7 @@ void OKeySet::executeInsert( const ORowSetRow& _rInsertRow,const ::rtl::OUString
                         // we will only fetch values which are keycolumns
                         SelectColumnsMetaData::iterator aFind = m_pKeyColumnNames->find(*aAutoIter);
                         if ( aFind != aEnd )
-                            (_rInsertRow->get())[aFind->second.nPosition].fill(i,aFind->second.nType,aFind->second.bNullable,xRow);
+                            (_rInsertRow->get())[aFind->second.nPosition].fill(i, aFind->second.nType, xRow);
                     }
                 }
                 ::comphelper::disposeComponent(xStatement);
@@ -1376,13 +1376,13 @@ sal_Bool OKeySet::fetchRow()
     {
         ORowSetRow aKeyRow = new connectivity::ORowVector< ORowSetValue >((*m_pKeyColumnNames).size() + m_pForeignColumnNames->size());
         connectivity::ORowVector< ORowSetValue >::Vector::iterator aIter = aKeyRow->get().begin();
-        // first fetch the values needed for the key column
+        // first fetch the values needed for the key columns
         SelectColumnsMetaData::const_iterator aPosIter = (*m_pKeyColumnNames).begin();
         SelectColumnsMetaData::const_iterator aPosEnd = (*m_pKeyColumnNames).end();
         for(;aPosIter != aPosEnd;++aPosIter,++aIter)
         {
             const SelectColumnDescription& rColDesc = aPosIter->second;
-            aIter->fill(rColDesc.nPosition,rColDesc.nType,rColDesc.bNullable,m_xDriverRow);
+            aIter->fill(rColDesc.nPosition, rColDesc.nType, m_xDriverRow);
         }
         // now fetch the values from the missing columns from other tables
         aPosIter = (*m_pForeignColumnNames).begin();
@@ -1390,7 +1390,7 @@ sal_Bool OKeySet::fetchRow()
         for(;aPosIter != aPosEnd;++aPosIter,++aIter)
         {
             const SelectColumnDescription& rColDesc = aPosIter->second;
-            aIter->fill(rColDesc.nPosition,rColDesc.nType,rColDesc.bNullable,m_xDriverRow);
+            aIter->fill(rColDesc.nPosition, rColDesc.nType, m_xDriverRow);
         }
         m_aKeyIter = m_aKeyMap.insert(OKeySetMatrix::value_type(m_aKeyMap.rbegin()->first+1,OKeySetValue(aKeyRow,::std::pair<sal_Int32,Reference<XRow> >(0,NULL)))).first;
     }
diff --git a/dbaccess/source/core/api/OptimisticSet.cxx b/dbaccess/source/core/api/OptimisticSet.cxx
index 1d11414..f7b97ed 100644
--- a/dbaccess/source/core/api/OptimisticSet.cxx
+++ b/dbaccess/source/core/api/OptimisticSet.cxx
@@ -725,7 +725,7 @@ void OptimisticSet::fillMissingValues(ORowSetValueVector::Vector& io_aRow) const
                         {
                             if ( aColIter->second.sTableName == aSqlIter->first )
                             {
-                                io_aRow[aColIter->second.nPosition].fill(i++,aColIter->second.nType,aColIter->second.bNullable,xRow);
+                                io_aRow[aColIter->second.nPosition].fill(i++, aColIter->second.nType, xRow);
                                 io_aRow[aColIter->second.nPosition].setModified();
                             }
                         }


More information about the Libreoffice-commits mailing list