greenplumn CXformExpandNAryJoinDPv2 源码

  • 2022-08-18
  • 浏览 (316)

greenplumn CXformExpandNAryJoinDPv2 代码

文件路径:/src/backend/gporca/libgpopt/src/xforms/CXformExpandNAryJoinDPv2.cpp

//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2019 VMware, Inc. or its affiliates.
//
//	@filename:
//		CXformExpandNAryJoinDPv2.cpp
//
//	@doc:
//		Implementation of n-ary join expansion using dynamic programming
//---------------------------------------------------------------------------

#include "gpopt/xforms/CXformExpandNAryJoinDPv2.h"

#include "gpos/base.h"

#include "gpopt/base/CUtils.h"
#include "gpopt/engine/CHint.h"
#include "gpopt/operators/CLogicalNAryJoin.h"
#include "gpopt/operators/CNormalizer.h"
#include "gpopt/operators/CPatternMultiLeaf.h"
#include "gpopt/operators/CPatternTree.h"
#include "gpopt/operators/CPredicateUtils.h"
#include "gpopt/operators/CScalarNAryJoinPredList.h"
#include "gpopt/optimizer/COptimizerConfig.h"
#include "gpopt/xforms/CJoinOrderDPv2.h"
#include "gpopt/xforms/CXformUtils.h"



using namespace gpopt;


//---------------------------------------------------------------------------
//	@function:
//		CXformExpandNAryJoinDPv2::CXformExpandNAryJoinDPv2
//
//	@doc:
//		Ctor
//
//---------------------------------------------------------------------------
CXformExpandNAryJoinDPv2::CXformExpandNAryJoinDPv2(CMemoryPool *mp)
	: CXformExploration(
		  // pattern
		  GPOS_NEW(mp) CExpression(
			  mp, GPOS_NEW(mp) CLogicalNAryJoin(mp),
			  GPOS_NEW(mp) CExpression(mp, GPOS_NEW(mp) CPatternMultiLeaf(mp)),
			  GPOS_NEW(mp) CExpression(mp, GPOS_NEW(mp) CPatternTree(mp))))
{
}


//---------------------------------------------------------------------------
//	@function:
//		CXformExpandNAryJoinDPv2::Exfp
//
//	@doc:
//		Compute xform promise for a given expression handle
//
//---------------------------------------------------------------------------
CXform::EXformPromise
CXformExpandNAryJoinDPv2::Exfp(CExpressionHandle &exprhdl) const
{
	return CXformUtils::ExfpExpandJoinOrder(exprhdl, this);
}


//---------------------------------------------------------------------------
//	@function:
//		CXformExpandNAryJoinDPv2::Transform
//
//	@doc:
//		Actual transformation of n-ary join to cluster of inner joins using
//		dynamic programming
//
//---------------------------------------------------------------------------
void
CXformExpandNAryJoinDPv2::Transform(CXformContext *pxfctxt,
									CXformResult *pxfres,
									CExpression *pexpr) const
{
	GPOS_ASSERT(nullptr != pxfctxt);
	GPOS_ASSERT(nullptr != pxfres);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	CMemoryPool *mp = pxfctxt->Pmp();

	const ULONG arity = pexpr->Arity();
	GPOS_ASSERT(arity >= 3);

	// Make an expression array with all the atoms (the logical children)
	CExpressionArray *pdrgpexpr = GPOS_NEW(mp) CExpressionArray(mp);
	for (ULONG ul = 0; ul < arity - 1; ul++)
	{
		CExpression *pexprChild = (*pexpr)[ul];
		pexprChild->AddRef();
		pdrgpexpr->Append(pexprChild);
	}

	// Make an expression array with all the join predicates, one entry for
	// every conjunct (ANDed condition),
	// plus an array of all the non-inner join predicates, together with
	// a lookup table for each child whether it is a non-inner join
	CLogicalNAryJoin *naryJoin = CLogicalNAryJoin::PopConvert(pexpr->Pop());
	CExpression *pexprScalar = (*pexpr)[arity - 1];
	CExpressionArray *innerJoinPreds = nullptr;
	CExpressionArray *onPreds = GPOS_NEW(mp) CExpressionArray(mp);
	ULongPtrArray *childPredIndexes = nullptr;

	if (nullptr != CScalarNAryJoinPredList::PopConvert(pexprScalar->Pop()))
	{
		innerJoinPreds =
			CPredicateUtils::PdrgpexprConjuncts(mp, (*pexprScalar)[0]);

		for (ULONG ul = 1; ul < pexprScalar->Arity(); ul++)
		{
			(*pexprScalar)[ul]->AddRef();
			onPreds->Append((*pexprScalar)[ul]);
		}

		childPredIndexes = naryJoin->GetLojChildPredIndexes();
		GPOS_ASSERT(nullptr != childPredIndexes);
		childPredIndexes->AddRef();
	}
	else
	{
		innerJoinPreds = CPredicateUtils::PdrgpexprConjuncts(mp, pexprScalar);
	}

	CColRefSet *outerRefs = pexpr->DeriveOuterReferences();

	outerRefs->AddRef();

	// create join order using dynamic programming v2, record topk results in jodp
	CJoinOrderDPv2 jodp(mp, pdrgpexpr, innerJoinPreds, onPreds,
						childPredIndexes, outerRefs);
	jodp.PexprExpand();

	// Retrieve top K join orders from jodp and add as alternatives
	CExpression *nextJoinOrder = nullptr;

	while (nullptr != (nextJoinOrder = jodp.GetNextOfTopK()))
	{
		CExpression *pexprNormalized =
			CNormalizer::PexprNormalize(mp, nextJoinOrder);

		nextJoinOrder->Release();
		pxfres->Add(pexprNormalized);
	}
}

// EOF

相关信息

greenplumn 源码目录

相关文章

greenplumn CDecorrelator 源码

greenplumn CJoinOrder 源码

greenplumn CJoinOrderDP 源码

greenplumn CJoinOrderDPv2 源码

greenplumn CJoinOrderGreedy 源码

greenplumn CJoinOrderMinCard 源码

greenplumn CSubqueryHandler 源码

greenplumn CXform 源码

greenplumn CXformCTEAnchor2Sequence 源码

greenplumn CXformCTEAnchor2TrivialSelect 源码

0  赞