greenplumn CPartInfo 源码

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

greenplumn CPartInfo 代码

文件路径:/src/backend/gporca/libgpopt/src/base/CPartInfo.cpp

//---------------------------------------------------------------------------
//	Greenplum Database
//	Copyright (C) 2014 VMware, Inc. or its affiliates.
//
//	@filename:
//		CPartInfo.cpp
//
//	@doc:
//		Implementation of derived partition information at the logical level
//---------------------------------------------------------------------------

#include "gpopt/base/CPartInfo.h"

#include "gpos/base.h"
#include "gpos/error/CAutoTrace.h"

#include "gpopt/base/CUtils.h"
#include "gpopt/metadata/CPartConstraint.h"

using namespace gpopt;

FORCE_GENERATE_DBGSTR(CPartInfo);
FORCE_GENERATE_DBGSTR(CPartInfo::CPartInfoEntry);

//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::CPartInfoEntry::CPartInfoEntry
//
//	@doc:
//		Ctor
//
//---------------------------------------------------------------------------
CPartInfo::CPartInfoEntry::CPartInfoEntry(ULONG scan_id, IMDId *mdid,
										  CPartKeysArray *pdrgppartkeys)
	: m_scan_id(scan_id), m_mdid(mdid), m_pdrgppartkeys(pdrgppartkeys)
{
	GPOS_ASSERT(mdid->IsValid());
	GPOS_ASSERT(pdrgppartkeys != nullptr);
	GPOS_ASSERT(0 < pdrgppartkeys->Size());
}

//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::CPartInfoEntry::~CPartInfoEntry
//
//	@doc:
//		Dtor
//
//---------------------------------------------------------------------------
CPartInfo::CPartInfoEntry::~CPartInfoEntry()
{
	m_mdid->Release();
	m_pdrgppartkeys->Release();
}

//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::CPartInfoEntry::PpartinfoentryAddRemappedKeys
//
//	@doc:
//		Create a copy of the current object, and add a set of remapped
//		part keys to this entry, using the existing keys and the given hashmap
//
//---------------------------------------------------------------------------
CPartInfo::CPartInfoEntry *
CPartInfo::CPartInfoEntry::PpartinfoentryAddRemappedKeys(
	CMemoryPool *mp, CColRefSet *pcrs, UlongToColRefMap *colref_mapping)
{
	GPOS_ASSERT(nullptr != pcrs);
	GPOS_ASSERT(nullptr != colref_mapping);

	CPartKeysArray *pdrgppartkeys =
		CPartKeys::PdrgppartkeysCopy(mp, m_pdrgppartkeys);

	const ULONG size = m_pdrgppartkeys->Size();
	for (ULONG ul = 0; ul < size; ul++)
	{
		CPartKeys *ppartkeys = (*m_pdrgppartkeys)[ul];

		if (ppartkeys->FOverlap(pcrs))
		{
			pdrgppartkeys->Append(
				ppartkeys->PpartkeysRemap(mp, colref_mapping));
			break;
		}
	}

	m_mdid->AddRef();

	return GPOS_NEW(mp) CPartInfoEntry(m_scan_id, m_mdid, pdrgppartkeys);
}

//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::CPartInfoEntry::OsPrint
//
//	@doc:
//		Print functions
//
//---------------------------------------------------------------------------
IOstream &
CPartInfo::CPartInfoEntry::OsPrint(IOstream &os) const
{
	os << m_scan_id;

	return os;
}


//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::CPartInfoEntry::PpartinfoentryCopy
//
//	@doc:
//		Copy part info entry into given memory pool
//
//---------------------------------------------------------------------------
CPartInfo::CPartInfoEntry *
CPartInfo::CPartInfoEntry::PpartinfoentryCopy(CMemoryPool *mp) const
{
	IMDId *mdid = MDId();
	mdid->AddRef();

	// copy part keys
	CPartKeysArray *pdrgppartkeysCopy =
		CPartKeys::PdrgppartkeysCopy(mp, Pdrgppartkeys());

	// copy part constraint using empty remapping to get exact copy
	UlongToColRefMap *colref_mapping = GPOS_NEW(mp) UlongToColRefMap(mp);
	colref_mapping->Release();

	return GPOS_NEW(mp) CPartInfoEntry(ScanId(), mdid, pdrgppartkeysCopy);
}


