tdf#160616 - Fix SUMPRODUCT calculation is broken in some cases
Double refs with operators only trimmable in case of one root paramater.
Follow up of: ba0ec4a5d2b025b675410cd18890d1cca3bc5a2f
Change-Id: If61fb39696d9539ffc9d32a6ecad79bfa1bf92e5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165957
Tested-by: Gabor Kelemen <gabor.kelemen.extern@allotropia.de>
Tested-by: Jenkins
Reviewed-by: Gabor Kelemen <gabor.kelemen.extern@allotropia.de>
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index adbc9c1..105c7e4 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -1464,7 +1464,7 @@ CPPUNIT_TEST_FIXTURE(TestFormula, testFormulaAnnotateTrimOnDoubleRefs)
{
"=SUMPRODUCT(A:A=$C$1; 1-(A:A=$C$1))",
ScRange(0, 0, 0, 0, 1048575, 0),
ScRange(-1, -1, -1, -1, -1, -1), // Has no trimmable double-ref.
0.0,
false // Not in matrix mode.
},
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 7b655d72..a0529fb 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -6468,6 +6468,8 @@ void ScCompiler::AnnotateTrimOnDoubleRefs()
// OpCode of the "root" operator (which is already in RPN array).
OpCode eOpCode = (*(pCode - 1))->GetOpCode();
// Param number of the "root" operator (which is already in RPN array).
sal_uInt8 nRootParam = (*(pCode - 1))->GetByte();
// eOpCode can be some operator which does not change with operands with or contains zero values.
if (eOpCode == ocSum)
{
@@ -6560,7 +6562,8 @@ void ScCompiler::AnnotateTrimOnDoubleRefs()
// such that one of the operands of ocEqual is a double-ref.
// Examples of formula that matches this are:
// SUMPRODUCT(IF($A:$A=$L12;$D:$D*G:G))
// Also in case of DoubleRef arguments around other Binary operators can be trimmable:
// Also in case of DoubleRef arguments around other Binary operators can be trimmable inside one parameter
// of the root operator:
// SUMPRODUCT(($D:$D>M47:M47)*($D:$D<M48:M48)*($I:$I=N$41))
bool bTillClose = true;
bool bCloseTillIf = false;
@@ -6612,7 +6615,9 @@ void ScCompiler::AnnotateTrimOnDoubleRefs()
case ocUnion:
case ocRange:
{
if (!pTok->IsInForceArray())
// tdf#160616: Double refs with these operators only
// trimmable in case of one paramater
if (!pTok->IsInForceArray() || nRootParam > 1)
break;
FormulaToken* pLHS = *(ppTok - 1);
FormulaToken* pRHS = *(ppTok - 2);