Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ADBDEV-4603: Fix ORCA attribute not found in project list #1140

Open
wants to merge 4 commits into
base: adb-6.x-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions src/backend/gpopt/translate/CMappingColIdVarPlStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,34 @@ CMappingColIdVarPlStmt::GetOutputContext()
return m_output_context;
}

//---------------------------------------------------------------------------
// @function:
// CMappingColIdVarPlStmt::GetChildContexts
//
// @doc:
// Returns the child contexts
//
//---------------------------------------------------------------------------
CDXLTranslationContextArray *
CMappingColIdVarPlStmt::GetChildContexts()
{
return m_child_contexts;
}

//---------------------------------------------------------------------------
// @function:
// CMappingColIdVarPlStmt::GetBaseTableContext
//
// @doc:
// Returns the base table context
//
//---------------------------------------------------------------------------
const CDXLTranslateContextBaseTable *
CMappingColIdVarPlStmt::GetBaseTableContext()
{
return m_base_table_context;
}

//---------------------------------------------------------------------------
// @function:
// CMappingColIdVarPlStmt::ParamFromDXLNodeScId
Expand Down
175 changes: 59 additions & 116 deletions src/backend/gpopt/translate/CTranslatorDXLToScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -702,21 +702,68 @@ CTranslatorDXLToScalar::TranslateDXLScalarSubplanToScalar(

CDXLTranslateContext *output_context = plstmt->GetOutputContext();
CContextDXLToPlStmt *dxl_to_plstmt_ctxt = plstmt->GetDXLToPlStmtContext();
CDXLTranslationContextArray *outer_child_contexts =
plstmt->GetChildContexts();
const CDXLTranslateContextBaseTable *m_base_table_context =
plstmt->GetBaseTableContext();

CDXLScalarSubPlan *dxlop =
CDXLScalarSubPlan::Cast(scalar_subplan_node->GetOperator());

// translate subplan test expression
// Generate outer context for test expression.
// When walking through the test expression tree, the params (inner
// subplan output columns) will be looked for in the outer context.
CDXLTranslateContext test_expr_output_ctxt(
m_mp, output_context->IsParentAggNode(),
output_context->GetColIdToParamIdMap());

List *param_ids = NIL;
const CDXLColRefArray *test_expr_params = dxlop->GetTestExprParams();
// Fill in the param mapping of the outer context and save the param ids
if (NULL != test_expr_params)
{
const ULONG size = test_expr_params->Size();
for (ULONG ul = 0; ul < size; ul++)
{
CDXLColRef *dxl_colref = (*test_expr_params)[ul];
IMDId *mdid = dxl_colref->MdidType();
ULONG colid = dxl_colref->Id();
INT type_modifier = dxl_colref->TypeModifier();

if (NULL == test_expr_output_ctxt.GetParamIdMappingElement(colid))
{
CMappingElementColIdParamId *colid_to_param_id_map =
GPOS_NEW(m_mp) CMappingElementColIdParamId(
colid, dxl_to_plstmt_ctxt->GetNextParamId(), mdid,
type_modifier);
#ifdef GPOS_DEBUG
BOOL is_inserted =
#endif
test_expr_output_ctxt.FInsertParamMapping(
colid, colid_to_param_id_map);

Param *param = TranslateParamFromMapping(colid_to_param_id_map);
param_ids = gpdb::LAppendInt(param_ids, param->paramid);
}
}
}

// Generate var mapping to handle test expression based on the required
// output context. Test expression may contain vars from external
// (relative to subplan) nodes, so add their context too.
// We create a copy of the external mapping because we don't want to
// add TestExpr params to the original.
CMappingColIdVarPlStmt test_expr_var_mapping = CMappingColIdVarPlStmt(
m_mp, m_base_table_context, outer_child_contexts,
&test_expr_output_ctxt, plstmt->GetDXLToPlStmtContext());

// translate subplan test expression
SubLinkType slink = CTranslatorUtils::MapDXLSubplanToSublinkType(
dxlop->GetDxlSubplanType());
Expr *test_expr = TranslateDXLSubplanTestExprToScalar(
dxlop->GetDxlTestExpr(), slink, colid_var, dxlop->FOuterParam(),
&param_ids);
dxlop->GetDxlTestExpr(), slink, &test_expr_var_mapping);

const CDXLColRefArray *outer_refs = dxlop->GetDxlOuterColRefsArray();