//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::CPartInfo
//
//	@doc:
//		Ctor
//
//---------------------------------------------------------------------------
CPartInfo::CPartInfo(CPartInfoEntryArray *pdrgppartentries)
	: m_pdrgppartentries(pdrgppartentries)
{
	GPOS_ASSERT(nullptr != pdrgppartentries);
}

//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::CPartInfo
//
//	@doc:
//		Ctor
//
//---------------------------------------------------------------------------
CPartInfo::CPartInfo(CMemoryPool *mp)
{
	m_pdrgppartentries = GPOS_NEW(mp) CPartInfoEntryArray(mp);
}

//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::~CPartInfo
//
//	@doc:
//		Dtor
//
//---------------------------------------------------------------------------
CPartInfo::~CPartInfo()
{
	CRefCount::SafeRelease(m_pdrgppartentries);
}

//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::AddPartConsumer
//
//	@doc:
//		Add part table consumer
//
//---------------------------------------------------------------------------
void
CPartInfo::AddPartConsumer(CMemoryPool *mp, ULONG scan_id, IMDId *mdid,
						   CColRef2dArray *pdrgpdrgpcrPart)
{
	CPartKeysArray *pdrgppartkeys = GPOS_NEW(mp) CPartKeysArray(mp);
	pdrgppartkeys->Append(GPOS_NEW(mp) CPartKeys(pdrgpdrgpcrPart));

	m_pdrgppartentries->Append(
		GPOS_NEW(mp) CPartInfoEntry(scan_id, mdid, pdrgppartkeys));
}

//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::FContainsScanId
//
//	@doc:
//		Check if part info contains given scan id
//
//---------------------------------------------------------------------------
BOOL
CPartInfo::FContainsScanId(ULONG scan_id) const
{
	const ULONG size = m_pdrgppartentries->Size();

	for (ULONG ul = 0; ul < size; ul++)
	{
		CPartInfoEntry *ppartinfoentry = (*m_pdrgppartentries)[ul];
		if (scan_id == ppartinfoentry->ScanId())
		{
			return true;
		}
	}

	return false;
}

//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::ScanId
//
//	@doc:
//		Return scan id of the entry at the given position
//
//---------------------------------------------------------------------------
ULONG
CPartInfo::ScanId(ULONG ulPos) const
{
	return (*m_pdrgppartentries)[ulPos]->ScanId();
}

//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::GetRelMdId
//
//	@doc:
//		Return relation mdid of the entry at the given position
//
//---------------------------------------------------------------------------
IMDId *
CPartInfo::GetRelMdId(ULONG ulPos) const
{
	return (*m_pdrgppartentries)[ulPos]->MDId();
}

//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::Pdrgppartkeys
//
//	@doc:
//		Return part keys of the entry at the given position
//
//---------------------------------------------------------------------------
CPartKeysArray *
CPartInfo::Pdrgppartkeys(ULONG ulPos) const
{
	return (*m_pdrgppartentries)[ulPos]->Pdrgppartkeys();
}

//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::PdrgppartkeysByScanId
//
//	@doc:
//		Return part keys of the entry with the given scan id
//
//---------------------------------------------------------------------------
CPartKeysArray *
CPartInfo::PdrgppartkeysByScanId(ULONG scan_id) const
{
	const ULONG size = m_pdrgppartentries->Size();

	for (ULONG ul = 0; ul < size; ul++)
	{
		CPartInfoEntry *ppartinfoentry = (*m_pdrgppartentries)[ul];
		if (scan_id == ppartinfoentry->ScanId())
		{
			return ppartinfoentry->Pdrgppartkeys();
		}
	}

	return nullptr;
}

//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::PpartinfoWithRemappedKeys
//
//	@doc:
//		Return a new part info object with an additional set of remapped keys
//
//---------------------------------------------------------------------------
CPartInfo *
CPartInfo::PpartinfoWithRemappedKeys(CMemoryPool *mp, CColRefArray *pdrgpcrSrc,
									 CColRefArray *pdrgpcrDest) const
{
	GPOS_ASSERT(nullptr != pdrgpcrSrc);
	GPOS_ASSERT(nullptr != pdrgpcrDest);

	CColRefSet *pcrs = GPOS_NEW(mp) CColRefSet(mp, pdrgpcrSrc);
	UlongToColRefMap *colref_mapping =
		CUtils::PhmulcrMapping(mp, pdrgpcrSrc, pdrgpcrDest);

	CPartInfoEntryArray *pdrgppartentries =
		GPOS_NEW(mp) CPartInfoEntryArray(mp);

	const ULONG size = m_pdrgppartentries->Size();
	for (ULONG ul = 0; ul < size; ul++)
	{
		CPartInfoEntry *ppartinfoentry = (*m_pdrgppartentries)[ul];

		// if this entry has keys that overlap with the source columns then
		// add another set of keys to it using the destination columns
		CPartInfoEntry *ppartinfoentryNew =
			ppartinfoentry->PpartinfoentryAddRemappedKeys(mp, pcrs,
														  colref_mapping);
		pdrgppartentries->Append(ppartinfoentryNew);
	}

	pcrs->Release();
	colref_mapping->Release();

	return GPOS_NEW(mp) CPartInfo(pdrgppartentries);
}

