提交 83aac2cb 编写于 作者: B Bhuvnesh Chaudhary 提交者: Bhuvnesh

Added test cases for equivalance classes

Added utility function to compare two Equivalence Class
Arrays
Signed-off-by: NOmer Arap <oarap@pivotal.io>
上级 66c3c843
......@@ -1052,6 +1052,10 @@ namespace gpopt
// check if the equivalance classes are disjoint
static
BOOL FEquivalanceClassesDisjoint(IMemoryPool *pmp, const DrgPcrs *pdrgpcrs);
// check if the equivalance classes are same
static
BOOL FEquivalanceClassesEqual(IMemoryPool *pmp, DrgPcrs *pdrgpcrsFst, DrgPcrs *pdrgpcrsSnd);
}; // class CUtils
} // namespace gpopt
......
......@@ -6299,4 +6299,46 @@ CUtils::FEquivalanceClassesDisjoint
phmcscrs->Release();
return true;
}
// check if the equivalance classes are same
BOOL
CUtils::FEquivalanceClassesEqual
(
IMemoryPool *pmp,
DrgPcrs *pdrgpcrsFst,
DrgPcrs *pdrgpcrsSnd
)
{
const ULONG ulLenFrst = pdrgpcrsFst->UlLength();
const ULONG ulLenSecond = pdrgpcrsSnd->UlLength();
if (ulLenFrst != ulLenSecond) return false;
HMCrCrs *phmcscrs = GPOS_NEW(pmp) HMCrCrs(pmp);
for (ULONG ulFst = 0; ulFst < ulLenFrst; ulFst++)
{
CColRefSet *pcrsFst = (*pdrgpcrsFst)[ulFst];
CColRefSetIter crsi(*pcrsFst);
while (crsi.FAdvance())
{
CColRef *pcr = crsi.Pcr();
pcrsFst->AddRef();
phmcscrs->FInsert(pcr, pcrsFst);
}
}
for (ULONG ulSnd = 0; ulSnd < ulLenSecond; ulSnd++)
{
CColRefSet *pcrsSnd = (*pdrgpcrsSnd)[ulSnd];
CColRef *pcr = pcrsSnd->PcrAny();
CColRefSet *pcrs = phmcscrs->PtLookup(pcr);
if(!pcrsSnd->FEqual(pcrs))
{
phmcscrs->Release();
return false;
}
}
phmcscrs->Release();
return true;
}
// EOF
......@@ -150,6 +150,8 @@ add_executable(gporca_test
src/unittest/gpopt/base/CColRefSetIterTest.cpp
include/unittest/gpopt/base/CColRefSetTest.h
src/unittest/gpopt/base/CColRefSetTest.cpp
include/unittest/gpopt/base/CEquivalenceClassesTest.h
src/unittest/gpopt/base/CEquivalenceClassesTest.cpp
include/unittest/gpopt/base/CFunctionalDependencyTest.h
src/unittest/gpopt/base/CFunctionalDependencyTest.cpp
include/unittest/gpopt/base/CMaxCardTest.h
......@@ -255,6 +257,7 @@ if (GPOS_ARCH_BITS EQUAL 64)
endif()
add_orca_test(CEngineTest)
add_orca_test(CEquivalenceClassesTest)
add_orca_test(CExpressionTest)
add_orca_test(CJoinOrderTest)
add_orca_test(CKeyCollectionTest)
......
......@@ -820,6 +820,11 @@ namespace gpopt
// return the number of segments, default return GPOPT_TEST_SEGMENTS
static
ULONG UlSegments(COptimizerConfig *poconf);
// create Equivalence Class based on the breakpoints
static
DrgPcrs *
createEquivalenceClasses(IMemoryPool *pmp, CColRefSet *pcrs, INT setBoundary[]);
}; // class CTestUtils
} // namespace gpopt
......
//---------------------------------------------------------------------------
// Pivotal Software, Inc
// Copyright (C) 2017 Pivotal Software, Inc
//---------------------------------------------------------------------------
#ifndef GPOPT_CEquivalenceClassesTest_H
#define GPOPT_CEquivalenceClassesTest_H
#include "gpos/base.h"
namespace gpopt
{
// Static unit tests for equivalence classes
class CEquivalenceClassesTest
{
public:
// unittests
static GPOS_RESULT EresUnittest();
static GPOS_RESULT EresUnittest_NotDisjointEquivalanceClasses();
static GPOS_RESULT EresUnittest_IntersectEquivalanceClasses();
static DrgPcrs* createEquivalenceClasses(IMemoryPool *pmp, CColRefSet *pcrs, int breakpoints[]);
}; // class CEquivalenceClassesTest
}
#endif // !GPOPT_CEquivalenceClassesTest_H
// EOF
......@@ -50,6 +50,7 @@
#include "unittest/gpopt/base/CColRefSetTest.h"
#include "unittest/gpopt/base/CColumnFactoryTest.h"
#include "unittest/gpopt/base/CDistributionSpecTest.h"
#include "unittest/gpopt/base/CEquivalenceClassesTest.h"
#include "unittest/gpopt/base/CFunctionalDependencyTest.h"
#include "unittest/gpopt/base/CKeyCollectionTest.h"
#include "unittest/gpopt/base/CMaxCardTest.h"
......@@ -184,6 +185,7 @@ static gpos::CUnittest rgut[] =
GPOS_UNITTEST_STD(CSubqueryHandlerTest),
#endif // !defined(GPOS_32BIT)
GPOS_UNITTEST_STD(CEngineTest),
GPOS_UNITTEST_STD(CEquivalenceClassesTest),
GPOS_UNITTEST_STD(CExpressionTest),
GPOS_UNITTEST_STD(CJoinOrderTest),
GPOS_UNITTEST_STD(CKeyCollectionTest),
......
......@@ -4590,4 +4590,31 @@ CTestUtils::EresUnittest_RunTestsWithoutAdditionalTraceFlags
}
// Create Equivalence Class based on the breakpoints
DrgPcrs *
CTestUtils::createEquivalenceClasses(IMemoryPool *pmp, CColRefSet *pcrs, INT setBoundary[]) {
INT i = 0;
ULONG bpIndex = 0;
DrgPcrs *pdrgcrs = GPOS_NEW(pmp) DrgPcrs(pmp);
CColRefSetIter crsi(*pcrs);
CColRefSet *pcrsLoop = GPOS_NEW(pmp) CColRefSet(pmp);
while (crsi.FAdvance())
{
if (i == setBoundary[bpIndex]) {
pdrgcrs->Append(pcrsLoop);
CColRefSet *pcrsLoop1 = GPOS_NEW(pmp) CColRefSet(pmp);
pcrsLoop = pcrsLoop1;
bpIndex++;
}
CColRef *pcr = crsi.Pcr();
pcrsLoop->Include(pcr);
i++;
}
pdrgcrs->Append(pcrsLoop);
return pdrgcrs;
}
// EOF
//---------------------------------------------------------------------------
// Pivotal Software, Inc
// Copyright (C) 2017 Pivotal Software, Inc
//---------------------------------------------------------------------------
#include "gpopt/base/CColRefSet.h"
#include "gpopt/base/CColRefSetIter.h"
#include "gpopt/base/CColumnFactory.h"
#include "gpopt/mdcache/CMDCache.h"
#include "gpopt/base/CQueryContext.h"
#include "gpopt/eval/CConstExprEvaluatorDefault.h"
#include "unittest/base.h"
#include "unittest/gpopt/CTestUtils.h"
#include "unittest/gpopt/base/CEquivalenceClassesTest.h"
#include "unittest/gpopt/translate/CTranslatorExprToDXLTest.h"
#include "naucrates/md/IMDTypeInt4.h"
#include "naucrates/md/CMDProviderMemory.h"
// Unittest for bit vectors
GPOS_RESULT
CEquivalenceClassesTest::EresUnittest()
{
CUnittest rgut[] =
{
GPOS_UNITTEST_FUNC(CEquivalenceClassesTest::EresUnittest_NotDisjointEquivalanceClasses),
GPOS_UNITTEST_FUNC(CEquivalenceClassesTest::EresUnittest_IntersectEquivalanceClasses)
};
return CUnittest::EresExecute(rgut, GPOS_ARRAY_SIZE(rgut));
}
// Check disjoint equivalence classes are detected
GPOS_RESULT
CEquivalenceClassesTest::EresUnittest_NotDisjointEquivalanceClasses()
{
CAutoMemoryPool amp;
IMemoryPool *pmp = amp.Pmp();
CColRefSet *pcrs = GPOS_NEW(pmp) CColRefSet(pmp);
// Setup an MD cache with a file-based provider
CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
pmdp->AddRef();
CMDAccessor mda(pmp, CMDCache::Pcache());
mda.RegisterProvider(CTestUtils::m_sysidDefault, pmdp);
// install opt context in TLS
CAutoOptCtxt aoc
(
pmp,
&mda,
NULL, /* pceeval */
CTestUtils::Pcm(pmp)
);
// get column factory from optimizer context object
CColumnFactory *pcf = COptCtxt::PoctxtFromTLS()->Pcf();
CWStringConst strName(GPOS_WSZ_LIT("Test Column"));
CName name(&strName);
const IMDTypeInt4 *pmdtypeint4 = mda.PtMDType<IMDTypeInt4>();
ULONG ulCols = 10;
for (ULONG i = 0; i < ulCols; i++)
{
CColRef *pcr = pcf->PcrCreate(pmdtypeint4, name);
pcrs->Include(pcr);
GPOS_ASSERT(pcrs->FMember(pcr));
}
GPOS_ASSERT(pcrs->CElements() == ulCols);
CColRefSet *pcrsTwo = GPOS_NEW(pmp) CColRefSet(pmp, *pcrs);
GPOS_ASSERT(pcrsTwo->CElements() == ulCols);
CColRefSet *pcrsThree = GPOS_NEW(pmp) CColRefSet(pmp);
GPOS_ASSERT(pcrsThree->CElements() == 0);
CColRef *pcrThree = pcf->PcrCreate(pmdtypeint4, name);
pcrsThree->Include(pcrThree);
GPOS_ASSERT(pcrsThree->CElements() == 1);
DrgPcrs *pdrgpcrs = GPOS_NEW(pmp) DrgPcrs(pmp);
pcrs->AddRef();
pcrsTwo->AddRef();
pdrgpcrs->Append(pcrs);
pdrgpcrs->Append(pcrsTwo);
GPOS_ASSERT(!CUtils::FEquivalanceClassesDisjoint(pmp,pdrgpcrs));
DrgPcrs *pdrgpcrsTwo = GPOS_NEW(pmp) DrgPcrs(pmp);
pcrs->AddRef();
pcrsThree->AddRef();
pdrgpcrsTwo->Append(pcrs);
pdrgpcrsTwo->Append(pcrsThree);
GPOS_ASSERT(CUtils::FEquivalanceClassesDisjoint(pmp,pdrgpcrsTwo));
pcrsThree->Release();
pcrsTwo->Release();
pcrs->Release();
pdrgpcrs->Release();
pdrgpcrsTwo->Release();
return GPOS_OK;
}
// Check disjoint equivalence classes are detected
GPOS_RESULT
CEquivalenceClassesTest::EresUnittest_IntersectEquivalanceClasses()
{
CAutoMemoryPool amp;
IMemoryPool *pmp = amp.Pmp();
CColRefSet *pcrs = GPOS_NEW(pmp) CColRefSet(pmp);
// Setup an MD cache with a file-based provider
CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
pmdp->AddRef();
CMDAccessor mda(pmp, CMDCache::Pcache());
mda.RegisterProvider(CTestUtils::m_sysidDefault, pmdp);
// install opt context in TLS
CAutoOptCtxt aoc
(
pmp,
&mda,
NULL, /* pceeval */
CTestUtils::Pcm(pmp)
);
// get column factory from optimizer context object
CColumnFactory *pcf = COptCtxt::PoctxtFromTLS()->Pcf();
CWStringConst strName(GPOS_WSZ_LIT("Test Column"));
CName name(&strName);
const IMDTypeInt4 *pmdtypeint4 = mda.PtMDType<IMDTypeInt4>();
ULONG ulCols = 10;
for (ULONG i = 0; i < ulCols; i++)
{
CColRef *pcr = pcf->PcrCreate(pmdtypeint4, name);
pcrs->Include(pcr);
GPOS_ASSERT(pcrs->FMember(pcr));
}
GPOS_ASSERT(pcrs->CElements() == ulCols);
// Generate equivalence classes
INT setBoundaryFirst[] = {2,5,7};
DrgPcrs *pdrgpFirst = CTestUtils::createEquivalenceClasses(pmp, pcrs, setBoundaryFirst);
INT setBoundarySecond[] = {1,4,5,6};
DrgPcrs *pdrgpSecond = CTestUtils::createEquivalenceClasses(pmp, pcrs, setBoundarySecond);
INT setBoundaryExpected[] = {1,2,4,5,6,7};
DrgPcrs *pdrgpIntersectExpectedOp = CTestUtils::createEquivalenceClasses(pmp, pcrs, setBoundaryExpected);
DrgPcrs *pdrgpResult = CUtils::PdrgpcrsIntersectEquivClasses(pmp, pdrgpFirst, pdrgpSecond);
GPOS_ASSERT(CUtils::FEquivalanceClassesDisjoint(pmp,pdrgpResult));
GPOS_ASSERT(CUtils::FEquivalanceClassesEqual(pmp, pdrgpResult, pdrgpIntersectExpectedOp));
pcrs->Release();
pdrgpFirst->Release();
pdrgpResult->Release();
pdrgpSecond->Release();
pdrgpIntersectExpectedOp->Release();
return GPOS_OK;
}
// EOF
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册