sc/inc/formulagroup.hxx              |    2 ++
 sc/source/core/data/column2.cxx      |   14 ++++++++++++++
 sc/source/core/tool/formulagroup.cxx |    7 +++++++
 3 files changed, 23 insertions(+)

New commits:
commit 8af5cb7870032fbdb50f0b3ad6d855e488af4b99
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Tue Jul 24 12:47:26 2018 +0200
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Fri Jul 27 09:43:30 2018 +0200

    do not keep incorrect calc values in the cache
    
    All these calls first entered the whole array into the cache and
    only then filled it up with values. If that failed, the values
    stayed in the cache and could be reused by something else.
    Testcase is sc/qa/.../linest.fods, where the error in X19 prevents
    caching of that column for the formula in AA24:AA28. Since currently
    ScFormulaCell::InterpretFormulaGroup() calls InterpretFormulaGroupOpenCL()
    twice, the first ScGroupTokenConverter::convert() call cached
    the incomplete column and then failed, and the second call simply reused
    the value. But this could presumably happen for multiple formulas using
    data in the same column as well, even without the double call.
    
    Change-Id: Iaa55671936fe61f72dfa35940db8deaf27d1c22d
    Reviewed-on: https://gerrit.libreoffice.org/57912
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx
index f0dcb4888a72..db37426df05f 100644
--- a/sc/inc/formulagroup.hxx
+++ b/sc/inc/formulagroup.hxx
@@ -94,6 +94,8 @@ struct FormulaGroupContext
     ColArray* setCachedColArray(
         SCTAB nTab, SCCOL nCol, NumArrayType* pNumArray, StrArrayType* 
pStrArray );
 
+    void discardCachedColArray(SCTAB nTab, SCCOL nCol);
+
     void ensureStrArray( ColArray& rColArray, size_t nArrayLen );
     void ensureNumArray( ColArray& rColArray, size_t nArrayLen );
 
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 21f38f54711d..183a219f1f4a 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2711,7 +2711,10 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( 
SCROW nRow1, SCROW nRow2
             size_t nPos = itBlk->size;
             ++itBlk;
             if (!appendToBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, 
itBlk, maCells.end()))
+            {
+                rCxt.discardCachedColArray(nTab, nCol);
                 return 
formula::VectorRefArray(formula::VectorRefArray::Invalid);
+            }
 
             rtl_uString** pStr = nullptr;
             if (pColArray->mpStrArray && hasNonEmpty(*pColArray->mpStrArray, 
nRow1, nRow2))
@@ -2744,7 +2747,10 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( 
SCROW nRow1, SCROW nRow2
             size_t nPos = itBlk->size;
             ++itBlk;
             if (!appendToBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, 
itBlk, maCells.end()))
+            {
+                rCxt.discardCachedColArray(nTab, nCol);
                 return 
formula::VectorRefArray(formula::VectorRefArray::Invalid);
+            }
 
             assert(pColArray->mpStrArray);
 
@@ -2781,13 +2787,18 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( 
SCROW nRow1, SCROW nRow2
 
             pColArray = copyFirstFormulaBlock(rCxt, itBlk, nRow2+1, nTab, 
nCol);
             if (!pColArray)
+            {
                 // Failed to insert a new cached column array.
                 return 
formula::VectorRefArray(formula::VectorRefArray::Invalid);
+            }
 
             size_t nPos = itBlk->size;
             ++itBlk;
             if (!appendToBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, 
itBlk, maCells.end()))
+            {
+                rCxt.discardCachedColArray(nTab, nCol);
                 return 
formula::VectorRefArray(formula::VectorRefArray::Invalid);
+            }
 
             const double* pNum = nullptr;
             rtl_uString** pStr = nullptr;
@@ -2817,7 +2828,10 @@ formula::VectorRefArray ScColumn::FetchVectorRefArray( 
SCROW nRow1, SCROW nRow2
             size_t nPos = itBlk->size;
             ++itBlk;
             if (!appendToBlock(pDocument, rCxt, *pColArray, nPos, nRow2+1, 
itBlk, maCells.end()))
+            {
+                rCxt.discardCachedColArray(nTab, nCol);
                 return 
formula::VectorRefArray(formula::VectorRefArray::Invalid);
+            }
 
             if (pColArray->mpStrArray && hasNonEmpty(*pColArray->mpStrArray, 
nRow1, nRow2))
                 return 
formula::VectorRefArray(&(*pColArray->mpNumArray)[nRow1], 
&(*pColArray->mpStrArray)[nRow1]);
diff --git a/sc/source/core/tool/formulagroup.cxx 
b/sc/source/core/tool/formulagroup.cxx
index cd4a4ccecaf3..4304e1b08e04 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -104,6 +104,13 @@ FormulaGroupContext::ColArray* 
FormulaGroupContext::setCachedColArray(
     return &rArray;
 }
 
+void FormulaGroupContext::discardCachedColArray( SCTAB nTab, SCCOL nCol )
+{
+    ColArraysType::iterator itColArray = maColArrays.find(ColKey(nTab, nCol));
+    if (itColArray != maColArrays.end())
+        maColArrays.erase(itColArray);
+}
+
 void FormulaGroupContext::ensureStrArray( ColArray& rColArray, size_t 
nArrayLen )
 {
     if (rColArray.mpStrArray)
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to