//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::PpartinfoCombine
//
//	@doc:
//		Combine two part info objects
//
//---------------------------------------------------------------------------
CPartInfo *
CPartInfo::PpartinfoCombine(CMemoryPool *mp, CPartInfo *ppartinfoFst,
							CPartInfo *ppartinfoSnd)
{
	GPOS_ASSERT(nullptr != ppartinfoFst);
	GPOS_ASSERT(nullptr != ppartinfoSnd);

	CPartInfoEntryArray *pdrgppartentries =
		GPOS_NEW(mp) CPartInfoEntryArray(mp);

	// copy part entries from first part info object
	CUtils::AddRefAppend(pdrgppartentries, ppartinfoFst->m_pdrgppartentries);

	// copy part entries from second part info object, except those which already exist
	const ULONG length = ppartinfoSnd->m_pdrgppartentries->Size();
	for (ULONG ul = 0; ul < length; ul++)
	{
		CPartInfoEntry *ppartinfoentry =
			(*(ppartinfoSnd->m_pdrgppartentries))[ul];
		CPartKeysArray *pdrgppartkeys =
			ppartinfoFst->PdrgppartkeysByScanId(ppartinfoentry->ScanId());

		if (nullptr != pdrgppartkeys)
		{
			// there is already an entry with the same scan id; need to add to it
			// the keys from the current entry
			CPartKeysArray *pdrgppartkeysCopy = CPartKeys::PdrgppartkeysCopy(
				mp, ppartinfoentry->Pdrgppartkeys());
			CUtils::AddRefAppend(pdrgppartkeys, pdrgppartkeysCopy);
			pdrgppartkeysCopy->Release();
		}
		else
		{
			CPartInfoEntry *ppartinfoentryCopy =
				ppartinfoentry->PpartinfoentryCopy(mp);
			pdrgppartentries->Append(ppartinfoentryCopy);
		}
	}

	return GPOS_NEW(mp) CPartInfo(pdrgppartentries);
}

//---------------------------------------------------------------------------
//	@function:
//		CPartInfo::OsPrint
//
//	@doc:
//		Debug print
//
//---------------------------------------------------------------------------
IOstream &
CPartInfo::OsPrint(IOstream &os) const
{
	const ULONG length = m_pdrgppartentries->Size();
	os << "Part Consumers: ";
	for (ULONG ul = 0; ul < length; ul++)
	{
		CPartInfoEntry *ppartinfoentry = (*m_pdrgppartentries)[ul];
		ppartinfoentry->OsPrint(os);

		// separator
		os << (ul == length - 1 ? "" : ", ");
	}

	os << ", Part Keys: ";
	for (ULONG ulCons = 0; ulCons < length; ulCons++)
	{
		CPartKeysArray *pdrgppartkeys = Pdrgppartkeys(ulCons);
		os << "(";
		const ULONG ulPartKeys = pdrgppartkeys->Size();
		;
		for (ULONG ulPartKey = 0; ulPartKey < ulPartKeys; ulPartKey++)
		{
			os << *(*pdrgppartkeys)[ulPartKey];
			os << (ulPartKey == ulPartKeys - 1 ? "" : ", ");
		}
		os << ")";
		os << (ulCons == length - 1 ? "" : ", ");
	}

	return os;
}

// EOF

相关信息

greenplumn 源码目录

相关文章

greenplumn CAutoOptCtxt 源码

greenplumn CCTEInfo 源码

greenplumn CCTEMap 源码

greenplumn CCTEReq 源码

greenplumn CCastUtils 源码

greenplumn CColConstraintsArrayMapper 源码

greenplumn CColConstraintsHashMapper 源码

greenplumn CColRef 源码

greenplumn CColRefComputed 源码

greenplumn CColRefSet 源码

0  赞