greenplumn CMappingVarColId 代码
文件路径:/src/backend/gpopt/translate/CMappingVarColId.cpp
/---------------------------------------------------------------------------
/ Greenplum Database
/ Copyright (C) 2011 Greenplum, Inc.
/
/ @filename:
/ CMappingVarColId.cpp
/
/ @doc:
/ Implementation of base (abstract) var mapping class
/
/ @test:
/
/
/---------------------------------------------------------------------------
extern "C" {
#include "postgres.h"
#include "nodes/primnodes.h"
#include "nodes/value.h"
}
#include "gpos/error/CAutoTrace.h"
#include "gpopt/gpdbwrappers.h"
#include "gpopt/translate/CMappingVarColId.h"
#include "gpopt/translate/CTranslatorUtils.h"
#include "naucrates/dxl/CDXLUtils.h"
#include "naucrates/dxl/operators/CDXLScalarIdent.h"
#include "naucrates/dxl/operators/CDXLScalarProjElem.h"
#include "naucrates/exception.h"
#include "naucrates/md/IMDIndex.h"
using namespace gpdxl;
using namespace gpmd;
/---------------------------------------------------------------------------
/ @function:
/ CMappingVarColId::CMappingVarColId
/
/ @doc:
/ Ctor
/
/---------------------------------------------------------------------------
CMappingVarColId::CMappingVarColId(CMemoryPool *mp) : m_mp(mp)
{
/ This map can have many entries if there are many tables with many columns
/ in the query, so use a larger hash map to minimize collisions
m_gpdb_att_opt_col_mapping =
GPOS_NEW(m_mp) GPDBAttOptColHashMap(m_mp, 2047);
}
/---------------------------------------------------------------------------
/ @function:
/ CMappingVarColId::GetGPDBAttOptColMapping
/
/ @doc:
/ Given a gpdb attribute, return the mapping info to opt col
/
/---------------------------------------------------------------------------
const CGPDBAttOptCol *
CMappingVarColId::GetGPDBAttOptColMapping(
ULONG current_query_level, const Var *var,
EPlStmtPhysicalOpType plstmt_physical_op_type) const
{
GPOS_ASSERT(nullptr != var);
GPOS_ASSERT(current_query_level >= var->varlevelsup);
/ absolute query level of var
ULONG abs_query_level = current_query_level - var->varlevelsup;
/ extract varno
ULONG var_no = var->varno;
if (EpspotWindow == plstmt_physical_op_type ||
EpspotAgg == plstmt_physical_op_type ||
EpspotMaterialize == plstmt_physical_op_type)
{
/ Agg and Materialize need to employ OUTER, since they have other
/ values in GPDB world
var_no = OUTER_VAR;
}
CGPDBAttInfo *gpdb_att_info =
GPOS_NEW(m_mp) CGPDBAttInfo(abs_query_level, var_no, var->varattno);
CGPDBAttOptCol *gpdb_att_opt_col_info =
m_gpdb_att_opt_col_mapping->Find(gpdb_att_info);
if (nullptr == gpdb_att_opt_col_info)
{
/ TODO: Sept 09 2013, remove temporary fix (revert exception to assert) to avoid crash during algebrization
GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiQuery2DXLError,
GPOS_WSZ_LIT("No variable"));
}
gpdb_att_info->Release();
return gpdb_att_opt_col_info;
}
/---------------------------------------------------------------------------
/ @function:
/ CMappingVarColId::GetOptColName
/
/ @doc:
/ Given a gpdb attribute, return a column name in optimizer world
/
/---------------------------------------------------------------------------
const CWStringBase *
CMappingVarColId::GetOptColName(
ULONG current_query_level, const Var *var,
EPlStmtPhysicalOpType plstmt_physical_op_type) const
{
return GetGPDBAttOptColMapping(current_query_level, var,
plstmt_physical_op_type)
->GetOptColInfo()
->GetOptColName();
}
/---------------------------------------------------------------------------
/ @function:
/ CMappingVarColId::GetColId
/
/ @doc:
/ given a gpdb attribute, return a column id in optimizer world
/
/---------------------------------------------------------------------------
ULONG
CMappingVarColId::GetColId(ULONG current_query_level, const Var *var,
EPlStmtPhysicalOpType plstmt_physical_op_type) const
{
return GetGPDBAttOptColMapping(current_query_level, var,
plstmt_physical_op_type)
->GetOptColInfo()
->GetColId();
}
/---------------------------------------------------------------------------
/ @function:
/ CMappingVarColId::Insert
/
/ @doc:
/ Insert a single entry into the hash map
/
/---------------------------------------------------------------------------
void
CMappingVarColId::Insert(ULONG query_level, ULONG var_no, INT attrnum,
ULONG colid, CWStringBase *column_name)
{
/ GPDB agg node uses 0 in Var, but that should've been taken care of
/ by translator
GPOS_ASSERT(var_no > 0);
/ create key
CGPDBAttInfo *gpdb_att_info =
GPOS_NEW(m_mp) CGPDBAttInfo(query_level, var_no, attrnum);
/ create value
COptColInfo *opt_col_info = GPOS_NEW(m_mp) COptColInfo(colid, column_name);
/ key is part of value, bump up refcount
gpdb_att_info->AddRef();
CGPDBAttOptCol *gpdb_att_opt_col_info =
GPOS_NEW(m_mp) CGPDBAttOptCol(gpdb_att_info, opt_col_info);
BOOL result GPOS_ASSERTS_ONLY = m_gpdb_att_opt_col_mapping->Insert(
gpdb_att_info, gpdb_att_opt_col_info);
GPOS_ASSERT(result);
}
/---------------------------------------------------------------------------
/ @function:
/ CMappingVarColId::LoadTblColumns
/
/ @doc:
/ Load up information from GPDB's base table RTE and corresponding
/ optimizer table descriptor
/
/---------------------------------------------------------------------------
void
CMappingVarColId::LoadTblColumns(ULONG query_level, ULONG RTE_index,
const CDXLTableDescr *table_descr)
{
GPOS_ASSERT(nullptr != table_descr);
const ULONG size = table_descr->Arity();
/ add mapping information for columns
for (ULONG i = 0; i < size; i++)
{
const CDXLColDescr *dxl_col_descr = table_descr->GetColumnDescrAt(i);
this->Insert(query_level, RTE_index, dxl_col_descr->AttrNum(),
dxl_col_descr->Id(),
dxl_col_descr->MdName()->GetMDName()->Copy(m_mp));
}
}
/---------------------------------------------------------------------------
/ @function:
/ CMappingVarColId::LoadIndexColumns
/
/ @doc:
/ Load up information from GPDB index and corresponding
/ optimizer table descriptor
/
/---------------------------------------------------------------------------
void
CMappingVarColId::LoadIndexColumns(ULONG query_level, ULONG RTE_index,
const IMDIndex *index,
const CDXLTableDescr *table_descr)
{
GPOS_ASSERT(nullptr != table_descr);
const ULONG size = index->Keys();
/ add mapping information for columns
for (ULONG i = 0; i < size; i++)
{
ULONG pos = index->KeyAt(i);
const CDXLColDescr *dxl_col_descr = table_descr->GetColumnDescrAt(pos);
this->Insert(query_level, RTE_index, INT(i + 1), dxl_col_descr->Id(),
dxl_col_descr->MdName()->GetMDName()->Copy(m_mp));
}
}
/---------------------------------------------------------------------------
/ @function:
/ CMappingVarColId::Load
/
/ @doc:
/ Load column mapping information from list of column names
/
/---------------------------------------------------------------------------
void
CMappingVarColId::Load(ULONG query_level, ULONG RTE_index,
CIdGenerator *id_generator, List *col_names)
{
ListCell *col_name = nullptr;
ULONG i = 0;
/ add mapping information for columns
ForEach(col_name, col_names)
{
Value *value = (Value *) lfirst(col_name);
CHAR *col_name_char_array = strVal(value);
CWStringDynamic *column_name =
CDXLUtils::CreateDynamicStringFromCharArray(m_mp,
col_name_char_array);
this->Insert(query_level, RTE_index, INT(i + 1),
id_generator->next_id(), column_name->Copy(m_mp));
i++;
GPOS_DELETE(column_name);
}
}
/---------------------------------------------------------------------------
/ @function:
/ CMappingVarColId::LoadColumns
/
/ @doc:
/ Load up columns information from the array of column descriptors
/
/---------------------------------------------------------------------------
void
CMappingVarColId::LoadColumns(ULONG query_level, ULONG RTE_index,
const CDXLColDescrArray *column_descrs)
{
GPOS_ASSERT(nullptr != column_descrs);
const ULONG size = column_descrs->Size();
/ add mapping information for columns
for (ULONG i = 0; i < size; i++)
{
const CDXLColDescr *dxl_col_descr = (*column_descrs)[i];
this->Insert(query_level, RTE_index, dxl_col_descr->AttrNum(),
dxl_col_descr->Id(),
dxl_col_descr->MdName()->GetMDName()->Copy(m_mp));
}
}
/---------------------------------------------------------------------------
/ @function:
/ CMappingVarColId::LoadDerivedTblColumns
/
/ @doc:
/ Load up information from column information in derived tables
/
/---------------------------------------------------------------------------
void
CMappingVarColId::LoadDerivedTblColumns(
ULONG query_level, ULONG RTE_index,
const CDXLNodeArray *derived_columns_dxl, List *target_list)
{
GPOS_ASSERT(nullptr != derived_columns_dxl);
GPOS_ASSERT((ULONG) gpdb::ListLength(target_list) >=
derived_columns_dxl->Size());
ULONG drvd_tbl_col_counter =
0; / counter for the dynamic array of DXL nodes
ListCell *lc = nullptr;
ForEach(lc, target_list)
{
TargetEntry *target_entry = (TargetEntry *) lfirst(lc);
if (!target_entry->resjunk)
{
GPOS_ASSERT(0 < target_entry->resno);
CDXLNode *dxlnode = (*derived_columns_dxl)[drvd_tbl_col_counter];
GPOS_ASSERT(nullptr != dxlnode);
CDXLScalarIdent *dxl_sc_ident =
CDXLScalarIdent::Cast(dxlnode->GetOperator());
const CDXLColRef *dxl_colref = dxl_sc_ident->GetDXLColRef();
this->Insert(query_level, RTE_index, INT(target_entry->resno),
dxl_colref->Id(),
dxl_colref->MdName()->GetMDName()->Copy(m_mp));
drvd_tbl_col_counter++;
}
}
}
/---------------------------------------------------------------------------
/ @function:
/ CMappingVarColId::LoadCTEColumns
/
/ @doc:
/ Load CTE column mappings
/
/---------------------------------------------------------------------------
void
CMappingVarColId::LoadCTEColumns(ULONG query_level, ULONG RTE_index,
const ULongPtrArray *CTE_columns,
List *target_list)
{
GPOS_ASSERT(nullptr != CTE_columns);
GPOS_ASSERT((ULONG) gpdb::ListLength(target_list) >= CTE_columns->Size());
ULONG idx = 0;
ListCell *lc = nullptr;
ForEach(lc, target_list)
{
TargetEntry *target_entry = (TargetEntry *) lfirst(lc);
if (!target_entry->resjunk)
{
GPOS_ASSERT(0 < target_entry->resno);
ULONG CTE_colid = *((*CTE_columns)[idx]);
CWStringDynamic *column_name =
CDXLUtils::CreateDynamicStringFromCharArray(
m_mp, target_entry->resname);
this->Insert(query_level, RTE_index, INT(target_entry->resno),
CTE_colid, column_name);
idx++;
}
}
}
/---------------------------------------------------------------------------
/ @function:
/ CMappingVarColId::LoadProjectElements
/
/ @doc:
/ Load up information from projection list created from GPDB join expression
/
/---------------------------------------------------------------------------
void
CMappingVarColId::LoadProjectElements(ULONG query_level, ULONG RTE_index,
const CDXLNode *project_list_dxlnode)
{
GPOS_ASSERT(nullptr != project_list_dxlnode);
const ULONG size = project_list_dxlnode->Arity();
/ add mapping information for columns
for (ULONG i = 0; i < size; i++)
{
CDXLNode *dxlnode = (*project_list_dxlnode)[i];
CDXLScalarProjElem *dxl_proj_elem =
CDXLScalarProjElem::Cast(dxlnode->GetOperator());
this->Insert(query_level, RTE_index, INT(i + 1), dxl_proj_elem->Id(),
dxl_proj_elem->GetMdNameAlias()->GetMDName()->Copy(m_mp));
}
}
/---------------------------------------------------------------------------
/ @function:
/ CMappingVarColId::CopyMapColId
/
/ @doc:
/ Create a deep copy
/
/---------------------------------------------------------------------------
CMappingVarColId *
CMappingVarColId::CopyMapColId(ULONG query_level) const
{
CMappingVarColId *var_colid_mapping = GPOS_NEW(m_mp) CMappingVarColId(m_mp);
/ iterate over full map
GPDBAttOptColHashMapIter col_map_iterator(this->m_gpdb_att_opt_col_mapping);
while (col_map_iterator.Advance())
{
const CGPDBAttOptCol *gpdb_att_opt_col_info = col_map_iterator.Value();
const CGPDBAttInfo *gpdb_att_info =
gpdb_att_opt_col_info->GetGPDBAttInfo();
const COptColInfo *opt_col_info =
gpdb_att_opt_col_info->GetOptColInfo();
if (gpdb_att_info->GetQueryLevel() <= query_level)
{
/ include all variables defined at same query level or before
CGPDBAttInfo *gpdb_att_info_new = GPOS_NEW(m_mp) CGPDBAttInfo(
gpdb_att_info->GetQueryLevel(), gpdb_att_info->GetVarNo(),
gpdb_att_info->GetAttNo());
COptColInfo *opt_col_info_new = GPOS_NEW(m_mp) COptColInfo(
opt_col_info->GetColId(),
GPOS_NEW(m_mp) CWStringConst(
m_mp, opt_col_info->GetOptColName()->GetBuffer()));
gpdb_att_info_new->AddRef();
CGPDBAttOptCol *gpdb_att_opt_col_new = GPOS_NEW(m_mp)
CGPDBAttOptCol(gpdb_att_info_new, opt_col_info_new);
/ insert into hashmap
BOOL result GPOS_ASSERTS_ONLY =
var_colid_mapping->m_gpdb_att_opt_col_mapping->Insert(
gpdb_att_info_new, gpdb_att_opt_col_new);
GPOS_ASSERT(result);
}
}
return var_colid_mapping;
}
/---------------------------------------------------------------------------
/ @function:
/ CMappingVarColId::CopyMapColId
/
/ @doc:
/ Create a deep copy
/
/---------------------------------------------------------------------------
CMappingVarColId *
CMappingVarColId::CopyMapColId(CMemoryPool *mp) const
{
CMappingVarColId *var_colid_mapping = GPOS_NEW(mp) CMappingVarColId(mp);
/ iterate over full map
GPDBAttOptColHashMapIter col_map_iterator(this->m_gpdb_att_opt_col_mapping);
while (col_map_iterator.Advance())
{
const CGPDBAttOptCol *gpdb_att_opt_col_info = col_map_iterator.Value();
const CGPDBAttInfo *gpdb_att_info =
gpdb_att_opt_col_info->GetGPDBAttInfo();
const COptColInfo *opt_col_info =
gpdb_att_opt_col_info->GetOptColInfo();
CGPDBAttInfo *gpdb_att_info_new = GPOS_NEW(mp)
CGPDBAttInfo(gpdb_att_info->GetQueryLevel(),
gpdb_att_info->GetVarNo(), gpdb_att_info->GetAttNo());
COptColInfo *opt_col_info_new = GPOS_NEW(mp) COptColInfo(
opt_col_info->GetColId(),
GPOS_NEW(mp)
CWStringConst(mp, opt_col_info->GetOptColName()->GetBuffer()));
gpdb_att_info_new->AddRef();
CGPDBAttOptCol *gpdb_att_opt_col_new =
GPOS_NEW(mp) CGPDBAttOptCol(gpdb_att_info_new, opt_col_info_new);
/ insert into hashmap
BOOL result GPOS_ASSERTS_ONLY =
var_colid_mapping->m_gpdb_att_opt_col_mapping->Insert(
gpdb_att_info_new, gpdb_att_opt_col_new);
GPOS_ASSERT(result);
}
return var_colid_mapping;
}
/---------------------------------------------------------------------------
/ @function:
/ CMappingVarColId::CopyRemapColId
/
/ @doc:
/ Create a copy of the mapping replacing the old column ids by new ones
/
/---------------------------------------------------------------------------
CMappingVarColId *
CMappingVarColId::CopyRemapColId(CMemoryPool *mp, ULongPtrArray *old_colids,
ULongPtrArray *new_colids) const
{
GPOS_ASSERT(nullptr != old_colids);
GPOS_ASSERT(nullptr != new_colids);
GPOS_ASSERT(new_colids->Size() == old_colids->Size());
/ construct a mapping old cols -> new cols
UlongToUlongMap *old_new_col_mapping =
CTranslatorUtils::MakeNewToOldColMapping(mp, old_colids, new_colids);
CMappingVarColId *var_colid_mapping = GPOS_NEW(mp) CMappingVarColId(mp);
GPDBAttOptColHashMapIter col_map_iterator(this->m_gpdb_att_opt_col_mapping);
while (col_map_iterator.Advance())
{
const CGPDBAttOptCol *gpdb_att_opt_col_info = col_map_iterator.Value();
const CGPDBAttInfo *gpdb_att_info =
gpdb_att_opt_col_info->GetGPDBAttInfo();
const COptColInfo *opt_col_info =
gpdb_att_opt_col_info->GetOptColInfo();
CGPDBAttInfo *gpdb_att_info_new = GPOS_NEW(mp)
CGPDBAttInfo(gpdb_att_info->GetQueryLevel(),
gpdb_att_info->GetVarNo(), gpdb_att_info->GetAttNo());
ULONG colid = opt_col_info->GetColId();
ULONG *new_colid = old_new_col_mapping->Find(&colid);
if (nullptr != new_colid)
{
colid = *new_colid;
}
COptColInfo *opt_col_info_new = GPOS_NEW(mp) COptColInfo(
colid, GPOS_NEW(mp) CWStringConst(
mp, opt_col_info->GetOptColName()->GetBuffer()));
gpdb_att_info_new->AddRef();
CGPDBAttOptCol *gpdb_att_opt_col_new =
GPOS_NEW(mp) CGPDBAttOptCol(gpdb_att_info_new, opt_col_info_new);
BOOL result GPOS_ASSERTS_ONLY =
var_colid_mapping->m_gpdb_att_opt_col_mapping->Insert(
gpdb_att_info_new, gpdb_att_opt_col_new);
GPOS_ASSERT(result);
}
old_new_col_mapping->Release();
return var_colid_mapping;
}
/ EOF
相关信息
相关文章
greenplumn CContextDXLToPlStmt 源码
greenplumn CContextQueryToDXL 源码
greenplumn CDXLTranslateContext 源码
greenplumn CDXLTranslateContextBaseTable 源码
greenplumn CMappingColIdVar 源码
greenplumn CMappingColIdVarPlStmt 源码
greenplumn CMappingElementColIdParamId 源码