greenplumn CConstraintTest 源码
greenplumn CConstraintTest 代码
文件路径:/src/backend/gporca/server/src/unittest/gpopt/base/CConstraintTest.cpp
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2012 EMC Corp.
//
// @filename:
// CConstraintTest.cpp
//
// @doc:
// Test for constraint
//---------------------------------------------------------------------------
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#include "unittest/gpopt/base/CConstraintTest.h"
#include <stdint.h>
#include "gpos/task/CAutoTraceFlag.h"
#include "gpopt/base/CDefaultComparator.h"
#include "gpopt/base/CUtils.h"
#include "gpopt/eval/CConstExprEvaluatorDefault.h"
#include "gpopt/operators/CPredicateUtils.h"
#include "naucrates/base/CDatumInt8GPDB.h"
#include "naucrates/md/CMDIdGPDB.h"
#include "naucrates/md/IMDScalarOp.h"
#include "unittest/base.h"
#include "unittest/gpopt/CConstExprEvaluatorForDates.h"
// number of microseconds in one day
const LINT CConstraintTest::lMicrosecondsPerDay =
24 * 60 * 60 * INT64_C(1000000);
// date for '01-01-2012'
const LINT CConstraintTest::lInternalRepresentationFor2012_01_01 =
LINT(4383) * CConstraintTest::lMicrosecondsPerDay;
// date for '01-21-2012'
const LINT CConstraintTest::lInternalRepresentationFor2012_01_21 =
LINT(5003) * CConstraintTest::lMicrosecondsPerDay;
// date for '01-02-2012'
const LINT CConstraintTest::lInternalRepresentationFor2012_01_02 =
LINT(4384) * CConstraintTest::lMicrosecondsPerDay;
// date for '01-22-2012'
const LINT CConstraintTest::lInternalRepresentationFor2012_01_22 =
LINT(5004) * CConstraintTest::lMicrosecondsPerDay;
// byte representation for '01-01-2012'
const WCHAR *CConstraintTest::wszInternalRepresentationFor2012_01_01 =
GPOS_WSZ_LIT("HxEAAA==");
// byte representation for '01-21-2012'
const WCHAR *CConstraintTest::wszInternalRepresentationFor2012_01_21 =
GPOS_WSZ_LIT("MxEAAA==");
// byte representation for '01-02-2012'
const WCHAR *CConstraintTest::wszInternalRepresentationFor2012_01_02 =
GPOS_WSZ_LIT("IBEAAA==");
// byte representation for '01-22-2012'
const WCHAR *CConstraintTest::wszInternalRepresentationFor2012_01_22 =
GPOS_WSZ_LIT("MhEAAA==");
static GPOS_RESULT EresUnittest_CConstraintIntervalFromArrayExprIncludesNull();
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::EresUnittest
//
// @doc:
// Unittest for ranges
//
//---------------------------------------------------------------------------
GPOS_RESULT
CConstraintTest::EresUnittest()
{
CUnittest rgut[] = {
GPOS_UNITTEST_FUNC(
EresUnittest_CConstraintIntervalFromArrayExprIncludesNull),
GPOS_UNITTEST_FUNC(CConstraintTest::EresUnittest_CInterval),
GPOS_UNITTEST_FUNC(
CConstraintTest::EresUnittest_CIntervalFromScalarExpr),
GPOS_UNITTEST_FUNC(CConstraintTest::EresUnittest_CConjunction),
GPOS_UNITTEST_FUNC(CConstraintTest::EresUnittest_CDisjunction),
GPOS_UNITTEST_FUNC(CConstraintTest::EresUnittest_CNegation),
GPOS_UNITTEST_FUNC(
CConstraintTest::EresUnittest_CConstraintFromScalarExpr),
GPOS_UNITTEST_FUNC(
CConstraintTest::EresUnittest_CConstraintIntervalConvertsTo),
GPOS_UNITTEST_FUNC(
CConstraintTest::EresUnittest_CConstraintIntervalPexpr),
GPOS_UNITTEST_FUNC(
CConstraintTest::EresUnittest_CConstraintIntervalFromArrayExpr),
#ifdef GPOS_DEBUG
GPOS_UNITTEST_FUNC_THROW(CConstraintTest::EresUnittest_NegativeTests,
gpos::CException::ExmaSystem,
gpos::CException::ExmiAssert),
#endif // GPOS_DEBUG
GPOS_UNITTEST_FUNC(CConstraintTest::EresUnittest_ConstraintsOnDates),
};
return CUnittest::EresExecute(rgut, GPOS_ARRAY_SIZE(rgut));
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::EresUnittest_CInterval
//
// @doc:
// Interval tests
//
//---------------------------------------------------------------------------
GPOS_RESULT
CConstraintTest::EresUnittest_CInterval()
{
// create memory pool
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
// setup a file-based provider
CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
pmdp->AddRef();
CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);
CConstExprEvaluatorForDates *pceeval =
GPOS_NEW(mp) CConstExprEvaluatorForDates(mp);
// install opt context in TLS
CAutoOptCtxt aoc(mp, &mda, pceeval, CTestUtils::GetCostModel(mp));
GPOS_ASSERT(nullptr != COptCtxt::PoctxtFromTLS()->Pcomp());
IMDTypeInt8 *pmdtypeint8 =
(IMDTypeInt8 *) mda.PtMDType<IMDTypeInt8>(CTestUtils::m_sysidDefault);
IMDId *mdid = pmdtypeint8->MDId();
CExpression *pexprGet = CTestUtils::PexprLogicalGet(mp);
CColRefSet *pcrs = pexprGet->DeriveOutputColumns();
CColRef *colref = pcrs->PcrAny();
// first interval
CConstraintInterval *pciFirst = PciFirstInterval(mp, mdid, colref);
PrintConstraint(mp, pciFirst);
// second interval
CConstraintInterval *pciSecond = PciSecondInterval(mp, mdid, colref);
PrintConstraint(mp, pciSecond);
// intersection
CConstraintInterval *pciIntersect = pciFirst->PciIntersect(mp, pciSecond);
PrintConstraint(mp, pciIntersect);
// union
CConstraintInterval *pciUnion = pciFirst->PciUnion(mp, pciSecond);
PrintConstraint(mp, pciUnion);
// diff 1
CConstraintInterval *pciDiff1 = pciFirst->PciDifference(mp, pciSecond);
PrintConstraint(mp, pciDiff1);
// diff 2
CConstraintInterval *pciDiff2 = pciSecond->PciDifference(mp, pciFirst);
PrintConstraint(mp, pciDiff2);
// complement
CConstraintInterval *pciComp = pciFirst->PciComplement(mp);
PrintConstraint(mp, pciComp);
// containment
GPOS_ASSERT(!pciFirst->Contains(pciSecond));
GPOS_ASSERT(pciFirst->Contains(pciDiff1));
GPOS_ASSERT(!pciSecond->Contains(pciFirst));
GPOS_ASSERT(pciSecond->Contains(pciDiff2));
// equality
CConstraintInterval *pciThird = PciFirstInterval(mp, mdid, colref);
pciThird->AddRef();
CConstraintInterval *pciFourth = pciThird;
GPOS_ASSERT(!pciFirst->Equals(pciSecond));
GPOS_ASSERT(!pciFirst->Equals(pciDiff1));
GPOS_ASSERT(!pciSecond->Equals(pciDiff2));
GPOS_ASSERT(pciFirst->Equals(pciThird));
GPOS_ASSERT(pciFourth->Equals(pciThird));
pciFirst->Release();
pciSecond->Release();
pciThird->Release();
pciFourth->Release();
pciIntersect->Release();
pciUnion->Release();
pciDiff1->Release();
pciDiff2->Release();
pciComp->Release();
pexprGet->Release();
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::EresUnittest_CConjunction
//
// @doc:
// Conjunction test
//
//---------------------------------------------------------------------------
GPOS_RESULT
CConstraintTest::EresUnittest_CConjunction()
{
// create memory pool
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
// setup a file-based provider
CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
pmdp->AddRef();
CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);
CConstExprEvaluatorForDates *pceeval =
GPOS_NEW(mp) CConstExprEvaluatorForDates(mp);
// install opt context in TLS
CAutoOptCtxt aoc(mp, &mda, pceeval, CTestUtils::GetCostModel(mp));
GPOS_ASSERT(nullptr != COptCtxt::PoctxtFromTLS()->Pcomp());
IMDTypeInt8 *pmdtypeint8 =
(IMDTypeInt8 *) mda.PtMDType<IMDTypeInt8>(CTestUtils::m_sysidDefault);
IMDId *mdid = pmdtypeint8->MDId();
CExpression *pexprGet1 = CTestUtils::PexprLogicalGet(mp);
CColRefSet *pcrs1 = pexprGet1->DeriveOutputColumns();
CColRef *pcr1 = pcrs1->PcrAny();
CExpression *pexprGet2 = CTestUtils::PexprLogicalGet(mp);
CColRefSet *pcrs2 = pexprGet2->DeriveOutputColumns();
CColRef *pcr2 = pcrs2->PcrAny();
CConstraintConjunction *pcconj1 = Pcstconjunction(mp, mdid, pcr1);
PrintConstraint(mp, pcconj1);
GPOS_ASSERT(!pcconj1->FContradiction());
CConstraintConjunction *pcconj2 = Pcstconjunction(mp, mdid, pcr2);
PrintConstraint(mp, pcconj2);
CConstraintArray *pdrgpcst = GPOS_NEW(mp) CConstraintArray(mp);
pcconj1->AddRef();
pcconj2->AddRef();
pdrgpcst->Append(pcconj1);
pdrgpcst->Append(pcconj2);
CConstraintConjunction *pcconjTop =
GPOS_NEW(mp) CConstraintConjunction(mp, pdrgpcst);
PrintConstraint(mp, pcconjTop);
// containment
GPOS_ASSERT(!pcconj1->Contains(pcconj2));
GPOS_ASSERT(!pcconj2->Contains(pcconj1));
GPOS_ASSERT(pcconj1->Contains(pcconjTop));
GPOS_ASSERT(!pcconjTop->Contains(pcconj1));
GPOS_ASSERT(pcconj2->Contains(pcconjTop));
GPOS_ASSERT(!pcconjTop->Contains(pcconj2));
// equality
GPOS_ASSERT(!pcconj1->Equals(pcconjTop));
GPOS_ASSERT(!pcconjTop->Equals(pcconj2));
pcconjTop->Release();
pcconj1->Release();
pcconj2->Release();
pexprGet1->Release();
pexprGet2->Release();
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::Pcstconjunction
//
// @doc:
// Build a conjunction
//
//---------------------------------------------------------------------------
CConstraintConjunction *
CConstraintTest::Pcstconjunction(CMemoryPool *mp, IMDId *mdid, CColRef *colref)
{
// first interval
CConstraintInterval *pciFirst = PciFirstInterval(mp, mdid, colref);
// second interval
CConstraintInterval *pciSecond = PciSecondInterval(mp, mdid, colref);
CConstraintArray *pdrgpcst = GPOS_NEW(mp) CConstraintArray(mp);
pdrgpcst->Append(pciFirst);
pdrgpcst->Append(pciSecond);
return GPOS_NEW(mp) CConstraintConjunction(mp, pdrgpcst);
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::Pcstdisjunction
//
// @doc:
// Build a disjunction
//
//---------------------------------------------------------------------------
CConstraintDisjunction *
CConstraintTest::Pcstdisjunction(CMemoryPool *mp, IMDId *mdid, CColRef *colref)
{
// first interval
CConstraintInterval *pciFirst = PciFirstInterval(mp, mdid, colref);
// second interval
CConstraintInterval *pciSecond = PciSecondInterval(mp, mdid, colref);
CConstraintArray *pdrgpcst = GPOS_NEW(mp) CConstraintArray(mp);
pdrgpcst->Append(pciFirst);
pdrgpcst->Append(pciSecond);
return GPOS_NEW(mp) CConstraintDisjunction(mp, pdrgpcst);
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::EresUnittest_CDisjunction
//
// @doc:
// Conjunction test
//
//---------------------------------------------------------------------------
GPOS_RESULT
CConstraintTest::EresUnittest_CDisjunction()
{
// create memory pool
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
// setup a file-based provider
CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
pmdp->AddRef();
CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);
CConstExprEvaluatorForDates *pceeval =
GPOS_NEW(mp) CConstExprEvaluatorForDates(mp);
// install opt context in TLS
CAutoOptCtxt aoc(mp, &mda, pceeval, CTestUtils::GetCostModel(mp));
GPOS_ASSERT(nullptr != COptCtxt::PoctxtFromTLS()->Pcomp());
IMDTypeInt8 *pmdtypeint8 =
(IMDTypeInt8 *) mda.PtMDType<IMDTypeInt8>(CTestUtils::m_sysidDefault);
IMDId *mdid = pmdtypeint8->MDId();
CExpression *pexprGet1 = CTestUtils::PexprLogicalGet(mp);
CColRefSet *pcrs1 = pexprGet1->DeriveOutputColumns();
CColRef *pcr1 = pcrs1->PcrAny();
CExpression *pexprGet2 = CTestUtils::PexprLogicalGet(mp);
CColRefSet *pcrs2 = pexprGet2->DeriveOutputColumns();
CColRef *pcr2 = pcrs2->PcrAny();
CConstraintDisjunction *pcdisj1 = Pcstdisjunction(mp, mdid, pcr1);
PrintConstraint(mp, pcdisj1);
GPOS_ASSERT(!pcdisj1->FContradiction());
CConstraintDisjunction *pcdisj2 = Pcstdisjunction(mp, mdid, pcr2);
PrintConstraint(mp, pcdisj2);
CConstraintArray *pdrgpcst = GPOS_NEW(mp) CConstraintArray(mp);
pcdisj1->AddRef();
pcdisj2->AddRef();
pdrgpcst->Append(pcdisj1);
pdrgpcst->Append(pcdisj2);
CConstraintDisjunction *pcdisjTop =
GPOS_NEW(mp) CConstraintDisjunction(mp, pdrgpcst);
PrintConstraint(mp, pcdisjTop);
// containment
GPOS_ASSERT(!pcdisj1->Contains(pcdisj2));
GPOS_ASSERT(!pcdisj2->Contains(pcdisj1));
GPOS_ASSERT(!pcdisj1->Contains(pcdisjTop));
GPOS_ASSERT(pcdisjTop->Contains(pcdisj1));
GPOS_ASSERT(!pcdisj2->Contains(pcdisjTop));
GPOS_ASSERT(pcdisjTop->Contains(pcdisj2));
// equality
GPOS_ASSERT(!pcdisj1->Equals(pcdisjTop));
GPOS_ASSERT(!pcdisjTop->Equals(pcdisj2));
pcdisjTop->Release();
pcdisj1->Release();
pcdisj2->Release();
pexprGet1->Release();
pexprGet2->Release();
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::EresUnittest_CNegation
//
// @doc:
// Conjunction test
//
//---------------------------------------------------------------------------
GPOS_RESULT
CConstraintTest::EresUnittest_CNegation()
{
// create memory pool
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
// setup a file-based provider
CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
pmdp->AddRef();
CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);
CConstExprEvaluatorForDates *pceeval =
GPOS_NEW(mp) CConstExprEvaluatorForDates(mp);
// install opt context in TLS
CAutoOptCtxt aoc(mp, &mda, pceeval, CTestUtils::GetCostModel(mp));
GPOS_ASSERT(nullptr != COptCtxt::PoctxtFromTLS()->Pcomp());
IMDTypeInt8 *pmdtypeint8 =
(IMDTypeInt8 *) mda.PtMDType<IMDTypeInt8>(CTestUtils::m_sysidDefault);
IMDId *mdid = pmdtypeint8->MDId();
CExpression *pexprGet = CTestUtils::PexprLogicalGet(mp);
CColRefSet *pcrs = pexprGet->DeriveOutputColumns();
CColRef *colref = pcrs->PcrAny();
CConstraintInterval *pci = PciFirstInterval(mp, mdid, colref);
PrintConstraint(mp, pci);
pci->AddRef();
CConstraintNegation *pcn1 = GPOS_NEW(mp) CConstraintNegation(mp, pci);
PrintConstraint(mp, pcn1);
pcn1->AddRef();
CConstraintNegation *pcn2 = GPOS_NEW(mp) CConstraintNegation(mp, pcn1);
PrintConstraint(mp, pcn2);
// containment
GPOS_ASSERT(!pcn1->Contains(pci));
GPOS_ASSERT(!pci->Contains(pcn1));
GPOS_ASSERT(!pcn2->Contains(pcn1));
GPOS_ASSERT(!pcn1->Contains(pcn2));
GPOS_ASSERT(pci->Contains(pcn2));
GPOS_ASSERT(pcn2->Contains(pci));
// equality
GPOS_ASSERT(!pcn1->Equals(pci));
GPOS_ASSERT(!pcn1->Equals(pcn2));
GPOS_ASSERT(pci->Equals(pcn2));
pcn2->Release();
pcn1->Release();
pci->Release();
pexprGet->Release();
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::EresUnittest_CIntervalFromScalarExpr
//
// @doc:
// Interval from scalar tests
//
//---------------------------------------------------------------------------
GPOS_RESULT
CConstraintTest::EresUnittest_CIntervalFromScalarExpr()
{
// create memory pool
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
// setup a file-based provider
CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
pmdp->AddRef();
CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);
CConstExprEvaluatorForDates *pceeval =
GPOS_NEW(mp) CConstExprEvaluatorForDates(mp);
// install opt context in TLS
CAutoOptCtxt aoc(mp, &mda, pceeval, CTestUtils::GetCostModel(mp));
GPOS_ASSERT(nullptr != COptCtxt::PoctxtFromTLS()->Pcomp());
CExpression *pexprGet = CTestUtils::PexprLogicalGet(mp);
CColRefSet *pcrs = pexprGet->DeriveOutputColumns();
CColRef *colref = pcrs->PcrAny();
// from ScalarCmp
GPOS_RESULT eres1 = EresUnittest_CIntervalFromScalarCmp(mp, &mda, colref);
// from ScalarBool
GPOS_RESULT eres2 =
EresUnittest_CIntervalFromScalarBoolOp(mp, &mda, colref);
pexprGet->Release();
if (GPOS_OK == eres1 && GPOS_OK == eres2)
{
return GPOS_OK;
}
return GPOS_FAILED;
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::EresUnittest_CConstraintFromScalarExpr
//
// @doc:
// Constraint from scalar tests
//
//---------------------------------------------------------------------------
GPOS_RESULT
CConstraintTest::EresUnittest_CConstraintFromScalarExpr()
{
// create memory pool
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
// setup a file-based provider
CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
pmdp->AddRef();
CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);
CConstExprEvaluatorForDates *pceeval =
GPOS_NEW(mp) CConstExprEvaluatorForDates(mp);
// install opt context in TLS
CAutoOptCtxt aoc(mp, &mda, pceeval, CTestUtils::GetCostModel(mp));
GPOS_ASSERT(nullptr != COptCtxt::PoctxtFromTLS()->Pcomp());
CExpression *pexprGet1 = CTestUtils::PexprLogicalGet(mp);
CColRefSet *pcrs1 = pexprGet1->DeriveOutputColumns();
CColRef *pcr1 = pcrs1->PcrAny();
CExpression *pexprGet2 = CTestUtils::PexprLogicalGet(mp);
CColRefSet *pcrs2 = pexprGet2->DeriveOutputColumns();
CColRef *pcr2 = pcrs2->PcrAny();
CColRefSetArray *pdrgpcrs = nullptr;
// expression with 1 column
CExpression *pexpr = PexprScalarCmp(mp, &mda, pcr1, IMDType::EcmptG, 15);
CConstraint *pcnstr =
CConstraint::PcnstrFromScalarExpr(mp, pexpr, &pdrgpcrs);
PrintConstraint(mp, pcnstr);
PrintEquivClasses(mp, pdrgpcrs);
pdrgpcrs->Release();
pdrgpcrs = nullptr;
pcnstr->Release();
pexpr->Release();
// expression with 2 columns
CExpressionArray *pdrgpexpr = GPOS_NEW(mp) CExpressionArray(mp);
pdrgpexpr->Append(PexprScalarCmp(mp, &mda, pcr1, IMDType::EcmptG, 15));
pdrgpexpr->Append(PexprScalarCmp(mp, &mda, pcr2, IMDType::EcmptL, 20));
CExpression *pexprAnd =
CUtils::PexprScalarBoolOp(mp, CScalarBoolOp::EboolopAnd, pdrgpexpr);
(void) pexprAnd->PdpDerive();
CConstraint *pcnstrAnd =
CConstraint::PcnstrFromScalarExpr(mp, pexprAnd, &pdrgpcrs);
PrintConstraint(mp, pcnstrAnd);
PrintEquivClasses(mp, pdrgpcrs);
pdrgpcrs->Release();
pdrgpcrs = nullptr;
pcnstrAnd->Release();
pexprAnd->Release();
// equality predicate with 2 columns
CExpression *pexprEq = CUtils::PexprScalarEqCmp(mp, pcr1, pcr2);
(void) pexprEq->PdpDerive();
CConstraint *pcnstrEq =
CConstraint::PcnstrFromScalarExpr(mp, pexprEq, &pdrgpcrs);
PrintConstraint(mp, pcnstrEq);
PrintEquivClasses(mp, pdrgpcrs);
pcnstrEq->Release();
pexprEq->Release();
pdrgpcrs->Release();
pexprGet1->Release();
pexprGet2->Release();
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::EresUnittest_CConstraintIntervalConvertsTo
//
// @doc:
// Tests CConstraintInterval::ConvertsToIn and
// CConstraintInterval::ConvertsToNotIn
//
//---------------------------------------------------------------------------
GPOS_RESULT
CConstraintTest::EresUnittest_CConstraintIntervalConvertsTo()
{
// create memory pool
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
// setup a file-based provider
CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
pmdp->AddRef();
CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);
CConstExprEvaluatorForDates *pceeval =
GPOS_NEW(mp) CConstExprEvaluatorForDates(mp);
// install opt context in TLS
CAutoOptCtxt aoc(mp, &mda, pceeval, CTestUtils::GetCostModel(mp));
GPOS_ASSERT(nullptr != COptCtxt::PoctxtFromTLS()->Pcomp());
// create a range which should convert to an IN array expression
const SRangeInfo rgRangeInfoIn[] = {
{CRange::EriIncluded, -1000, CRange::EriIncluded, -1000},
{CRange::EriIncluded, -5, CRange::EriIncluded, -5},
{CRange::EriIncluded, 0, CRange::EriIncluded, 0}};
// metadata id
IMDTypeInt8 *pmdtypeint8 =
(IMDTypeInt8 *) mda.PtMDType<IMDTypeInt8>(CTestUtils::m_sysidDefault);
IMDId *mdid = pmdtypeint8->MDId();
// get a column ref
CExpression *pexprGet = CTestUtils::PexprLogicalGet(mp);
CColRefSet *pcrs = pexprGet->DeriveOutputColumns();
CColRef *colref = pcrs->PcrAny();
// create constraint
CRangeArray *pdrgprng =
Pdrgprng(mp, mdid, rgRangeInfoIn, GPOS_ARRAY_SIZE(rgRangeInfoIn));
CConstraintInterval *pcnstin =
GPOS_NEW(mp) CConstraintInterval(mp, colref, pdrgprng, true);
PrintConstraint(mp, pcnstin);
// should convert to in
GPOS_ASSERT(pcnstin->FConvertsToIn());
GPOS_ASSERT(!pcnstin->FConvertsToNotIn());
CConstraintInterval *pcnstNotIn = pcnstin->PciComplement(mp);
// should convert to a not in statement after taking the complement
GPOS_ASSERT(pcnstNotIn->FConvertsToNotIn());
GPOS_ASSERT(!pcnstNotIn->FConvertsToIn());
pcnstin->Release();
pcnstNotIn->Release();
pexprGet->Release();
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::EresUnittest_CConstraintIntervalPexpr
//
// @doc:
// Tests CConstraintInterval::PexprConstructArrayScalar
//
//---------------------------------------------------------------------------
GPOS_RESULT
CConstraintTest::EresUnittest_CConstraintIntervalPexpr()
{
// create memory pool
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
// setup a file-based provider
CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
pmdp->AddRef();
CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);
CConstExprEvaluatorForDates *pceeval =
GPOS_NEW(mp) CConstExprEvaluatorForDates(mp);
// install opt context in TLS
CAutoOptCtxt aoc(mp, &mda, pceeval, CTestUtils::GetCostModel(mp));
GPOS_RTL_ASSERT(nullptr != COptCtxt::PoctxtFromTLS()->Pcomp());
CAutoTraceFlag atf(EopttraceArrayConstraints, true);
// create a range which should convert to an IN array expression
const SRangeInfo rgRangeInfoIn[] = {
{CRange::EriIncluded, -1000, CRange::EriIncluded, -1000},
{CRange::EriIncluded, -5, CRange::EriIncluded, -5},
{CRange::EriIncluded, 0, CRange::EriIncluded, 0}};
// metadata id
IMDTypeInt8 *pmdtypeint8 =
(IMDTypeInt8 *) mda.PtMDType<IMDTypeInt8>(CTestUtils::m_sysidDefault);
IMDId *mdid = pmdtypeint8->MDId();
// get a column ref
CExpression *pexprGet = CTestUtils::PexprLogicalGet(mp);
CColRefSet *pcrs = pexprGet->DeriveOutputColumns();
CColRef *colref = pcrs->PcrAny();
CRangeArray *pdrgprng = nullptr;
CConstraintInterval *pcnstin = nullptr;
CExpression *pexpr = nullptr;
CConstraintInterval *pcnstNotIn = nullptr;
// IN CONSTRAINT FOR SIMPLE INTERVAL (WITHOUT NULL)
// create constraint
pdrgprng =
Pdrgprng(mp, mdid, rgRangeInfoIn, GPOS_ARRAY_SIZE(rgRangeInfoIn));
pcnstin = GPOS_NEW(mp) CConstraintInterval(mp, colref, pdrgprng, false);
pexpr = pcnstin->PexprScalar(mp); // pexpr is owned by the constraint
PrintConstraint(mp, pcnstin);
GPOS_RTL_ASSERT(!pcnstin->FConvertsToNotIn());
GPOS_RTL_ASSERT(pcnstin->FConvertsToIn());
GPOS_RTL_ASSERT(CUtils::FScalarArrayCmp(pexpr));
GPOS_RTL_ASSERT(3 ==
CUtils::UlCountOperator(pexpr, COperator::EopScalarConst));
pcnstin->Release();
// IN CONSTRAINT FOR SIMPLE INTERVAL WITH NULL
// create constraint
pdrgprng =
Pdrgprng(mp, mdid, rgRangeInfoIn, GPOS_ARRAY_SIZE(rgRangeInfoIn));
pcnstin = GPOS_NEW(mp) CConstraintInterval(mp, colref, pdrgprng, true);
pexpr = pcnstin->PexprScalar(mp); // pexpr is owned by the constraint
PrintConstraint(mp, pcnstin);
GPOS_RTL_ASSERT(!pcnstin->FConvertsToNotIn());
GPOS_RTL_ASSERT(pcnstin->FConvertsToIn());
GPOS_RTL_ASSERT(CUtils::FScalarBoolOp(pexpr, CScalarBoolOp::EboolopOr));
GPOS_RTL_ASSERT(CUtils::FScalarArrayCmp((*pexpr)[0]));
GPOS_RTL_ASSERT(
3 == CUtils::UlCountOperator((*pexpr)[0], COperator::EopScalarConst));
GPOS_RTL_ASSERT(CUtils::FScalarNullTest((*pexpr)[1]));
pcnstin->Release();
// NOT IN CONSTRAINT FOR SIMPLE INTERVAL WITHOUT NULL
// create constraint
pdrgprng =
Pdrgprng(mp, mdid, rgRangeInfoIn, GPOS_ARRAY_SIZE(rgRangeInfoIn));
pcnstin = GPOS_NEW(mp) CConstraintInterval(mp, colref, pdrgprng, true);
pcnstNotIn = pcnstin->PciComplement(mp);
pcnstin->Release();
pexpr = pcnstNotIn->PexprScalar(mp); // pexpr is owned by the constraint
PrintConstraint(mp, pcnstNotIn);
GPOS_RTL_ASSERT(pcnstNotIn->FConvertsToNotIn());
GPOS_RTL_ASSERT(!pcnstNotIn->FConvertsToIn());
GPOS_RTL_ASSERT(CUtils::FScalarArrayCmp(pexpr));
GPOS_RTL_ASSERT(3 ==
CUtils::UlCountOperator(pexpr, COperator::EopScalarConst));
pcnstNotIn->Release();
// NOT IN CONSTRAINT FOR SIMPLE INTERVAL WITH NULL
// create constraint
pdrgprng =
Pdrgprng(mp, mdid, rgRangeInfoIn, GPOS_ARRAY_SIZE(rgRangeInfoIn));
pcnstin = GPOS_NEW(mp) CConstraintInterval(mp, colref, pdrgprng, false);
pcnstNotIn = pcnstin->PciComplement(mp);
pcnstin->Release();
pexpr = pcnstNotIn->PexprScalar(mp); // pexpr is owned by the constraint
PrintConstraint(mp, pcnstNotIn);
GPOS_RTL_ASSERT(pcnstNotIn->FConvertsToNotIn());
GPOS_RTL_ASSERT(!pcnstNotIn->FConvertsToIn());
GPOS_RTL_ASSERT(CUtils::FScalarBoolOp(pexpr, CScalarBoolOp::EboolopOr));
GPOS_RTL_ASSERT(CUtils::FScalarArrayCmp((*pexpr)[0]));
GPOS_RTL_ASSERT(3 ==
CUtils::UlCountOperator(pexpr, COperator::EopScalarConst));
GPOS_RTL_ASSERT(CUtils::FScalarNullTest((*pexpr)[1]));
pcnstNotIn->Release();
pexprGet->Release();
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::EresUnittest_CConstraintIntervalFromArrayExpr
//
// @doc:
// Tests CConstraintInterval::PcnstrIntervalFromScalarArrayCmp
//
//---------------------------------------------------------------------------
GPOS_RESULT
CConstraintTest::EresUnittest_CConstraintIntervalFromArrayExpr()
{
// create memory pool
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
// setup a file-based provider
CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
pmdp->AddRef();
CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);
CConstExprEvaluatorForDates *pceeval =
GPOS_NEW(mp) CConstExprEvaluatorForDates(mp);
// install opt context in TLS
CAutoOptCtxt aoc(mp, &mda, pceeval, CTestUtils::GetCostModel(mp));
GPOS_ASSERT(nullptr != COptCtxt::PoctxtFromTLS()->Pcomp());
CAutoTraceFlag atf(EopttraceArrayConstraints, true);
// Create an IN array expression
CExpression *pexpr = CTestUtils::PexprLogicalSelectArrayCmp(mp);
// get a ref to the comparison column
CColRef *colref = pexpr->DeriveOutputColumns()->PcrAny();
// remove the array child
CExpression *pexprArrayComp = (*pexpr->PdrgPexpr())[1];
GPOS_ASSERT(CUtils::FScalarArrayCmp(pexprArrayComp));
CConstraintInterval *pcnstIn =
CConstraintInterval::PciIntervalFromScalarExpr(mp, pexprArrayComp,
colref);
GPOS_ASSERT(CConstraint::EctInterval == pcnstIn->Ect());
GPOS_ASSERT(
pcnstIn->Pdrgprng()->Size() ==
CUtils::UlCountOperator(pexprArrayComp, COperator::EopScalarConst));
pcnstIn->Release();
pexpr->Release();
// test a NOT IN expression
CExpression *pexprNotIn = CTestUtils::PexprLogicalSelectArrayCmp(
mp, CScalarArrayCmp::EarrcmpAll, IMDType::EcmptNEq);
CExpression *pexprArrayNotInComp = (*pexprNotIn->PdrgPexpr())[1];
CColRef *pcrNot = pexprNotIn->DeriveOutputColumns()->PcrAny();
CConstraintInterval *pcnstNotIn =
CConstraintInterval::PciIntervalFromScalarExpr(mp, pexprArrayNotInComp,
pcrNot);
GPOS_ASSERT(CConstraint::EctInterval == pcnstNotIn->Ect());
// a NOT IN range array should have one more element than the expression array consts
GPOS_ASSERT(pcnstNotIn->Pdrgprng()->Size() ==
1 + CUtils::UlCountOperator(pexprArrayNotInComp,
COperator::EopScalarConst));
pexprNotIn->Release();
pcnstNotIn->Release();
// create an IN expression with repeated values
IntPtrArray *pdrgpi = GPOS_NEW(mp) IntPtrArray(mp);
INT aiValsRepeat[] = {5, 1, 2, 5, 3, 4, 5};
ULONG aiValsLength = sizeof(aiValsRepeat) / sizeof(INT);
for (ULONG ul = 0; ul < aiValsLength; ul++)
{
pdrgpi->Append(GPOS_NEW(mp) INT(aiValsRepeat[ul]));
}
CExpression *pexprInRepeatsSelect = CTestUtils::PexprLogicalSelectArrayCmp(
mp, CScalarArrayCmp::EarrcmpAny, IMDType::EcmptEq, pdrgpi);
CColRef *pcrInRepeats =
pexprInRepeatsSelect->DeriveOutputColumns()->PcrAny();
CExpression *pexprArrayCmpRepeats = (*pexprInRepeatsSelect->PdrgPexpr())[1];
// add 2 repeated values and one unique
CConstraintInterval *pcnstInRepeats =
CConstraintInterval::PciIntervalFromScalarExpr(mp, pexprArrayCmpRepeats,
pcrInRepeats);
GPOS_ASSERT(5 == pcnstInRepeats->Pdrgprng()->Size());
pexprInRepeatsSelect->Release();
pcnstInRepeats->Release();
// create a NOT IN expression with repeated values
CExpression *pexprNotInRepeatsSelect =
CTestUtils::PexprLogicalSelectArrayCmp(mp, CScalarArrayCmp::EarrcmpAll,
IMDType::EcmptNEq, pdrgpi);
CColRef *pcrNotInRepeats =
pexprNotInRepeatsSelect->DeriveOutputColumns()->PcrAny();
CExpression *pexprNotInArrayCmpRepeats =
(*pexprNotInRepeatsSelect->PdrgPexpr())[1];
CConstraintInterval *pcnstNotInRepeats =
CConstraintInterval::PciIntervalFromScalarExpr(
mp, pexprNotInArrayCmpRepeats, pcrNotInRepeats);
// a total of 5 unique ScalarConsts in the expression will result in 6 ranges
GPOS_ASSERT(6 == pcnstNotInRepeats->Pdrgprng()->Size());
pexprNotInRepeatsSelect->Release();
pcnstNotInRepeats->Release();
pdrgpi->Release();
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::EresUnittest_CConstraintIntervalFromArrayExprIncludesNull
//
// @doc:
// Tests CConstraintInterval::PcnstrIntervalFromScalarArrayCmp in cases
// where NULL is in the scalar array expression
//
//---------------------------------------------------------------------------
GPOS_RESULT
EresUnittest_CConstraintIntervalFromArrayExprIncludesNull()
{
// create memory pool
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
// setup a file-based provider
CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
pmdp->AddRef();
CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);
CConstExprEvaluatorForDates *pceeval =
GPOS_NEW(mp) CConstExprEvaluatorForDates(mp);
// install opt context in TLS
CAutoOptCtxt aoc(mp, &mda, pceeval, CTestUtils::GetCostModel(mp));
GPOS_ASSERT(nullptr != COptCtxt::PoctxtFromTLS()->Pcomp());
CAutoTraceFlag atf(EopttraceArrayConstraints, true);
// test for includes NULL
// create an IN expression with repeated values
IntPtrArray *pdrgpi = GPOS_NEW(mp) IntPtrArray(mp);
INT rngiValues[] = {1, 2};
ULONG ulValsLength = GPOS_ARRAY_SIZE(rngiValues);
for (ULONG ul = 0; ul < ulValsLength; ul++)
{
pdrgpi->Append(GPOS_NEW(mp) INT(rngiValues[ul]));
}
CExpression *pexprIn = CTestUtils::PexprLogicalSelectArrayCmp(
mp, CScalarArrayCmp::EarrcmpAny, IMDType::EcmptEq, pdrgpi);
CExpression *pexprArrayChild = (*(*pexprIn)[1])[1];
// create a int4 datum
const IMDTypeInt4 *pmdtypeint4 = mda.PtMDType<IMDTypeInt4>();
IDatumInt4 *pdatumNull = pmdtypeint4->CreateInt4Datum(mp, 0, true);
CExpression *pexprConstNull = GPOS_NEW(mp)
CExpression(mp, GPOS_NEW(mp) CScalarConst(mp, (IDatum *) pdatumNull));
pexprArrayChild->PdrgPexpr()->Append(pexprConstNull);
CColRef *colref = pexprIn->DeriveOutputColumns()->PcrAny();
CConstraintInterval *pci = CConstraintInterval::PciIntervalFromScalarExpr(
mp, (*pexprIn)[1], colref);
GPOS_RTL_ASSERT(!pci->FIncludesNull());
GPOS_RTL_ASSERT(2 == pci->Pdrgprng()->Size());
pexprIn->Release();
pci->Release();
pdrgpi->Release();
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::EresUnittest_CIntervalFromScalarCmp
//
// @doc:
// Interval from scalar comparison
//
//---------------------------------------------------------------------------
GPOS_RESULT
CConstraintTest::EresUnittest_CIntervalFromScalarCmp(CMemoryPool *mp,
CMDAccessor *md_accessor,
CColRef *colref)
{
IMDType::ECmpType rgecmpt[] = {
IMDType::EcmptEq, IMDType::EcmptNEq, IMDType::EcmptL,
IMDType::EcmptLEq, IMDType::EcmptG, IMDType::EcmptGEq,
};
for (ULONG ul = 0; ul < GPOS_ARRAY_SIZE(rgecmpt); ul++)
{
CExpression *pexprScCmp =
PexprScalarCmp(mp, md_accessor, colref, rgecmpt[ul], 4);
CConstraintInterval *pci =
CConstraintInterval::PciIntervalFromScalarExpr(mp, pexprScCmp,
colref);
PrintConstraint(mp, pci);
pci->Release();
pexprScCmp->Release();
}
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::EresUnittest_CIntervalFromScalarBoolOp
//
// @doc:
// Interval from scalar bool op
//
//---------------------------------------------------------------------------
GPOS_RESULT
CConstraintTest::EresUnittest_CIntervalFromScalarBoolOp(
CMemoryPool *mp, CMDAccessor *md_accessor, CColRef *colref)
{
// AND
CExpressionArray *pdrgpexpr = GPOS_NEW(mp) CExpressionArray(mp);
pdrgpexpr->Append(
PexprScalarCmp(mp, md_accessor, colref, IMDType::EcmptL, 5));
pdrgpexpr->Append(
PexprScalarCmp(mp, md_accessor, colref, IMDType::EcmptGEq, 0));
CExpression *pexpr =
CUtils::PexprScalarBoolOp(mp, CScalarBoolOp::EboolopAnd, pdrgpexpr);
(void) pexpr->PdpDerive();
CConstraintInterval *pciAnd =
CConstraintInterval::PciIntervalFromScalarExpr(mp, pexpr, colref);
PrintConstraint(mp, pciAnd);
pciAnd->Release();
(void) pexpr->Release();
// OR
pdrgpexpr = GPOS_NEW(mp) CExpressionArray(mp);
pdrgpexpr->Append(
PexprScalarCmp(mp, md_accessor, colref, IMDType::EcmptL, 5));
pdrgpexpr->Append(
PexprScalarCmp(mp, md_accessor, colref, IMDType::EcmptGEq, 10));
pexpr = CUtils::PexprScalarBoolOp(mp, CScalarBoolOp::EboolopOr, pdrgpexpr);
(void) pexpr->PdpDerive();
CConstraintInterval *pciOr =
CConstraintInterval::PciIntervalFromScalarExpr(mp, pexpr, colref);
PrintConstraint(mp, pciOr);
pciOr->Release();
pexpr->Release();
// NOT
pdrgpexpr = GPOS_NEW(mp) CExpressionArray(mp);
pdrgpexpr->Append(
CUtils::PexprIsNull(mp, CUtils::PexprScalarIdent(mp, colref)));
pexpr = CUtils::PexprScalarBoolOp(mp, CScalarBoolOp::EboolopNot, pdrgpexpr);
(void) pexpr->PdpDerive();
CConstraintInterval *pciNot =
CConstraintInterval::PciIntervalFromScalarExpr(mp, pexpr, colref);
PrintConstraint(mp, pciNot);
pciNot->Release();
pexpr->Release();
return GPOS_OK;
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::PexprScalarCmp
//
// @doc:
// Generate comparison expression
//
//---------------------------------------------------------------------------
CExpression *
CConstraintTest::PexprScalarCmp(CMemoryPool *mp, CMDAccessor *md_accessor,
CColRef *colref, IMDType::ECmpType cmp_type,
LINT val)
{
CExpression *pexprConst = CUtils::PexprScalarConstInt8(mp, val);
const IMDTypeInt8 *pmdtypeint8 = md_accessor->PtMDType<IMDTypeInt8>();
IMDId *mdid_op = pmdtypeint8->GetMdidForCmpType(cmp_type);
mdid_op->AddRef();
const CMDName mdname = md_accessor->RetrieveScOp(mdid_op)->Mdname();
CWStringConst strOpName(mdname.GetMDName()->GetBuffer());
CExpression *pexpr =
CUtils::PexprScalarCmp(mp, colref, pexprConst, strOpName, mdid_op);
(void) pexpr->PdpDerive();
return pexpr;
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::PciFirstInterval
//
// @doc:
// Create an interval
//
//---------------------------------------------------------------------------
CConstraintInterval *
CConstraintTest::PciFirstInterval(CMemoryPool *mp, IMDId *mdid, CColRef *colref)
{
const SRangeInfo rgRangeInfo[] = {
{CRange::EriExcluded, -1000, CRange::EriIncluded, -20},
{CRange::EriExcluded, -15, CRange::EriExcluded, -5},
{CRange::EriIncluded, 0, CRange::EriExcluded, 5},
{CRange::EriIncluded, 10, CRange::EriIncluded, 10},
{CRange::EriExcluded, 20, CRange::EriExcluded, 1000},
};
CRangeArray *pdrgprng =
Pdrgprng(mp, mdid, rgRangeInfo, GPOS_ARRAY_SIZE(rgRangeInfo));
return GPOS_NEW(mp)
CConstraintInterval(mp, colref, pdrgprng, true /*is_null*/);
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::PciSecondInterval
//
// @doc:
// Create an interval
//
//---------------------------------------------------------------------------
CConstraintInterval *
CConstraintTest::PciSecondInterval(CMemoryPool *mp, IMDId *mdid,
CColRef *colref)
{
const SRangeInfo rgRangeInfo[] = {
{CRange::EriExcluded, -30, CRange::EriExcluded, 1},
{CRange::EriIncluded, 3, CRange::EriIncluded, 3},
{CRange::EriExcluded, 10, CRange::EriExcluded, 25},
};
CRangeArray *pdrgprng =
Pdrgprng(mp, mdid, rgRangeInfo, GPOS_ARRAY_SIZE(rgRangeInfo));
return GPOS_NEW(mp)
CConstraintInterval(mp, colref, pdrgprng, false /*is_null*/);
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::Pdrgprng
//
// @doc:
// Construct an array of ranges to be used to create an interval
//
//---------------------------------------------------------------------------
CRangeArray *
CConstraintTest::Pdrgprng(CMemoryPool *mp, IMDId *mdid,
const SRangeInfo rgRangeInfo[], ULONG ulRanges)
{
CRangeArray *pdrgprng = GPOS_NEW(mp) CRangeArray(mp);
for (ULONG ul = 0; ul < ulRanges; ul++)
{
SRangeInfo rnginfo = rgRangeInfo[ul];
mdid->AddRef();
CRange *prange = GPOS_NEW(mp)
CRange(mdid, COptCtxt::PoctxtFromTLS()->Pcomp(),
GPOS_NEW(mp) CDatumInt8GPDB(CTestUtils::m_sysidDefault,
(LINT) rnginfo.iLeft),
rnginfo.eriLeft,
GPOS_NEW(mp) CDatumInt8GPDB(CTestUtils::m_sysidDefault,
(LINT) rnginfo.iRight),
rnginfo.eriRight);
pdrgprng->Append(prange);
}
return pdrgprng;
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::PrintConstraint
//
// @doc:
// Print a constraint and its expression representation
//
//---------------------------------------------------------------------------
void
CConstraintTest::PrintConstraint(CMemoryPool *mp, CConstraint *pcnstr)
{
CExpression *pexpr = pcnstr->PexprScalar(mp);
// debug print
CAutoTrace at(mp);
at.Os() << std::endl;
at.Os() << "CONSTRAINT:" << std::endl
<< *pcnstr << std::endl
<< "EXPR:" << std::endl
<< *pexpr << std::endl;
}
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::PrintEquivClasses
//
// @doc:
// Print equivalent classes
//
//---------------------------------------------------------------------------
void
CConstraintTest::PrintEquivClasses(CMemoryPool *mp, CColRefSetArray *pdrgpcrs,
BOOL fExpected)
{
// debug print
CAutoTrace at(mp);
at.Os() << std::endl;
if (fExpected)
{
at.Os() << "EXPECTED ";
}
else
{
at.Os() << "ACTUAL ";
}
at.Os() << "EQUIVALENCE CLASSES: [ ";
if (nullptr == pdrgpcrs)
{
at.Os() << "]" << std::endl;
return;
}
for (ULONG ul = 0; ul < pdrgpcrs->Size(); ul++)
{
at.Os() << "{" << *(*pdrgpcrs)[ul] << "} ";
}
at.Os() << "]" << std::endl;
}
#ifdef GPOS_DEBUG
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::EresUnittest_NegativeTests
//
// @doc:
// Tests for unconstrainable types.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CConstraintTest::EresUnittest_NegativeTests()
{
// create memory pool
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
// setup a file-based provider
CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
pmdp->AddRef();
// we need to use an auto pointer for the cache here to ensure
// deleting memory of cached objects when we throw
CAutoP<CMDAccessor::MDCache> apcache;
apcache =
CCacheFactory::CreateCache<gpopt::IMDCacheObject *, gpopt::CMDKey *>(
true, // fUnique
0 /* unlimited cache quota */, CMDKey::UlHashMDKey,
CMDKey::FEqualMDKey);
CMDAccessor::MDCache *pcache = apcache.Value();
CMDAccessor mda(mp, pcache, CTestUtils::m_sysidDefault, pmdp);
CConstExprEvaluatorForDates *pceeval =
GPOS_NEW(mp) CConstExprEvaluatorForDates(mp);
// install opt context in TLS
CAutoOptCtxt aoc(mp, &mda, pceeval, CTestUtils::GetCostModel(mp));
GPOS_ASSERT(nullptr != COptCtxt::PoctxtFromTLS()->Pcomp());
const IMDType *pmdtype = mda.RetrieveType(&CMDIdGPDB::m_mdid_text);
CWStringConst str(GPOS_WSZ_LIT("text_col"));
CName name(mp, &str);
CAutoP<CColRef> colref(COptCtxt::PoctxtFromTLS()->Pcf()->PcrCreate(
pmdtype, default_type_modifier, name));
// create a text interval: ['baz', 'foobar')
CAutoP<CWStringDynamic> pstrLower1(
GPOS_NEW(mp) CWStringDynamic(mp, GPOS_WSZ_LIT("AAAAB2Jheg==")));
CAutoP<CWStringDynamic> pstrUpper1(
GPOS_NEW(mp) CWStringDynamic(mp, GPOS_WSZ_LIT("AAAACmZvb2Jhcg==")));
const LINT lLower1 = 571163436;
const LINT lUpper1 = 322061118;
// 'text' is not a constrainable type, so the interval construction should assert-fail
CConstraintInterval *pciFirst = CTestUtils::PciGenericInterval(
mp, &mda, CMDIdGPDB::m_mdid_text, colref.Value(), pstrLower1.Value(),
lLower1, CRange::EriIncluded, pstrUpper1.Value(), lUpper1,
CRange::EriExcluded);
PrintConstraint(mp, pciFirst);
pciFirst->Release();
return GPOS_OK;
}
#endif // GPOS_DEBUG
//---------------------------------------------------------------------------
// @function:
// CConstraintTest::EresUnittest_ConstraintsOnDates
// @doc:
// Test constraints on date intervals.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CConstraintTest::EresUnittest_ConstraintsOnDates()
{
CAutoTraceFlag atf(EopttraceEnableConstantExpressionEvaluation,
true /*value*/);
// create memory pool
CAutoMemoryPool amp;
CMemoryPool *mp = amp.Pmp();
// setup a file-based provider
CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
pmdp->AddRef();
CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);
CConstExprEvaluatorForDates *pceeval =
GPOS_NEW(mp) CConstExprEvaluatorForDates(mp);
// install opt context in TLS
CAutoOptCtxt aoc(mp, &mda, pceeval, CTestUtils::GetCostModel(mp));
GPOS_ASSERT(nullptr != COptCtxt::PoctxtFromTLS()->Pcomp());
const IMDType *pmdtype = mda.RetrieveType(&CMDIdGPDB::m_mdid_date);
CWStringConst str(GPOS_WSZ_LIT("date_col"));
CName name(mp, &str);
CAutoP<CColRef> colref(COptCtxt::PoctxtFromTLS()->Pcf()->PcrCreate(
pmdtype, default_type_modifier, name));
// create a date interval: ['01-01-2012', '01-21-2012')
CWStringDynamic pstrLowerDate1(mp, wszInternalRepresentationFor2012_01_01);
CWStringDynamic pstrUpperDate1(mp, wszInternalRepresentationFor2012_01_21);
CConstraintInterval *pciFirst = CTestUtils::PciGenericInterval(
mp, &mda, CMDIdGPDB::m_mdid_date, colref.Value(), &pstrLowerDate1,
lInternalRepresentationFor2012_01_01, CRange::EriIncluded,
&pstrUpperDate1, lInternalRepresentationFor2012_01_21,
CRange::EriExcluded);
PrintConstraint(mp, pciFirst);
// create a date interval: ['01-02-2012', '01-22-2012')
CWStringDynamic pstrLowerDate2(mp, wszInternalRepresentationFor2012_01_02);
CWStringDynamic pstrUpperDate2(mp, wszInternalRepresentationFor2012_01_22);
CConstraintInterval *pciSecond = CTestUtils::PciGenericInterval(
mp, &mda, CMDIdGPDB::m_mdid_date, colref.Value(), &pstrLowerDate2,
lInternalRepresentationFor2012_01_02, CRange::EriIncluded,
&pstrUpperDate2, lInternalRepresentationFor2012_01_22,
CRange::EriExcluded);
PrintConstraint(mp, pciSecond);
// intersection
CConstraintInterval *pciIntersect = pciFirst->PciIntersect(mp, pciSecond);
PrintConstraint(mp, pciIntersect);
CConstraintInterval *pciIntersectExpected = CTestUtils::PciGenericInterval(
mp, &mda, CMDIdGPDB::m_mdid_date, colref.Value(), &pstrLowerDate2,
lInternalRepresentationFor2012_01_02, CRange::EriIncluded,
&pstrUpperDate1, lInternalRepresentationFor2012_01_21,
CRange::EriExcluded);
GPOS_ASSERT(pciIntersectExpected->Equals(pciIntersect));
// union
CConstraintInterval *pciUnion = pciFirst->PciUnion(mp, pciSecond);
PrintConstraint(mp, pciUnion);
CConstraintInterval *pciUnionExpected = CTestUtils::PciGenericInterval(
mp, &mda, CMDIdGPDB::m_mdid_date, colref.Value(), &pstrLowerDate1,
lInternalRepresentationFor2012_01_01, CRange::EriIncluded,
&pstrUpperDate2, lInternalRepresentationFor2012_01_22,
CRange::EriExcluded);
GPOS_ASSERT(pciUnionExpected->Equals(pciUnion));
// difference between pciFirst and pciSecond
CConstraintInterval *pciDiff1 = pciFirst->PciDifference(mp, pciSecond);
PrintConstraint(mp, pciDiff1);
CConstraintInterval *pciDiff1Expected = CTestUtils::PciGenericInterval(
mp, &mda, CMDIdGPDB::m_mdid_date, colref.Value(), &pstrLowerDate1,
lInternalRepresentationFor2012_01_01, CRange::EriIncluded,
&pstrLowerDate2, lInternalRepresentationFor2012_01_02,
CRange::EriExcluded);
GPOS_ASSERT(pciDiff1Expected->Equals(pciDiff1));
// difference between pciSecond and pciFirst
CConstraintInterval *pciDiff2 = pciSecond->PciDifference(mp, pciFirst);
PrintConstraint(mp, pciDiff2);
CConstraintInterval *pciDiff2Expected = CTestUtils::PciGenericInterval(
mp, &mda, CMDIdGPDB::m_mdid_date, colref.Value(), &pstrUpperDate1,
lInternalRepresentationFor2012_01_21, CRange::EriIncluded,
&pstrUpperDate2, lInternalRepresentationFor2012_01_22,
CRange::EriExcluded);
GPOS_ASSERT(pciDiff2Expected->Equals(pciDiff2));
// containment
GPOS_ASSERT(!pciFirst->Contains(pciSecond));
GPOS_ASSERT(pciFirst->Contains(pciDiff1));
GPOS_ASSERT(!pciSecond->Contains(pciFirst));
GPOS_ASSERT(pciSecond->Contains(pciDiff2));
GPOS_ASSERT(pciFirst->Contains(pciFirst));
GPOS_ASSERT(pciSecond->Contains(pciSecond));
// equality
// create a third interval identical to the first
CConstraintInterval *pciThird = CTestUtils::PciGenericInterval(
mp, &mda, CMDIdGPDB::m_mdid_date, colref.Value(), &pstrLowerDate1,
lInternalRepresentationFor2012_01_01, CRange::EriIncluded,
&pstrUpperDate1, lInternalRepresentationFor2012_01_21,
CRange::EriExcluded);
GPOS_ASSERT(!pciFirst->Equals(pciSecond));
GPOS_ASSERT(!pciFirst->Equals(pciDiff1));
GPOS_ASSERT(!pciSecond->Equals(pciDiff2));
GPOS_ASSERT(pciFirst->Equals(pciThird));
pciThird->Release();
pciDiff2Expected->Release();
pciDiff1Expected->Release();
pciUnionExpected->Release();
pciIntersectExpected->Release();
pciDiff2->Release();
pciDiff1->Release();
pciUnion->Release();
pciIntersect->Release();
pciSecond->Release();
pciFirst->Release();
return GPOS_OK;
}
// EOF
相关信息
相关文章
greenplumn CColRefSetIterTest 源码
greenplumn CColumnFactoryTest 源码
greenplumn CDistributionSpecTest 源码
greenplumn CEquivalenceClassesTest 源码
greenplumn CFunctionalDependencyTest 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