sc/source/core/data/formulacell.cxx |   52 ++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

New commits:
commit 81c19355d7ad830c2356d7d82e244929be3823a8
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Sat Aug 19 16:42:25 2023 +0100
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Sat Aug 19 20:55:08 2023 +0200

    crashtesting: parallel calc assert with Lookup
    
    seen in forum-mso-en4-55192.xlsx with a singlecell as the result vector
    which gets autoextended outside the range that the pre-parallel calc
    took into consideration on set up. For simplicity if there is a result
    vector assume that if it doesn't match the size of the search vector
    that we can't parallelize this.
    
    Change-Id: Ic67e1b5b35964760ac5b1608cd516a69e08d0540
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155862
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/sc/source/core/data/formulacell.cxx 
b/sc/source/core/data/formulacell.cxx
index 4b974831992b..85d43700461e 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -4432,6 +4432,52 @@ struct ScDependantsCalculator
         return nRowLen;
     }
 
+    // Because Lookup will extend the Result Vector under certain cirumstances 
listed at:
+    // https://wiki.documentfoundation.org/Documentation/Calc_Functions/LOOKUP
+    // then if the Lookup has a Result Vector only accept the Lookup for 
parallelization
+    // of the Result Vector has the same dimensions as the Search Vector.
+    bool LookupResultVectorMismatch(sal_Int32 nTokenIdx)
+    {
+        if (nTokenIdx >= 3)
+        {
+            FormulaToken** pRPNArray = mrCode.GetCode();
+            if (pRPNArray[nTokenIdx - 1]->GetOpCode() == ocPush &&   // <- 
result vector
+                pRPNArray[nTokenIdx - 2]->GetOpCode() == ocPush &&   // <- 
search vector
+                pRPNArray[nTokenIdx - 2]->GetType() == svDoubleRef &&
+                pRPNArray[nTokenIdx - 3]->GetOpCode() == ocPush)     // <- 
search criterion
+            {
+                auto res = pRPNArray[nTokenIdx - 1];
+                // If Result vector is just a single cell reference
+                // LOOKUP extends it as a column vector.
+                if (res->GetType() == svSingleRef)
+                    return true;
+
+                // If Result vector is a cell range and the match position
+                // falls outside its length, it gets automatically extended
+                // to the length of Search vector, but in the direction of
+                // Result vector.
+                if (res->GetType() == svDoubleRef)
+                {
+                    ScComplexRefData aRef1 = *res->GetDoubleRef();
+                    ScComplexRefData aRef2 = *pRPNArray[nTokenIdx - 
2]->GetDoubleRef();
+                    ScRange resultRange = aRef1.toAbs(mrDoc, mrPos);
+                    ScRange sourceRange = aRef2.toAbs(mrDoc, mrPos);
+
+                    SCROW nResultRows = resultRange.aEnd.Row() - 
resultRange.aStart.Row();
+                    SCROW nSourceRows = sourceRange.aEnd.Row() - 
sourceRange.aStart.Row();
+                    if (nResultRows != nSourceRows)
+                        return true;
+
+                    SCCOL nResultCols = resultRange.aEnd.Col() - 
resultRange.aStart.Col();
+                    SCCOL nSourceCols = sourceRange.aEnd.Col() - 
sourceRange.aStart.Col();
+                    if (nResultCols != nSourceCols)
+                        return true;
+                }
+            }
+        }
+        return false;
+    }
+
     bool DoIt(ScRangeList* pSuccessfulDependencies, ScAddress* pDirtiedAddress)
     {
         // Partially from ScGroupTokenConverter::convert in 
sc/source/core/data/grouptokenconverter.cxx
@@ -4460,6 +4506,12 @@ struct ScDependantsCalculator
                     return false;
             }
 
+            if (p->GetOpCode() == ocLookup && 
LookupResultVectorMismatch(nTokenIdx))
+            {
+                SAL_INFO("sc.core.formulacell", "Lookup Result Vector size 
doesn't match Search Vector");
+                return false;
+            }
+
             switch (p->GetType())
             {
             case svSingleRef:

Reply via email to