Kaydet (Commit) 8af5cb78 authored tarafından Luboš Luňák's avatar Luboš Luňák

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: 's avatarLuboš Luňák <l.lunak@collabora.com>
üst c5fcb476
......@@ -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 );
......
......@@ -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]);
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment