summaryrefslogtreecommitdiff
path: root/sc/qa
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2021-12-04 18:39:22 +0100
committerLuboš Luňák <l.lunak@collabora.com>2021-12-05 10:00:57 +0100
commit9d08f3363188d446b287c445f1ab09339c65d208 (patch)
tree2ea7b1b19fa4786c968cf91ffd010a6a8ea7470f /sc/qa
parent9e0d471466997fce4b59ac88d6bd8ad0108b8974 (diff)
fix caching of ScQueryItem values for multiple entries (tdf#146037)
The code assumed that there would be only one ScQueryEntry. Change-Id: Idf4cc6bdbbf1edad7d13eb9a9643bb67e199dd01 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126368 Tested-by: Luboš Luňák <l.lunak@collabora.com> Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'sc/qa')
-rw-r--r--sc/qa/unit/ucalc.cxx106
1 files changed, 106 insertions, 0 deletions
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index e936aada4a51..9a80a42ad4b1 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -169,6 +169,7 @@ public:
void testDataArea();
void testAutofilter();
void testAutoFilterTimeValue();
+ void testAutofilterOptimizations();
void testTdf76836();
void testTdf76441();
void testTdf142186();
@@ -293,6 +294,7 @@ public:
CPPUNIT_TEST(testToggleRefFlag);
CPPUNIT_TEST(testAutofilter);
CPPUNIT_TEST(testAutoFilterTimeValue);
+ CPPUNIT_TEST(testAutofilterOptimizations);
CPPUNIT_TEST(testTdf76836);
CPPUNIT_TEST(testTdf76441);
CPPUNIT_TEST(testTdf142186);
@@ -3540,6 +3542,110 @@ void Test::testAutoFilterTimeValue()
m_pDoc->DeleteTab(0);
}
+void Test::testAutofilterOptimizations()
+{
+ m_pDoc->InsertTab( 0, "Test" );
+
+ constexpr SCCOL nCols = 4;
+ constexpr SCROW nRows = 200;
+ m_pDoc->SetString(0, 0, 0, "Column1");
+ m_pDoc->SetString(1, 0, 0, "Column2");
+ m_pDoc->SetString(2, 0, 0, "Column3");
+ m_pDoc->SetString(3, 0, 0, "Column4");
+
+ // Fill 1st column with 0-199, 2nd with 1-200, 3rd with "1000"-"1199", 4th with "1001-1200"
+ // (the pairs are off by one to each other to check filtering out a value filters out
+ // only the relevant column).
+ for(SCROW i = 0; i < nRows; ++i)
+ {
+ m_pDoc->SetValue(0, i + 1, 0, i);
+ m_pDoc->SetValue(1, i + 1, 0, i+1);
+ m_pDoc->SetString(2, i + 1, 0, "val" + OUString::number(i+1000));
+ m_pDoc->SetString(3, i + 1, 0, "val" + OUString::number(i+1000+1));
+ }
+
+ ScDBData* pDBData = new ScDBData("NONAME", 0, 0, 0, nCols, nRows);
+ m_pDoc->SetAnonymousDBData(0, std::unique_ptr<ScDBData>(pDBData));
+
+ pDBData->SetAutoFilter(true);
+ ScRange aRange;
+ pDBData->GetArea(aRange);
+ m_pDoc->ApplyFlagsTab( aRange.aStart.Col(), aRange.aStart.Row(),
+ aRange.aEnd.Col(), aRange.aStart.Row(),
+ aRange.aStart.Tab(), ScMF::Auto);
+
+ //create the query param
+ ScQueryParam aParam;
+ pDBData->GetQueryParam(aParam);
+ ScQueryEntry& rEntry0 = aParam.GetEntry(0);
+ rEntry0.bDoQuery = true;
+ rEntry0.nField = 0;
+ rEntry0.eOp = SC_EQUAL;
+ rEntry0.GetQueryItems().resize(nRows);
+ ScQueryEntry& rEntry1 = aParam.GetEntry(1);
+ rEntry1.bDoQuery = true;
+ rEntry1.nField = 1;
+ rEntry1.eOp = SC_EQUAL;
+ rEntry1.GetQueryItems().resize(nRows);
+ ScQueryEntry& rEntry2 = aParam.GetEntry(2);
+ rEntry2.bDoQuery = true;
+ rEntry2.nField = 2;
+ rEntry2.eOp = SC_EQUAL;
+ rEntry2.GetQueryItems().resize(nRows);
+ ScQueryEntry& rEntry3 = aParam.GetEntry(3);
+ rEntry3.bDoQuery = true;
+ rEntry3.nField = 3;
+ rEntry3.eOp = SC_EQUAL;
+ rEntry3.GetQueryItems().resize(nRows);
+ // Set up autofilter to select all values except one in each column.
+ // This should only filter out 2nd, 3rd, 6th and 7th rows.
+ for( int i = 0; i < nRows; ++i )
+ {
+ if(i!= 1)
+ rEntry0.GetQueryItems()[i].mfVal = i;
+ if(i!= 2)
+ rEntry1.GetQueryItems()[i].mfVal = i + 1;
+ if(i!= 5)
+ {
+ rEntry2.GetQueryItems()[i].maString = m_pDoc->GetSharedStringPool().intern("val" + OUString::number(i+1000));
+ rEntry2.GetQueryItems()[i].meType = ScQueryEntry::ByString;
+ }
+ if(i!= 6)
+ {
+ rEntry3.GetQueryItems()[i].maString = m_pDoc->GetSharedStringPool().intern("val" + OUString::number(i+1000+1));
+ rEntry3.GetQueryItems()[i].meType = ScQueryEntry::ByString;
+ }
+ }
+ // add queryParam to database range.
+ pDBData->SetQueryParam(aParam);
+
+ // perform the query.
+ m_pDoc->Query(0, aParam, true);
+
+ // check that only rows with filtered out values are hidden, and not rows that share
+ // a value in a different column
+ SCROW nRow1, nRow2;
+ CPPUNIT_ASSERT_MESSAGE("row 2 should be visible", !m_pDoc->RowHidden(1, 0, &nRow1, &nRow2));
+ CPPUNIT_ASSERT_MESSAGE("row 3 should be hidden", m_pDoc->RowHidden(2, 0, &nRow1, &nRow2));
+ CPPUNIT_ASSERT_MESSAGE("row 4 should be hidden", m_pDoc->RowHidden(3, 0, &nRow1, &nRow2));
+ CPPUNIT_ASSERT_MESSAGE("row 5 should be visible", !m_pDoc->RowHidden(4, 0, &nRow1, &nRow2));
+ CPPUNIT_ASSERT_MESSAGE("row 6 should be visible", !m_pDoc->RowHidden(5, 0, &nRow1, &nRow2));
+ CPPUNIT_ASSERT_MESSAGE("row 7 should be hidden", m_pDoc->RowHidden(6, 0, &nRow1, &nRow2));
+ CPPUNIT_ASSERT_MESSAGE("row 8 should be hidden", m_pDoc->RowHidden(7, 0, &nRow1, &nRow2));
+ CPPUNIT_ASSERT_MESSAGE("row 9 should be visible", !m_pDoc->RowHidden(8, 0, &nRow1, &nRow2));
+
+ // Remove filtering.
+ rEntry0.Clear();
+ rEntry1.Clear();
+ rEntry2.Clear();
+ m_pDoc->Query(0, aParam, true);
+ CPPUNIT_ASSERT_MESSAGE("All rows should be shown.", !m_pDoc->RowHidden(0, 0, &nRow1, &nRow2));
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("All rows should be shown.", SCROW(0), nRow1);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("All rows should be shown.", SCROW(MAXROW), nRow2);
+
+ m_pDoc->DeleteTab(0);
+}
+
void Test::testTdf76441()
{
m_pDoc->InsertTab(0, "Test");