Kaydet (Commit) ff166845 authored tarafından Dennis Francis's avatar Dennis Francis

tdf#115093 : Do not reuse singleref tokens...

...in formula group computation if the formula contains
only a single reference besides any ocOpen/ocClose pairs
wrapping it as the sole content.

In such a case the "result" formula token
returned by ScInterpreter::GetResultToken() is the same
as the original singleref token, so for each row of the
formulagroup, we need to use a separate singleref token.

Also added a unit test in sc/qa/unit/parallelism.cxx

Change-Id: I6032efc5be9b51ca1e9daf9bdd19997a949d2f43
Reviewed-on: https://gerrit.libreoffice.org/48449Reviewed-by: 's avatarMichael Meeks <michael.meeks@collabora.com>
Tested-by: 's avatarJenkins <ci@libreoffice.org>
üst f8aca037
......@@ -46,12 +46,14 @@ public:
void testDivision();
void testVLOOKUP();
void testVLOOKUPSUM();
void testSingleRef();
CPPUNIT_TEST_SUITE(ScParallelismTest);
CPPUNIT_TEST(testSUMIFS);
CPPUNIT_TEST(testDivision);
CPPUNIT_TEST(testVLOOKUP);
CPPUNIT_TEST(testVLOOKUPSUM);
CPPUNIT_TEST(testSingleRef);
CPPUNIT_TEST_SUITE_END();
private:
......@@ -296,6 +298,27 @@ void ScParallelismTest::testVLOOKUPSUM()
m_pDoc->DeleteTab(0);
}
void ScParallelismTest::testSingleRef()
{
m_pDoc->InsertTab(0, "1");
const size_t nNumRows = 200;
for (size_t i = 0; i < nNumRows; ++i)
{
m_pDoc->SetValue(0, i, 0, static_cast<double>(i));
m_pDoc->SetFormula(ScAddress(1, i, 0), "=A" + OUString::number(i+1), formula::FormulaGrammar::GRAM_NATIVE_UI);
}
m_xDocShell->DoHardRecalc();
for (size_t i = 0; i < nNumRows; ++i)
{
OString aMsg = "At row " + OString::number(i);
CPPUNIT_ASSERT_EQUAL_MESSAGE(aMsg.getStr(), i, static_cast<size_t>(m_pDoc->GetValue(1, i, 0)));
}
m_pDoc->DeleteTab(0);
}
CPPUNIT_TEST_SUITE_REGISTRATION(ScParallelismTest);
CPPUNIT_PLUGIN_IMPLEMENT();
......
......@@ -177,6 +177,7 @@ public:
ScTokenArray aCode2;
ScInterpreterContext aContext(mrDoc, mpFormatter);
sal_uInt16 nNumNonOpenClose = mrCode.GetLen();
for (SCROW i = mnIdx; i <= mnLastIdx; ++i, maBatchTopPos.IncRow())
{
......@@ -212,7 +213,7 @@ public:
aCode2.AddString(rPool.intern(OUString(pStr)));
else
{
if ( pTargetTok->GetType() == formula::svString )
if ( ( pTargetTok->GetType() == formula::svString ) && ( nNumNonOpenClose > 1 ) )
pTargetTok->SetString(rPool.intern(OUString(pStr)));
else
{
......@@ -226,7 +227,7 @@ public:
// Value of NaN represents an empty cell.
if ( !pTargetTok )
aCode2.AddToken(ScEmptyCellToken(false, false));
else if ( pTargetTok->GetType() != formula::svEmptyCell )
else if ( ( pTargetTok->GetType() != formula::svEmptyCell ) || ( nNumNonOpenClose == 1 ) )
{
ScEmptyCellToken* pEmptyTok = new ScEmptyCellToken(false, false);
aCode2.ReplaceToken(nTokIdx, pEmptyTok, formula::FormulaTokenArray::CODE_ONLY);
......@@ -239,7 +240,7 @@ public:
aCode2.AddDouble(fVal);
else
{
if ( pTargetTok->GetType() == formula::svDouble )
if ( ( pTargetTok->GetType() == formula::svDouble ) && ( nNumNonOpenClose > 1 ) )
pTargetTok->GetDoubleAsReference() = fVal;
else
{
......@@ -291,7 +292,16 @@ public:
break;
default:
if ( !pTargetTok )
{
if ( p->GetType() == formula::svSep )
{
OpCode eOp = p->GetOpCode();
if ( eOp == ocOpen || eOp == ocClose )
--nNumNonOpenClose;
}
aCode2.AddToken(*p);
}
} // end of switch statement
} // end of formula token for loop
......
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