const ULONG len = outer_refs->Size();

// Translate a copy of the translate context: the param mappings from the outer scope get copied in the constructor
Expand Down Expand Up @@ -785,57 +832,6 @@ CTranslatorDXLToScalar::TranslateDXLScalarSubplanToScalar(
return (Expr *) subplan;
}

//---------------------------------------------------------------------------
// @function:
// CTranslatorDXLToScalar::TranslateDXLTestExprScalarIdentToExpr
//
// @doc:
// Translate subplan test expression parameter
//
//---------------------------------------------------------------------------
void
CTranslatorDXLToScalar::TranslateDXLTestExprScalarIdentToExpr(
CDXLNode *child_node, Param *param, CDXLScalarIdent **ident, Expr **expr)
{
if (EdxlopScalarIdent == child_node->GetOperator()->GetDXLOperator())
{
// Ident
*ident = CDXLScalarIdent::Cast(child_node->GetOperator());
*expr = (Expr *) param;
}
else if (EdxlopScalarCast == child_node->GetOperator()->GetDXLOperator() &&
child_node->Arity() > 0 &&
EdxlopScalarIdent ==
(*child_node)[0]->GetOperator()->GetDXLOperator())
{
// Casted Ident
*ident = CDXLScalarIdent::Cast((*child_node)[0]->GetOperator());
CDXLScalarCast *scalar_cast =
CDXLScalarCast::Cast(child_node->GetOperator());
*expr =
TranslateDXLScalarCastWithChildExpr(scalar_cast, (Expr *) param);
}
else if (EdxlopScalarCoerceViaIO ==
child_node->GetOperator()->GetDXLOperator() &&
child_node->Arity() > 0 &&
EdxlopScalarIdent ==
(*child_node)[0]->GetOperator()->GetDXLOperator())
{
// CoerceViaIO over Ident
*ident = CDXLScalarIdent::Cast((*child_node)[0]->GetOperator());
CDXLScalarCoerceViaIO *coerce =
CDXLScalarCoerceViaIO::Cast(child_node->GetOperator());
*expr =
TranslateDXLScalarCoerceViaIOWithChildExpr(coerce, (Expr *) param);
}
else
{
// ORCA currently only supports PARAMs of the form id or cast(id)
GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXL2PlStmtConversion,
GPOS_WSZ_LIT("Unsupported subplan test expression"));
}
}


