提交 10e91f99 编写于 作者: E Ekta Khanna 提交者: Bhuvnesh

Refactoring cast functions into `CUtilsCasts`

This commit creates a new file `CCastUtils.cpp` which maintains all the
cast functions.

The following functions are moved from `CUtils.cpp` to `CCastUtils.cpp`:
```
* BOOL FBinaryCoercibleCastedScId(CExpression *pexpr, CColRef *pcr)
* BOOL FBinaryCoercibleCastedScId(CExpression *pexpr)
* const CColRef *PcrExtractFromScIdOrCastScId(CExpression *pexpr)
* CExpression *PexprCast( IMemoryPool *pmp, CMDAccessor *pmda, const
CColRef *pcr, IMDId *pmdidDest)
* BOOL FBinaryCoercibleCast(CExpression *pexpr)
* CExpression *PexprWithoutBinaryCoercibleCasts(CExpression *pexpr)
```

The following functions are moved from `CPredicateUtils.cpp` to
`CCastUtils.cpp`:

```
* DrgPexpr *PdrgpexprCastEquality(IMemoryPool *pmp, CExpression *pexpr)
* CExpression *PexprAddCast(IMemoryPool *pmp, CExpression *pexprPred)
* CExpression *PexprCast(IMemoryPool *pmp, CMDAccessor *pmda,
CExpression *pexpr, IMDId *pmdidDest)
```
Signed-off-by: NDhanashree Kashid <dkashid@pivotal.io>
Signed-off-by: NBhuvnesh Chaudhary <bchaudhary@pivotal.io>
上级 5bcd44f6
......@@ -205,6 +205,8 @@ add_library(gpopt
src/base/CRewindabilitySpec.cpp
include/gpopt/base/CUtils.h
src/base/CUtils.cpp
include/gpopt/base/CCastUtils.h
src/base/CCastUtils.cpp
include/gpopt/base/CWindowFrame.h
src/base/CWindowFrame.cpp
include/gpopt/base/IColConstraintsMapper.h
......
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2017 Pivotal Software, Inc.
//
// @filename:
// CCastUtils.h
//
// @doc:
// Optimizer cast utility functions
//---------------------------------------------------------------------------
#ifndef GPOPT_CCastUtils_H
#define GPOPT_CCastUtils_H
#include "gpopt/base/CColRef.h"
namespace gpmd
{
class IMDId;
}
namespace gpopt
{
using namespace gpos;
// general cast utility functions
class CCastUtils
{
public:
// is the given expression a binary coercible cast of a scalar identifier for the given column
static
BOOL FBinaryCoercibleCastedScId(CExpression *pexpr, CColRef *pcr);
// is the given expression a binary coercible cast of a scalar identifier
static
BOOL FBinaryCoercibleCastedScId(CExpression *pexpr);
// extract the column reference if the given expression a scalar identifier
// or a cast of a scalar identifier or a function that casts a scalar identifier.
// Else return NULL.
static
const CColRef *PcrExtractFromScIdOrCastScId(CExpression *pexpr);
// cast the input column reference to the destination mdid
static
CExpression *PexprCast( IMemoryPool *pmp, CMDAccessor *pmda, const CColRef *pcr, IMDId *pmdidDest);
// check whether the given expression is a binary coercible cast of something
static
BOOL FBinaryCoercibleCast(CExpression *pexpr);
// return the given expression without any binary coercible casts
// that exist on the top
static
CExpression *PexprWithoutBinaryCoercibleCasts(CExpression *pexpr);
// add explicit casting to equality operations between compatible types
static
DrgPexpr *PdrgpexprCastEquality(IMemoryPool *pmp, CExpression *pexpr);
// helper to add explicit casting to left child of given equality predicate
static
CExpression *PexprAddCast(IMemoryPool *pmp, CExpression *pexprPred);
// add explicit casting on the input expression to the destination type
static
CExpression *PexprCast(IMemoryPool *pmp, CMDAccessor *pmda, CExpression *pexpr, IMDId *pmdidDest);
}; // class CCastUtils
} // namespace gpopt
#endif // !GPOPT_CCastUtils_H
// EOF
......@@ -113,7 +113,7 @@ namespace gpopt
static
void ValidateCTEProducerConsumerLocality(IMemoryPool *pmp, CExpression *pexpr, EExecLocalityType edt, HMUlUl *phmulul);
// Check is a comparison between given types or a comparison after casting
// check is a comparison between given types or a comparison after casting
// one side to an another exists
static
BOOL FCmpOrCastedCmpExists(IMDId *pmdidLeft, IMDId *pmdidRight, IMDType::ECmpType ecmpt);
......@@ -920,20 +920,6 @@ namespace gpopt
static
ULONG UlHashColArray(const DrgPcr *pdrgpcr, const ULONG ulMaxCols = 5);
// is the given expression a binary coercible cast of a scalar identifier for the given column
static
BOOL FBinaryCoercibleCastedScId(CExpression *pexpr, CColRef *pcr);
// is the given expression a binary coercible cast of a scalar identifier
static
BOOL FBinaryCoercibleCastedScId(CExpression *pexpr);
// extract the column reference if the given expression a scalar identifier
// or a cast of a scalar identifier or a function that casts a scalar identifier.
// Else return NULL.
static
const CColRef *PcrExtractFromScIdOrCastScId(CExpression *pexpr);
// return the set of column reference from the CTE Producer corresponding to the
// subset of input columns from the CTE Consumer
static
......@@ -948,23 +934,10 @@ namespace gpopt
static
BOOL FHasDuplicates(const DrgPcr *pdrgpcr);
// cast the input column reference to the destination mdid
static
CExpression *PexprCast( IMemoryPool *pmp, CMDAccessor *pmda, const CColRef *pcr, IMDId *pmdidDest);
// cast the input expression to the destination mdid
static
CExpression *PexprCast(IMemoryPool *pmp, CMDAccessor *pmda, CExpression *pexpr, IMDId *pmdidDest);
// check whether the given expression is a binary coercible cast of something
static
BOOL FBinaryCoercibleCast(CExpression *pexpr);
// return the given expression without any binary coercible casts
// that exist on the top
static
CExpression *PexprWithoutBinaryCoercibleCasts(CExpression *pexpr);
// construct a logical join expression of the given type, with the given children
static
CExpression *PexprLogicalJoin(IMemoryPool *pmp, EdxlJoinType edxljointype, DrgPexpr *pdrgpexpr);
......
......@@ -63,10 +63,6 @@ namespace gpopt
// no column references and no volatile functions
static
BOOL FValidRefsOnly(CExpression *pexprScalar, CColRefSet *pcrsAllowedRefs);
// helper to add explicit casting to left child of given equality predicate
static
CExpression *PexprAddCast(IMemoryPool *pmp, CExpression *pexprPred);
// determine which predicates we should test implication for
static
......@@ -461,10 +457,6 @@ namespace gpopt
static
CExpression *PexprInverseComparison(IMemoryPool *pmp, CExpression *pexprCmp);
// add explicit casting to equality operations between compatible types
static
DrgPexpr *PdrgpexprCastEquality(IMemoryPool *pmp, CExpression *pexpr);
// prune unnecessary equality operations
static
CExpression *PexprPruneSuperfluosEquality(IMemoryPool *pmp, CExpression *pexpr);
......@@ -509,10 +501,6 @@ namespace gpopt
static
void SeparateOuterRefs(IMemoryPool *pmp, CExpression *pexprScalar, CColRefSet *pcrsOuter, CExpression **ppexprLocal, CExpression **ppexprOuterRef);
// add explicit casting on the input expression to the destination type
static
CExpression *PexprCast(IMemoryPool *pmp, CMDAccessor *pmda, CExpression *pexpr, IMDId *pmdidDest);
// is the condition a LIKE predicate
static
BOOL FLikePredicate(IMDId *pmdid);
......
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2017 Pivotal Software, Inc.
//
// @filename:
// CCastUtils.cpp
//
// @doc:
// Implementation of cast utility functions
//---------------------------------------------------------------------------
#include "gpos/memory/CAutoMemoryPool.h"
#include "gpopt/base/CUtils.h"
#include "gpopt/base/CCastUtils.h"
#include "gpopt/mdcache/CMDAccessorUtils.h"
#include "gpopt/operators/CScalarIdent.h"
#include "gpopt/operators/CScalarArrayCoerceExpr.h"
#include "gpopt/operators/CScalarCast.h"
#include "naucrates/md/IMDCast.h"
#include "naucrates/md/CMDArrayCoerceCastGPDB.h"
#include "gpopt/operators/CPredicateUtils.h"
using namespace gpopt;
using namespace gpmd;
// is the given expression a binary coercible cast of a scalar identifier
BOOL
CCastUtils::FBinaryCoercibleCastedScId
(
CExpression *pexpr,
CColRef *pcr
)
{
GPOS_ASSERT(NULL != pexpr);
if (!FBinaryCoercibleCast(pexpr))
{
return false;
}
CExpression *pexprChild = (*pexpr)[0];
// cast(col1)
return COperator::EopScalarIdent == pexprChild->Pop()->Eopid() &&
pcr == CScalarIdent::PopConvert(pexprChild->Pop())->Pcr();
}
// is the given expression a binary coercible cast of a scalar identifier
BOOL
CCastUtils::FBinaryCoercibleCastedScId
(
CExpression *pexpr
)
{
GPOS_ASSERT(NULL != pexpr);
if (!FBinaryCoercibleCast(pexpr))
{
return false;
}
CExpression *pexprChild = (*pexpr)[0];
// cast(col1)
return COperator::EopScalarIdent == pexprChild->Pop()->Eopid();
}
// extract the column reference if the given expression a scalar identifier
// or a cast of a scalar identifier or a function that casts a scalar identifier.
// Else return NULL.
const CColRef *
CCastUtils::PcrExtractFromScIdOrCastScId
(
CExpression *pexpr
)
{
GPOS_ASSERT(NULL != pexpr);
BOOL fScIdent = COperator::EopScalarIdent == pexpr->Pop()->Eopid();
BOOL fCastedScIdent = CScalarIdent::FCastedScId(pexpr);
// col or cast(col)
if (!fScIdent && !fCastedScIdent)
{
return NULL;
}
CScalarIdent *popScIdent = NULL;
if (fScIdent)
{
popScIdent = CScalarIdent::PopConvert(pexpr->Pop());
}
else
{
GPOS_ASSERT(fCastedScIdent);
popScIdent = CScalarIdent::PopConvert((*pexpr)[0]->Pop());
}
return popScIdent->Pcr();
}
// cast the input column reference to the destination mdid
CExpression *
CCastUtils::PexprCast
(
IMemoryPool *pmp,
CMDAccessor *pmda,
const CColRef *pcr,
IMDId *pmdidDest
)
{
GPOS_ASSERT(NULL != pmdidDest);
IMDId *pmdidSrc = pcr->Pmdtype()->Pmdid();
GPOS_ASSERT(CMDAccessorUtils::FCastExists(pmda, pmdidSrc, pmdidDest));
const IMDCast *pmdcast = pmda->Pmdcast(pmdidSrc, pmdidDest);
pmdidDest->AddRef();
pmdcast->PmdidCastFunc()->AddRef();
CExpression *pexpr;
if(pmdcast->EmdPathType() == IMDCast::EmdtArrayCoerce)
{
CMDArrayCoerceCastGPDB *parrayCoerceCast = (CMDArrayCoerceCastGPDB *) pmdcast;
pexpr = GPOS_NEW(pmp) CExpression
(
pmp,
GPOS_NEW(pmp) CScalarArrayCoerceExpr
(
pmp,
parrayCoerceCast->PmdidCastFunc(),
pmdidDest,
parrayCoerceCast->IMod(),
parrayCoerceCast->FIsExplicit(),
(COperator::ECoercionForm) parrayCoerceCast->Ecf(),
parrayCoerceCast->ILoc()
),
CUtils::PexprScalarIdent(pmp, pcr)
);
}
else
{
CScalarCast *popCast = GPOS_NEW(pmp) CScalarCast(pmp, pmdidDest, pmdcast->PmdidCastFunc(), pmdcast->FBinaryCoercible());
pexpr = GPOS_NEW(pmp) CExpression(pmp, popCast, CUtils::PexprScalarIdent(pmp, pcr));
}
return pexpr;
}
// check whether the given expression is a binary coercible cast of something
BOOL
CCastUtils::FBinaryCoercibleCast
(
CExpression *pexpr
)
{
GPOS_ASSERT(NULL != pexpr);
COperator *pop = pexpr->Pop();
return COperator::EopScalarCast == pop->Eopid() &&
CScalarCast::PopConvert(pop)->FBinaryCoercible();
}
// return the given expression without any binary coercible casts
// that exist on the top
CExpression *
CCastUtils::PexprWithoutBinaryCoercibleCasts
(
CExpression *pexpr
)
{
GPOS_ASSERT(NULL != pexpr);
GPOS_ASSERT(pexpr->Pop()->FScalar());
CExpression *pexprOutput = pexpr;
while (FBinaryCoercibleCast(pexprOutput))
{
GPOS_ASSERT(1 == pexprOutput->UlArity());
pexprOutput = (*pexprOutput)[0];
}
return pexprOutput;
}
// add explicit casting to equality operations between compatible types
DrgPexpr *
CCastUtils::PdrgpexprCastEquality
(
IMemoryPool *pmp,
CExpression *pexpr
)
{
GPOS_ASSERT(pexpr->Pop()->FScalar());
DrgPexpr *pdrgpexpr = CPredicateUtils::PdrgpexprConjuncts(pmp, pexpr);
DrgPexpr *pdrgpexprNew = GPOS_NEW(pmp) DrgPexpr(pmp);
const ULONG ulPreds = pdrgpexpr->UlLength();
for (ULONG ul = 0; ul < ulPreds; ul++)
{
CExpression *pexprPred = (*pdrgpexpr)[ul];
pexprPred->AddRef();
CExpression *pexprNewPred = pexprPred;
if (CPredicateUtils::FEquality(pexprPred) || CPredicateUtils::FINDF(pexprPred))
{
CExpression *pexprCasted = PexprAddCast(pmp, pexprPred);
if (NULL != pexprCasted)
{
// release predicate since we will construct a new one
pexprNewPred->Release();
pexprNewPred = pexprCasted;
}
}
pdrgpexprNew->Append(pexprNewPred);
}
pdrgpexpr->Release();
return pdrgpexprNew;
}
// add explicit casting to left child of given equality or INDF predicate
// and return resulting casted expression;
// the function returns NULL if operation failed
CExpression *
CCastUtils::PexprAddCast
(
IMemoryPool *pmp,
CExpression *pexprPred
)
{
GPOS_ASSERT(NULL != pexprPred);
GPOS_ASSERT(CUtils::FScalarCmp(pexprPred) || CPredicateUtils::FINDF(pexprPred));
CExpression *pexprChild = pexprPred;
if (!CUtils::FScalarCmp(pexprPred))
{
pexprChild = (*pexprPred)[0];
}
CExpression *pexprLeft = (*pexprChild)[0];
CExpression *pexprRight = (*pexprChild)[1];
IMDId *pmdidTypeLeft = CScalar::PopConvert(pexprLeft->Pop())->PmdidType();
IMDId *pmdidTypeRight = CScalar::PopConvert(pexprRight->Pop())->PmdidType();
CMDAccessor *pmda = COptCtxt::PoctxtFromTLS()->Pmda();
CExpression *pexprNewPred = NULL;
BOOL fTypesEqual = pmdidTypeLeft->FEquals(pmdidTypeRight);
BOOL fCastLtoR = CMDAccessorUtils::FCastExists(pmda, pmdidTypeLeft, pmdidTypeRight);
BOOL fCastRtoL = CMDAccessorUtils::FCastExists(pmda, pmdidTypeRight, pmdidTypeLeft);
if (fTypesEqual || !(fCastLtoR || fCastRtoL))
{
return pexprNewPred;
}
pexprLeft->AddRef();
pexprRight->AddRef();
CExpression *pexprNewLeft = pexprLeft;
CExpression *pexprNewRight = pexprRight;
if (fCastLtoR)
{
pexprNewLeft = PexprCast(pmp, pmda, pexprLeft, pmdidTypeRight);
}
else
{
GPOS_ASSERT(fCastRtoL);
pexprNewRight = PexprCast(pmp, pmda, pexprRight, pmdidTypeLeft);;
}
GPOS_ASSERT(NULL != pexprNewLeft && NULL != pexprNewRight);
if (CUtils::FScalarCmp(pexprPred))
{
pexprNewPred = CUtils::PexprScalarCmp(pmp, pexprNewLeft, pexprNewRight, IMDType::EcmptEq);
}
else
{
pexprNewPred = CUtils::PexprINDF(pmp, pexprNewLeft, pexprNewRight);
}
return pexprNewPred;
}
// add explicit casting on the input expression to the destination type
CExpression *
CCastUtils::PexprCast
(
IMemoryPool *pmp,
CMDAccessor *pmda,
CExpression *pexpr,
IMDId *pmdidDest
)
{
IMDId *pmdidSrc = CScalar::PopConvert(pexpr->Pop())->PmdidType();
const IMDCast *pmdcast = pmda->Pmdcast(pmdidSrc, pmdidDest);
pmdidDest->AddRef();
pmdcast->PmdidCastFunc()->AddRef();
CExpression *pexprCast;
if (pmdcast->EmdPathType() == IMDCast::EmdtArrayCoerce)
{
CMDArrayCoerceCastGPDB *parrayCoerceCast = (CMDArrayCoerceCastGPDB *) pmdcast;
pexprCast = GPOS_NEW(pmp) CExpression
(
pmp,
GPOS_NEW(pmp) CScalarArrayCoerceExpr(pmp, parrayCoerceCast->PmdidCastFunc(), pmdidDest, parrayCoerceCast->IMod(), parrayCoerceCast->FIsExplicit(), (COperator::ECoercionForm) parrayCoerceCast->Ecf(), parrayCoerceCast->ILoc()),
pexpr
);
}
else
{
CScalarCast *popCast = GPOS_NEW(pmp) CScalarCast(pmp, pmdidDest, pmdcast->PmdidCastFunc(), pmdcast->FBinaryCoercible());
pexprCast = GPOS_NEW(pmp) CExpression(pmp, popCast, pexpr);
}
return pexprCast;
}
// EOF
......@@ -12,6 +12,7 @@
#include "naucrates/traceflags/traceflags.h"
#include "gpopt/base/COptCtxt.h"
#include "gpopt/base/CUtils.h"
#include "gpopt/base/CCastUtils.h"
#include "gpopt/base/CColRefSet.h"
#include "gpopt/base/CColRefSetIter.h"
#include "gpopt/base/CDistributionSpecHashed.h"
......@@ -192,12 +193,12 @@ CDistributionSpecHashed::FMatchSubset
for (ULONG ulOuter = 0; ulOuter < ulOwnExprs; ulOuter++)
{
CExpression *pexprOwn = CUtils::PexprWithoutBinaryCoercibleCasts((*m_pdrgpexpr)[ulOuter]);
CExpression *pexprOwn = CCastUtils::PexprWithoutBinaryCoercibleCasts((*m_pdrgpexpr)[ulOuter]);
BOOL fFound = false;
for (ULONG ulInner = 0; ulInner < ulOtherExprs; ulInner++)
{
CExpression *pexprOther = CUtils::PexprWithoutBinaryCoercibleCasts((*(pdsHashed->m_pdrgpexpr))[ulInner]);
CExpression *pexprOther = CCastUtils::PexprWithoutBinaryCoercibleCasts((*(pdsHashed->m_pdrgpexpr))[ulInner]);
if (CUtils::FEqual(pexprOwn, pexprOther))
{
fFound = true;
......@@ -406,8 +407,8 @@ CDistributionSpecHashed::FMatchHashedDistribution
const ULONG ulLen = m_pdrgpexpr->UlLength();
for (ULONG ul = 0; ul < ulLen; ul++)
{
if (!CUtils::FEqual(CUtils::PexprWithoutBinaryCoercibleCasts((*(pdshashed->m_pdrgpexpr))[ul]),
CUtils::PexprWithoutBinaryCoercibleCasts((*m_pdrgpexpr)[ul])))
if (!CUtils::FEqual(CCastUtils::PexprWithoutBinaryCoercibleCasts((*(pdshashed->m_pdrgpexpr))[ul]),
CCastUtils::PexprWithoutBinaryCoercibleCasts((*m_pdrgpexpr)[ul])))
{
return false;
}
......
......@@ -264,29 +264,29 @@ CUtils::PexprScalarCmp
// one side to an another exists
BOOL
CUtils::FCmpOrCastedCmpExists
(
(
IMDId *pmdidLeft,
IMDId *pmdidRight,
IMDType::ECmpType ecmpt
)
{
CMDAccessor *pmda = COptCtxt::PoctxtFromTLS()->Pmda();
if (CMDAccessorUtils::FCmpExists(pmda, pmdidLeft, pmdidRight, ecmpt))
{
return true;
}
if (CMDAccessorUtils::FCmpExists(pmda, pmdidRight, pmdidRight, ecmpt) && CMDAccessorUtils::FCastExists(pmda, pmdidLeft, pmdidRight))
{
return true;
}
if (CMDAccessorUtils::FCmpExists(pmda, pmdidLeft, pmdidLeft, ecmpt) && CMDAccessorUtils::FCastExists(pmda, pmdidRight, pmdidLeft))
{
return true;
}
return false;
}
......@@ -4107,48 +4107,6 @@ CUtils::PexprConjINDFCond
return pexprScCond;
}
// is the given expression a binary coercible cast of a scalar identifier
BOOL
CUtils::FBinaryCoercibleCastedScId
(
CExpression *pexpr,
CColRef *pcr
)
{
GPOS_ASSERT(NULL != pexpr);
if (!FBinaryCoercibleCast(pexpr))
{
return false;
}
CExpression *pexprChild = (*pexpr)[0];
// cast(col1)
return COperator::EopScalarIdent == pexprChild->Pop()->Eopid() &&
pcr == CScalarIdent::PopConvert(pexprChild->Pop())->Pcr();
}
// is the given expression a binary coercible cast of a scalar identifier
BOOL
CUtils::FBinaryCoercibleCastedScId
(
CExpression *pexpr
)
{
GPOS_ASSERT(NULL != pexpr);
if (!FBinaryCoercibleCast(pexpr))
{
return false;
}
CExpression *pexprChild = (*pexpr)[0];
// cast(col1)
return COperator::EopScalarIdent == pexprChild->Pop()->Eopid();
}
// return index of the set containing given column; if column is not found, return ULONG_MAX
ULONG
CUtils::UlPcrIndexContainingSet
......@@ -4172,93 +4130,10 @@ CUtils::UlPcrIndexContainingSet
return ULONG_MAX;
}
// extract the column reference if the given expression a scalar identifier
// or a cast of a scalar identifier or a function that casts a scalar identifier.
// Else return NULL.
const CColRef *
CUtils::PcrExtractFromScIdOrCastScId
(
CExpression *pexpr
)
{
GPOS_ASSERT(NULL != pexpr);
BOOL fScIdent = COperator::EopScalarIdent == pexpr->Pop()->Eopid();
BOOL fCastedScIdent = CScalarIdent::FCastedScId(pexpr);
// col or cast(col)
if (!fScIdent && !fCastedScIdent)
{
return NULL;
}
CScalarIdent *popScIdent = NULL;
if (fScIdent)
{
popScIdent = CScalarIdent::PopConvert(pexpr->Pop());
}
else
{
GPOS_ASSERT(fCastedScIdent);
popScIdent = CScalarIdent::PopConvert((*pexpr)[0]->Pop());
}
return popScIdent->Pcr();
}
// cast the input column reference to the destination mdid
CExpression *
CUtils::PexprCast
(
IMemoryPool *pmp,
CMDAccessor *pmda,
const CColRef *pcr,
IMDId *pmdidDest
)
{
GPOS_ASSERT(NULL != pmdidDest);
IMDId *pmdidSrc = pcr->Pmdtype()->Pmdid();
GPOS_ASSERT(CMDAccessorUtils::FCastExists(pmda, pmdidSrc, pmdidDest));
const IMDCast *pmdcast = pmda->Pmdcast(pmdidSrc, pmdidDest);
pmdidDest->AddRef();
pmdcast->PmdidCastFunc()->AddRef();
CExpression *pexpr;
if(pmdcast->EmdPathType() == IMDCast::EmdtArrayCoerce)
{
CMDArrayCoerceCastGPDB *parrayCoerceCast = (CMDArrayCoerceCastGPDB *) pmdcast;
pexpr = GPOS_NEW(pmp) CExpression
(
pmp,
GPOS_NEW(pmp) CScalarArrayCoerceExpr
(
pmp,
parrayCoerceCast->PmdidCastFunc(),
pmdidDest,
parrayCoerceCast->IMod(),
parrayCoerceCast->FIsExplicit(),
(COperator::ECoercionForm) parrayCoerceCast->Ecf(),
parrayCoerceCast->ILoc()
),
PexprScalarIdent(pmp, pcr)
);
}
else
{
CScalarCast *popCast = GPOS_NEW(pmp) CScalarCast(pmp, pmdidDest, pmdcast->PmdidCastFunc(), pmdcast->FBinaryCoercible());
pexpr = GPOS_NEW(pmp) CExpression(pmp, popCast, PexprScalarIdent(pmp, pcr));
}
return pexpr;
}
// cast the input expression to the destination mdid
CExpression *
CUtils::PexprCast
(
(
IMemoryPool *pmp,
CMDAccessor *pmda,
CExpression *pexpr,
......@@ -4268,9 +4143,9 @@ CUtils::PexprCast
GPOS_ASSERT(NULL != pmdidDest);
IMDId *pmdidSrc = CScalar::PopConvert(pexpr->Pop())->PmdidType();
GPOS_ASSERT(CMDAccessorUtils::FCastExists(pmda, pmdidSrc, pmdidDest));
const IMDCast *pmdcast = pmda->Pmdcast(pmdidSrc, pmdidDest);
pmdidDest->AddRef();
pmdcast->PmdidCastFunc()->AddRef();
CExpression *pexprCast;
......@@ -4279,20 +4154,20 @@ CUtils::PexprCast
{
CMDArrayCoerceCastGPDB *parrayCoerceCast = (CMDArrayCoerceCastGPDB *) pmdcast;
pexprCast = GPOS_NEW(pmp) CExpression
(
pmp,
GPOS_NEW(pmp) CScalarArrayCoerceExpr
(
pmp,
parrayCoerceCast->PmdidCastFunc(),
pmdidDest,
parrayCoerceCast->IMod(),
parrayCoerceCast->FIsExplicit(),
(COperator::ECoercionForm) parrayCoerceCast->Ecf(),
parrayCoerceCast->ILoc()
),
pexpr
);
(
pmp,
GPOS_NEW(pmp) CScalarArrayCoerceExpr
(
pmp,
parrayCoerceCast->PmdidCastFunc(),
pmdidDest,
parrayCoerceCast->IMod(),
parrayCoerceCast->FIsExplicit(),
(COperator::ECoercionForm) parrayCoerceCast->Ecf(),
parrayCoerceCast->ILoc()
),
pexpr
);
}
else
{
......@@ -4300,46 +4175,10 @@ CUtils::PexprCast
CScalarCast *popCast = GPOS_NEW(pmp) CScalarCast(pmp, pmdidDest, pmdcast->PmdidCastFunc(), pmdcast->FBinaryCoercible());
pexprCast = GPOS_NEW(pmp) CExpression(pmp, popCast, pexpr);
}
return pexprCast;
}
// check whether the given expression is a binary coercible cast of something
BOOL
CUtils::FBinaryCoercibleCast
(
CExpression *pexpr
)
{
GPOS_ASSERT(NULL != pexpr);
COperator *pop = pexpr->Pop();
return COperator::EopScalarCast == pop->Eopid() &&
CScalarCast::PopConvert(pop)->FBinaryCoercible();
}
// return the given expression without any binary coercible casts
// that exist on the top
CExpression *
CUtils::PexprWithoutBinaryCoercibleCasts
(
CExpression *pexpr
)
{
GPOS_ASSERT(NULL != pexpr);
GPOS_ASSERT(pexpr->Pop()->FScalar());
CExpression *pexprOutput = pexpr;
while (FBinaryCoercibleCast(pexprOutput))
{
GPOS_ASSERT(1 == pexprOutput->UlArity());
pexprOutput = (*pexprOutput)[0];
}
return pexprOutput;
}
// check whether a colref array contains repeated items
BOOL
CUtils::FHasDuplicates
......
......@@ -13,6 +13,7 @@
#include "gpos/sync/CAutoMutex.h"
#include "gpopt/base/CUtils.h"
#include "gpopt/base/CCastUtils.h"
#include "gpopt/base/COptCtxt.h"
#include "gpopt/base/CDistributionSpecReplicated.h"
#include "gpopt/base/CDistributionSpecNonSingleton.h"
......@@ -309,11 +310,11 @@ CPhysicalHashJoin::PdshashedMatching
DrgPexpr *pdrgpexprTargetNoCast = GPOS_NEW(pmp) DrgPexpr(pmp);
for (ULONG ul = 0; ul < ulSourceSize; ul++)
{
CExpression *pexpr = CUtils::PexprWithoutBinaryCoercibleCasts((*pdrgpexprSource)[ul]);
CExpression *pexpr = CCastUtils::PexprWithoutBinaryCoercibleCasts((*pdrgpexprSource)[ul]);
pexpr->AddRef();
pdrgpexprSourceNoCast->Append(pexpr);
pexpr = CUtils::PexprWithoutBinaryCoercibleCasts((*pdrgpexprTarget)[ul]);
pexpr = CCastUtils::PexprWithoutBinaryCoercibleCasts((*pdrgpexprTarget)[ul]);
pexpr->AddRef();
pdrgpexprTargetNoCast->Append(pexpr);
}
......@@ -322,7 +323,7 @@ CPhysicalHashJoin::PdshashedMatching
DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
for (ULONG ulDlvrdIdx = 0; ulDlvrdIdx < ulDlvrdSize; ulDlvrdIdx++)
{
CExpression *pexprDlvrd = CUtils::PexprWithoutBinaryCoercibleCasts((*pdrgpexprDist)[ulDlvrdIdx]);
CExpression *pexprDlvrd = CCastUtils::PexprWithoutBinaryCoercibleCasts((*pdrgpexprDist)[ulDlvrdIdx]);
for (ULONG ulIdx = 0; ulIdx < ulSourceSize; ulIdx++)
{
if (CUtils::FEqual(pexprDlvrd, (*pdrgpexprSourceNoCast)[ulIdx]))
......
......@@ -12,6 +12,7 @@
#include "gpos/base.h"
#include "gpopt/base/CUtils.h"
#include "gpopt/base/CCastUtils.h"
#include "gpopt/base/CDistributionSpecAny.h"
#include "gpopt/base/CDistributionSpecReplicated.h"
......@@ -699,7 +700,7 @@ CPhysicalJoin::FHashJoinPossible
GPOS_ASSERT(NULL != ppexprResult);
// introduce explicit casting, if needed
DrgPexpr *pdrgpexpr = CPredicateUtils::PdrgpexprCastEquality(pmp, (*pexpr)[2]);
DrgPexpr *pdrgpexpr = CCastUtils::PdrgpexprCastEquality(pmp, (*pexpr)[2]);
// identify hashkeys
ULONG ulPreds = pdrgpexpr->UlLength();
......
......@@ -12,6 +12,7 @@
#include "gpos/base.h"
#include "gpopt/base/CUtils.h"
#include "gpopt/base/CCastUtils.h"
#include "gpopt/base/CColRefTable.h"
#include "gpopt/base/CColRefSetIter.h"
#include "gpopt/base/CConstraintInterval.h"
......@@ -143,12 +144,12 @@ CPredicateUtils::FComparison
CExpression *pexprLeft = (*pexpr)[0];
CExpression *pexprRight = (*pexpr)[1];
if (CUtils::FScalarIdent(pexprLeft, pcr) || CUtils::FBinaryCoercibleCastedScId(pexprLeft, pcr))
if (CUtils::FScalarIdent(pexprLeft, pcr) || CCastUtils::FBinaryCoercibleCastedScId(pexprLeft, pcr))
{
return FValidRefsOnly(pexprRight, pcrsAllowedRefs);
}
if (CUtils::FScalarIdent(pexprRight, pcr) || CUtils::FBinaryCoercibleCastedScId(pexprRight, pcr))
if (CUtils::FScalarIdent(pexprRight, pcr) || CCastUtils::FBinaryCoercibleCastedScId(pexprRight, pcr))
{
return FValidRefsOnly(pexprLeft, pcrsAllowedRefs);
}
......@@ -626,13 +627,13 @@ CPredicateUtils::ExtractComponents
IMDType::ECmpType ecmpt =
CScalarCmp::PopConvert(pexprScCmp->Pop())->Ecmpt();
if (CUtils::FScalarIdent(pexprLeft, pcrKey) || CUtils::FBinaryCoercibleCastedScId(pexprLeft, pcrKey))
if (CUtils::FScalarIdent(pexprLeft, pcrKey) || CCastUtils::FBinaryCoercibleCastedScId(pexprLeft, pcrKey))
{
*ppexprKey = pexprLeft;
*ppexprOther = pexprRight;
*pecmpt = ecmpt;
}
else if (CUtils::FScalarIdent(pexprRight, pcrKey) || CUtils::FBinaryCoercibleCastedScId(pexprRight, pcrKey))
else if (CUtils::FScalarIdent(pexprRight, pcrKey) || CCastUtils::FBinaryCoercibleCastedScId(pexprRight, pcrKey))
{
*ppexprKey = pexprRight;
*ppexprOther = pexprLeft;
......@@ -1305,7 +1306,7 @@ CPredicateUtils::FNullCheckOnColumn
if (CUtils::FScalarNullTest(pexprIsNull))
{
CExpression *pexprChild = (*pexprIsNull)[0];
return (CUtils::FScalarIdent(pexprChild, pcr) || CUtils::FBinaryCoercibleCastedScId(pexprChild, pcr));
return (CUtils::FScalarIdent(pexprChild, pcr) || CCastUtils::FBinaryCoercibleCastedScId(pexprChild, pcr));
}
return false;
......@@ -1671,7 +1672,7 @@ CPredicateUtils::PexprIndexLookupKeyOnLeft
CColRefSet *pcrsIndex = GPOS_NEW(pmp) CColRefSet(pmp, pdrgpcrIndex);
if ((CUtils::FScalarIdent(pexprLeft) && pcrsIndex->FMember(CScalarIdent::PopConvert(pexprLeft->Pop())->Pcr())) ||
(CUtils::FBinaryCoercibleCast(pexprLeft) && pcrsIndex->FMember(CScalarIdent::PopConvert((*pexprLeft)[0]->Pop())->Pcr())))
(CCastUtils::FBinaryCoercibleCast(pexprLeft) && pcrsIndex->FMember(CScalarIdent::PopConvert((*pexprLeft)[0]->Pop())->Pcr())))
{
// left expression is a scalar identifier or casted scalar identifier on an index key
CColRefSet *pcrsUsedRight = CDrvdPropScalar::Pdpscalar(pexprRight->PdpDerive())->PcrsUsed();
......@@ -1929,148 +1930,6 @@ CPredicateUtils::SeparateOuterRefs
*ppexprOuterRef = PexprConjunction(pmp, pdrgpexprOuterRefs);
}
// add explicit casting to left child of given equality or INDF predicate
// and return resulting casted expression;
// the function returns NULL if operation failed
CExpression *
CPredicateUtils::PexprAddCast
(
IMemoryPool *pmp,
CExpression *pexprPred
)
{
GPOS_ASSERT(NULL != pexprPred);
GPOS_ASSERT(CUtils::FScalarCmp(pexprPred) || FINDF(pexprPred));
CExpression *pexprChild = pexprPred;
if (!CUtils::FScalarCmp(pexprPred))
{
pexprChild = (*pexprPred)[0];
}
CExpression *pexprLeft = (*pexprChild)[0];
CExpression *pexprRight = (*pexprChild)[1];
IMDId *pmdidTypeLeft = CScalar::PopConvert(pexprLeft->Pop())->PmdidType();
IMDId *pmdidTypeRight = CScalar::PopConvert(pexprRight->Pop())->PmdidType();
CMDAccessor *pmda = COptCtxt::PoctxtFromTLS()->Pmda();
CExpression *pexprNewPred = NULL;
BOOL fTypesEqual = pmdidTypeLeft->FEquals(pmdidTypeRight);
BOOL fCastLtoR = CMDAccessorUtils::FCastExists(pmda, pmdidTypeLeft, pmdidTypeRight);
BOOL fCastRtoL = CMDAccessorUtils::FCastExists(pmda, pmdidTypeRight, pmdidTypeLeft);
if (fTypesEqual || !(fCastLtoR || fCastRtoL))
{
return pexprNewPred;
}
pexprLeft->AddRef();
pexprRight->AddRef();
CExpression *pexprNewLeft = pexprLeft;
CExpression *pexprNewRight = pexprRight;
if (fCastLtoR)
{
pexprNewLeft = PexprCast(pmp, pmda, pexprLeft, pmdidTypeRight);
}
else
{
GPOS_ASSERT(fCastRtoL);
pexprNewRight = PexprCast(pmp, pmda, pexprRight, pmdidTypeLeft);;
}
GPOS_ASSERT(NULL != pexprNewLeft && NULL != pexprNewRight);
if (CUtils::FScalarCmp(pexprPred))
{
pexprNewPred = CUtils::PexprScalarCmp(pmp, pexprNewLeft, pexprNewRight, IMDType::EcmptEq);
}
else
{
pexprNewPred = CUtils::PexprINDF(pmp, pexprNewLeft, pexprNewRight);
}
return pexprNewPred;
}
// add explicit casting on the input expression to the destination type
CExpression *
CPredicateUtils::PexprCast
(
IMemoryPool *pmp,
CMDAccessor *pmda,
CExpression *pexpr,
IMDId *pmdidDest
)
{
IMDId *pmdidSrc = CScalar::PopConvert(pexpr->Pop())->PmdidType();
const IMDCast *pmdcast = pmda->Pmdcast(pmdidSrc, pmdidDest);
pmdidDest->AddRef();
pmdcast->PmdidCastFunc()->AddRef();
CExpression *pexprCast;
if (pmdcast->EmdPathType() == IMDCast::EmdtArrayCoerce)
{
CMDArrayCoerceCastGPDB *parrayCoerceCast = (CMDArrayCoerceCastGPDB *) pmdcast;
pexprCast = GPOS_NEW(pmp) CExpression
(
pmp,
GPOS_NEW(pmp) CScalarArrayCoerceExpr(pmp, parrayCoerceCast->PmdidCastFunc(), pmdidDest, parrayCoerceCast->IMod(), parrayCoerceCast->FIsExplicit(), (COperator::ECoercionForm) parrayCoerceCast->Ecf(), parrayCoerceCast->ILoc()),
pexpr
);
}
else
{
CScalarCast *popCast = GPOS_NEW(pmp) CScalarCast(pmp, pmdidDest, pmdcast->PmdidCastFunc(), pmdcast->FBinaryCoercible());
pexprCast = GPOS_NEW(pmp) CExpression(pmp, popCast, pexpr);
}
return pexprCast;
}
// add explicit casting to equality operations between compatible types
DrgPexpr *
CPredicateUtils::PdrgpexprCastEquality
(
IMemoryPool *pmp,
CExpression *pexpr
)
{
GPOS_ASSERT(pexpr->Pop()->FScalar());
DrgPexpr *pdrgpexpr = PdrgpexprConjuncts(pmp, pexpr);
DrgPexpr *pdrgpexprNew = GPOS_NEW(pmp) DrgPexpr(pmp);
const ULONG ulPreds = pdrgpexpr->UlLength();
for (ULONG ul = 0; ul < ulPreds; ul++)
{
CExpression *pexprPred = (*pdrgpexpr)[ul];
pexprPred->AddRef();
CExpression *pexprNewPred = pexprPred;
if (FEquality(pexprPred) || FINDF(pexprPred))
{
CExpression *pexprCasted = PexprAddCast(pmp, pexprPred);
if (NULL != pexprCasted)
{
// release predicate since we will construct a new one
pexprNewPred->Release();
pexprNewPred = pexprCasted;
}
}
pdrgpexprNew->Append(pexprNewPred);
}
pdrgpexpr->Release();
return pdrgpexprNew;
}
// convert predicates of the form (a Cmp b) into (a InvCmp b);
// where InvCmp is the inverse comparison (e.g., '=' --> '<>')
CExpression *
......
......@@ -45,6 +45,7 @@
#include "gpopt/translate/CTranslatorExprToDXLUtils.h"
#include "gpopt/base/CUtils.h"
#include "gpopt/base/CCastUtils.h"
#include "naucrates/base/IDatumInt8.h"
#include "naucrates/base/CDatumBoolGPDB.h"
......@@ -4909,7 +4910,7 @@ CTranslatorExprToDXL::PdxlnPredOnPartKey
{
#ifdef GPOS_DEBUG
CExpression *pexprChild = (*pexprPred)[0];
GPOS_ASSERT(CUtils::FScalarIdent(pexprChild, pcrPartKey) || CUtils::FBinaryCoercibleCastedScId(pexprChild, pcrPartKey));
GPOS_ASSERT(CUtils::FScalarIdent(pexprChild, pcrPartKey) || CCastUtils::FBinaryCoercibleCastedScId(pexprChild, pcrPartKey));
#endif //GPOS_DEBUG
return PdxlnScNullTestPartKey(pmdidTypePartKey, ulPartLevel, fRangePart, true /*fIsNull*/);
......@@ -4920,7 +4921,7 @@ CTranslatorExprToDXL::PdxlnPredOnPartKey
#ifdef GPOS_DEBUG
CExpression *pexprIsNull = (*pexprPred)[0];
CExpression *pexprChild = (*pexprIsNull)[0];
GPOS_ASSERT(CUtils::FScalarIdent(pexprChild, pcrPartKey) || CUtils::FBinaryCoercibleCastedScId(pexprChild, pcrPartKey));
GPOS_ASSERT(CUtils::FScalarIdent(pexprChild, pcrPartKey) || CCastUtils::FBinaryCoercibleCastedScId(pexprChild, pcrPartKey));
#endif //GPOS_DEBUG
*pfEQComparison = true;
......
......@@ -12,6 +12,7 @@
#include "gpos/base.h"
#include "gpopt/base/CUtils.h"
#include "gpopt/base/CCastUtils.h"
#include "gpopt/exception.h"
#include "gpopt/operators/ops.h"
#include "gpopt/operators/CExpressionUtils.h"
......@@ -287,7 +288,7 @@ CStatsPredUtils::Pstatspred
GPOS_ASSERT(COperator::EopScalarIdent == pexprLeft->Pop()->Eopid() || CScalarIdent::FCastedScId(pexprLeft));
GPOS_ASSERT(COperator::EopScalarConst == pexprRight->Pop()->Eopid() || CScalarConst::FCastedConst(pexprRight));
const CColRef *pcr = CUtils::PcrExtractFromScIdOrCastScId(pexprLeft);
const CColRef *pcr = CCastUtils::PcrExtractFromScIdOrCastScId(pexprLeft);
CScalarConst *popScalarConst = CScalarConst::PopExtractFromConstOrCastConst(pexprRight);
GPOS_ASSERT(NULL != popScalarConst);
......@@ -365,8 +366,8 @@ CStatsPredUtils::FCmpColsIgnoreCast
pexprRight = (*pexpr)[1];
}
(*ppcrLeft) = CUtils::PcrExtractFromScIdOrCastScId(pexprLeft);
(*ppcrRight) = CUtils::PcrExtractFromScIdOrCastScId(pexprRight);
(*ppcrLeft) = CCastUtils::PcrExtractFromScIdOrCastScId(pexprLeft);
(*ppcrRight) = CCastUtils::PcrExtractFromScIdOrCastScId(pexprRight);
if (NULL == *ppcrLeft || NULL == *ppcrRight)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册