//---------------------------------------------------------------------------
// @function:
Expand All @@ -847,8 +843,7 @@ CTranslatorDXLToScalar::TranslateDXLTestExprScalarIdentToExpr(
//---------------------------------------------------------------------------
Expr *
CTranslatorDXLToScalar::TranslateDXLSubplanTestExprToScalar(
CDXLNode *test_expr_node, SubLinkType slink, CMappingColIdVar *colid_var,
BOOL has_outer_refs, List **param_ids)
CDXLNode *test_expr_node, SubLinkType slink, CMappingColIdVar *colid_var)
{
if (EXPR_SUBLINK == slink || EXISTS_SUBLINK == slink ||
NOT_EXISTS_SUBLINK == slink)
Expand Down Expand Up @@ -876,73 +871,20 @@ CTranslatorDXLToScalar::TranslateDXLSubplanTestExprToScalar(

// Translate arguments
List *args = NULL;
Expr *outer_expr = NULL;
Expr *inner_expr = NULL;

CDXLNode *outer_child_node = (*test_expr_node)[0];
CDXLNode *inner_child_node = (*test_expr_node)[1];

CContextDXLToPlStmt *dxl_to_plstmt_ctxt =
(dynamic_cast<CMappingColIdVarPlStmt *>(colid_var))
->GetDXLToPlStmtContext();
outer_expr = TranslateDXLToScalar(outer_child_node, colid_var);
GPOS_ASSERT(NULL != outer_expr);
args = gpdb::LAppend(args, outer_expr);

// translate outer expression (can be a deep scalar tree)
Expr *outer_arg_expr = NULL;
if (has_outer_refs)
{
Param *param1 = MakeNode(Param);
param1->paramkind = PARAM_EXEC;

CDXLScalarIdent *outer_ident = NULL;
Expr *outer_expr = NULL;

TranslateDXLTestExprScalarIdentToExpr(outer_child_node, param1,
&outer_ident, &outer_expr);
GPOS_ASSERT(NULL != outer_ident);
GPOS_ASSERT(NULL != outer_expr);

// finalize outer expression
param1->paramtype = CMDIdGPDB::CastMdid(outer_ident->MdidType())->Oid();
param1->paramtypmod = outer_ident->TypeModifier();
param1->paramid = dxl_to_plstmt_ctxt->GetNextParamId();

// test expression is used for non-scalar subplan,
// first arg of test expression must be an EXEC param1 referring to subplan output
args = gpdb::LAppend(args, outer_expr);

// also, add this param1 to subplan param1 ids before translating other params
*param_ids = gpdb::LAppendInt(*param_ids, param1->paramid);
}
else
{
outer_arg_expr = TranslateDXLToScalar(outer_child_node, colid_var);
args = gpdb::LAppend(args, outer_arg_expr);
}

// translate inner expression (only certain forms supported)
// second arg must be an EXEC param which is replaced during query execution with subplan output
Param *param = MakeNode(Param);
param->paramkind = PARAM_EXEC;
param->paramid = dxl_to_plstmt_ctxt->GetNextParamId();

CDXLScalarIdent *inner_ident = NULL;
Expr *inner_expr = NULL;

TranslateDXLTestExprScalarIdentToExpr(inner_child_node, param, &inner_ident,
&inner_expr);

GPOS_ASSERT(NULL != inner_ident);
inner_expr = TranslateDXLToScalar(inner_child_node, colid_var);
GPOS_ASSERT(NULL != inner_expr);

// finalize inner expression
param->paramtype = CMDIdGPDB::CastMdid(inner_ident->MdidType())->Oid();
param->paramtypmod = inner_ident->TypeModifier();

// test expression is used for non-scalar subplan,
// second arg of test expression must be an EXEC param referring to subplan output
args = gpdb::LAppend(args, inner_expr);

// also, add this param to subplan param ids before translating other params
*param_ids = gpdb::LAppendInt(*param_ids, param->paramid);

// finally, create an OpExpr for subplan test expression
CDXLScalarComp *scalar_cmp_dxl =
CDXLScalarComp::Cast(test_expr_node->GetOperator());
Expand Down Expand Up @@ -2020,6 +1962,7 @@ CTranslatorDXLToScalar::TranslateDXLScalarIdentToScalar(
dxlop->GetDXLColRef()->Id()))
{
// not an outer ref -> Translate var node

result_expr = (Expr *) colid_var->VarFromDXLNodeScId(dxlop);
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,9 @@ class CTranslatorExprToDXL
// helper to build a Result expression with project list restricted to required columns
CDXLNode *PdxlnRestrictResult(CDXLNode *dxlnode, const CColRefSet *colrefs);

// helper to build a projected DXLColRefs of Result node
CDXLColRefArray *GetResultProjectedColRefArray(CDXLNode *dxlProjectNode);

// helper to build subplans from correlated LOJ
void BuildSubplansForCorrelatedLOJ(
CExpression *pexprCorrelatedLOJ, CDXLColRefArray *dxl_colref_array,
Expand Down
68 changes: 60 additions & 8 deletions src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3089,7 +3089,7 @@ CTranslatorExprToDXL::PdxlnRestrictResult(CDXLNode *dxlnode,
//
// @doc:
// Helper to build a Result expression with project list
// restricted to required columns
// restricted to required columns.
//
//---------------------------------------------------------------------------
CDXLNode *
Expand Down Expand Up @@ -3157,6 +3157,48 @@ CTranslatorExprToDXL::PdxlnRestrictResult(CDXLNode *dxlnode,
return pdxlnResult;
}

//---------------------------------------------------------------------------
// @function:
// CTranslatorExprToDXL::GetResultProjectedColRefArray
//
// @doc:
// Helper to build an CDXLColRefArray of projected columns of Result node
//
//---------------------------------------------------------------------------
CDXLColRefArray *
CTranslatorExprToDXL::GetResultProjectedColRefArray(CDXLNode *dxlProjectNode)
{
if (NULL == dxlProjectNode)
{
return NULL;
}

CDXLNode *pdxlnProjList = (*dxlProjectNode)[0];
const ULONG ulPrjElems = pdxlnProjList->Arity();

if (0 == ulPrjElems)
{
return NULL;
}

CDXLColRefArray *dxlColRefArray = GPOS_NEW(m_mp) CDXLColRefArray(m_mp);
for (ULONG ul = 0; ul < ulPrjElems; ul++)
{
CDXLNode *child_dxlnode = (*pdxlnProjList)[ul];
CDXLScalarProjElem *pdxlPrjElem =
CDXLScalarProjElem::Cast(child_dxlnode->GetOperator());
CColRef *colref = m_pcf->LookupColRef(pdxlPrjElem->Id());

CMDName *mdname = GPOS_NEW(m_mp) CMDName(m_mp, colref->Name().Pstr());
IMDId *mdid = colref->RetrieveType()->MDId();
mdid->AddRef();
CDXLColRef *dxl_colref = GPOS_NEW(m_mp) CDXLColRef(
m_mp, mdname, colref->Id(), mdid, colref->TypeModifier());
dxlColRefArray->Append(dxl_colref);
}
return dxlColRefArray;
}

//---------------------------------------------------------------------------
// @function:
// CTranslatorExprToDXL::PdxlnQuantifiedSubplan
Expand All @@ -3175,7 +3217,8 @@ CTranslatorExprToDXL::PdxlnQuantifiedSubplan(
COperator *popCorrelatedJoin = pexprCorrelatedNLJoin->Pop();
COperator::EOperatorId op_id = popCorrelatedJoin->Eopid();
BOOL fCorrelatedLOJ =
(COperator::EopPhysicalCorrelatedLeftOuterNLJoin == op_id);
(COperator::EopPhysicalCorrelatedInLeftSemiNLJoin == op_id ||
COperator::EopPhysicalCorrelatedLeftOuterNLJoin == op_id);
GPOS_ASSERT(COperator::EopPhysicalCorrelatedInLeftSemiNLJoin == op_id ||
COperator::EopPhysicalCorrelatedNotInLeftAntiSemiNLJoin ==
op_id ||
Expand All @@ -3197,23 +3240,23 @@ CTranslatorExprToDXL::PdxlnQuantifiedSubplan(
CColRefSet *pcrInner = GPOS_NEW(m_mp) CColRefSet(m_mp);
pcrInner->Include((*pdrgpcrInner)[0]);

BOOL outerParam = false;
if (fCorrelatedLOJ)
{
// overwrite required inner column based on scalar expression
// Overwrite required inner column based on scalar expression.
// The columns contained in the scalar and the inner
// (intersection) are params of TestExpr if Correlated. The
// remaining columns of scalar are treated as vars. The vars
// refer to the node external to subplan.

CColRefSet *pcrsInner = pexprInner->DeriveOutputColumns();
CColRefSet *pcrsUsed =
GPOS_NEW(m_mp) CColRefSet(m_mp, *pexprScalar->DeriveUsedColumns());
pcrsUsed->Intersection(pcrsInner);
if (0 < pcrsUsed->Size())
{
GPOS_ASSERT(1 == pcrsUsed->Size() || 2 == pcrsUsed->Size());

// Both sides of the SubPlan test expression can come from the
// inner side. So we need to pass pcrsUsed instead of pcrInner into
// PdxlnRestrictResult()
outerParam = pcrsUsed->Size() > 1;

pcrInner->Release();
pcrInner = pcrsUsed;
Expand All @@ -3226,6 +3269,15 @@ CTranslatorExprToDXL::PdxlnQuantifiedSubplan(

CDXLNode *inner_dxlnode = PdxlnRestrictResult(pdxlnInnerChild, pcrInner);
pcrInner->Release();

// Params for the test expression are the output columns from the
// projection of the inner expression. The order of the params must
// match the order of the columns from the projection of the inner
// expression. For this obtain the necessary columns directly from
// the projection of result node.
CDXLColRefArray *test_expr_params =
GetResultProjectedColRefArray(inner_dxlnode);

if (NULL == inner_dxlnode)
{
GPOS_RAISE(
Expand All @@ -3245,7 +3297,7 @@ CTranslatorExprToDXL::PdxlnQuantifiedSubplan(
CDXLNode *pdxlnSubPlan = GPOS_NEW(m_mp)
CDXLNode(m_mp, GPOS_NEW(m_mp) CDXLScalarSubPlan(
m_mp, mdid, dxl_colref_array, dxl_subplan_type,
dxlnode_test_expr, outerParam));
dxlnode_test_expr, test_expr_params));
pdxlnSubPlan->AddChild(inner_dxlnode);

// add to hashmap
Expand Down
Loading
Loading