You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hawq.apache.org by iw...@apache.org on 2016/06/08 02:53:44 UTC
[2/2] incubator-hawq git commit: Revert "HAWQ-765. Delete Deadcode:
CTranslatorDXLToQuery [#119780063]"
Revert "HAWQ-765. Delete Deadcode: CTranslatorDXLToQuery [#119780063]"
This reverts commit 235d999101b1cf54447b83677dc938f1ba3ad1a2.
Project: http://git-wip-us.apache.org/repos/asf/incubator-hawq/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-hawq/commit/3d11a580
Tree: http://git-wip-us.apache.org/repos/asf/incubator-hawq/tree/3d11a580
Diff: http://git-wip-us.apache.org/repos/asf/incubator-hawq/diff/3d11a580
Branch: refs/heads/master
Commit: 3d11a5806dac739179198a13c13490f35804af22
Parents: 37c5d64
Author: ivan <iw...@pivotal.io>
Authored: Wed Jun 8 10:53:16 2016 +0800
Committer: ivan <iw...@pivotal.io>
Committed: Wed Jun 8 10:53:16 2016 +0800
----------------------------------------------------------------------
.../gpopt/translate/CTranslatorDXLToQuery.cpp | 1478 ++++++++++++++++++
.../gpopt/translate/CTranslatorDXLToScalar.cpp | 212 +++
src/backend/gpopt/translate/Makefile | 1 +
src/backend/gpopt/utils/COptTasks.cpp | 87 ++
src/backend/gpopt/utils/funcs.cpp | 77 +
.../gpopt/translate/CTranslatorDXLToQuery.h | 317 ++++
.../gpopt/translate/CTranslatorDXLToScalar.h | 25 +
src/include/gpopt/utils/COptTasks.h | 4 +
8 files changed, 2201 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/3d11a580/src/backend/gpopt/translate/CTranslatorDXLToQuery.cpp
----------------------------------------------------------------------
diff --git a/src/backend/gpopt/translate/CTranslatorDXLToQuery.cpp b/src/backend/gpopt/translate/CTranslatorDXLToQuery.cpp
new file mode 100644
index 0000000..260fe63
--- /dev/null
+++ b/src/backend/gpopt/translate/CTranslatorDXLToQuery.cpp
@@ -0,0 +1,1478 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+//---------------------------------------------------------------------------
+// @filename:
+// CTranslatorDXLToQuery.cpp
+//
+// @doc:
+// Implementation of the methods used to translate a DXL tree into query.
+// All translator methods allocate memory in the provided memory pool, and
+// the caller is responsible for freeing it.
+//
+//
+// @test:
+//
+//
+//---------------------------------------------------------------------------
+
+#define ALLOW_DatumGetPointer
+#define ALLOW_ntohl
+#define ALLOW_memset
+#define ALLOW_printf
+
+#include "postgres.h"
+#include "gpopt/translate/CMappingColIdVarQuery.h"
+#include "gpopt/translate/CMappingElementColIdTE.h"
+#include "gpopt/translate/CTranslatorDXLToQuery.h"
+#include "gpopt/translate/CTranslatorDXLToPlStmt.h"
+#include "gpopt/translate/CTranslatorUtils.h"
+
+#include "gpos/base.h"
+#include "gpos/common/CBitSet.h"
+
+#include "naucrates/dxl/CDXLUtils.h"
+#include "naucrates/md/IMDColumn.h"
+#include "naucrates/md/IMDRelation.h"
+
+#include "gpopt/mdcache/CMDAccessor.h"
+
+#include "gpopt/gpdbwrappers.h"
+
+using namespace gpmd;
+using namespace gpdxl;
+using namespace gpos;
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::CTranslatorDXLToQuery
+//
+// @doc:
+// Constructor
+//
+//---------------------------------------------------------------------------
+CTranslatorDXLToQuery::CTranslatorDXLToQuery
+ (
+ IMemoryPool *pmp,
+ CMDAccessor *pmda,
+ ULONG ulSegments
+ )
+ :
+ m_pmp(pmp),
+ m_pmda(pmda),
+ m_ulSortgrouprefCounter(0),
+ m_ulSegments(ulSegments)
+{
+ m_pdxlsctranslator = GPOS_NEW(m_pmp) CTranslatorDXLToScalar(m_pmp, m_pmda, m_ulSegments);
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::~CTranslatorDXLToQuery
+//
+// @doc:
+// Destructor
+//
+//---------------------------------------------------------------------------
+CTranslatorDXLToQuery::~CTranslatorDXLToQuery()
+{
+ GPOS_DELETE(m_pdxlsctranslator);
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::PqueryFromDXL
+//
+// @doc:
+// Translate DXL node into a Query
+//
+//---------------------------------------------------------------------------
+Query *
+CTranslatorDXLToQuery::PqueryFromDXL
+ (
+ const CDXLNode *pdxln,
+ const DrgPdxln *pdrgpdxlnQueryOutput,
+ CStateDXLToQuery *pstatedxltoquery,
+ TEMap *ptemap,
+ ULONG ulQueryLevel
+ )
+{
+ // initialize the colid->var mapping
+ CMappingColIdVarQuery *pmapcidvarquery = GPOS_NEW(m_pmp) CMappingColIdVarQuery(m_pmp, ptemap, ulQueryLevel);
+
+ GPOS_ASSERT(NULL != pdxln);
+
+ Query *pquery = MakeNode(Query);
+
+ TranslateLogicalOp(pdxln, pquery, pstatedxltoquery, pmapcidvarquery);
+
+ if(0 == ulQueryLevel)
+ {
+ SetQueryOutput
+ (
+ pdrgpdxlnQueryOutput,
+ pquery,
+ pstatedxltoquery,
+ pmapcidvarquery
+ );
+ }
+ else
+ {
+ List *plTE = NIL;
+ const ULONG ulSize = pstatedxltoquery->UlLength();
+ for (ULONG ul = 0; ul < ulSize ; ul++)
+ {
+ TargetEntry *pte = pstatedxltoquery->PteColumn(ul);
+ GPOS_ASSERT(NULL != pte);
+
+ TargetEntry *pteCopy = (TargetEntry*) gpdb::PvCopyObject(pte);
+ pteCopy->resno = (AttrNumber) (ul + 1);
+
+ plTE = gpdb::PlAppendElement(plTE, pteCopy);
+ }
+ pquery->targetList = plTE;
+ }
+
+ // TODO: venky; June 14 2011, We currently assume that all queries are of the type select.
+ pquery->commandType = CMD_SELECT;
+
+ GPOS_DELETE(pmapcidvarquery);
+
+ if (m_pdxlsctranslator->FHasSubqueries())
+ {
+ pquery->hasSubLinks = true;
+ }
+
+ return pquery;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::PqueryFromDXLSubquery
+//
+// @doc:
+// Translate DXL node subquery into a Query
+//
+//---------------------------------------------------------------------------
+Query *
+CTranslatorDXLToQuery::PqueryFromDXLSubquery
+ (
+ const CDXLNode *pdxln,
+ ULONG ulColId,
+ CStateDXLToQuery *pstatedxltoquery,
+ TEMap *ptemap,
+ ULONG ulQueryLevel
+ )
+{
+
+ // initialize the colid->var mapping
+ CMappingColIdVarQuery *pmapcidvarquery = GPOS_NEW (m_pmp) CMappingColIdVarQuery(m_pmp, ptemap, ulQueryLevel);
+
+ GPOS_ASSERT(NULL != pdxln);
+
+ Query *pquery = MakeNode(Query);
+
+ TranslateLogicalOp(pdxln, pquery, pstatedxltoquery, pmapcidvarquery);
+
+
+ SetSubqueryOutput
+ (
+ ulColId,
+ pquery,
+ pstatedxltoquery,
+ pmapcidvarquery
+ );
+
+ pquery->commandType = CMD_SELECT;
+
+ GPOS_DELETE(pmapcidvarquery);
+
+ if (m_pdxlsctranslator->FHasSubqueries())
+ {
+ pquery->hasSubLinks = true;
+ }
+
+ return pquery;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::SetSubqueryOutput
+//
+// @doc:
+// Set query target list based on the DXL query output
+//
+//---------------------------------------------------------------------------
+void
+CTranslatorDXLToQuery::SetSubqueryOutput
+ (
+ ULONG ulColId,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ )
+{
+ GPOS_ASSERT(NULL != pquery);
+ CStateDXLToQuery *pstatedxltoqueryOutput = GPOS_NEW(m_pmp) CStateDXLToQuery(m_pmp);
+
+ List *plTE = NIL;
+ ULONG ulResno = 1;
+ const TargetEntry *pte = pmapcidvarquery->Pte(ulColId);
+
+ TargetEntry *pteCopy = (TargetEntry*) gpdb::PvCopyObject(const_cast<TargetEntry*>(pte));
+ pteCopy->resno = (AttrNumber) ulResno;
+
+ pstatedxltoqueryOutput->AddOutputColumnEntry(pteCopy, pteCopy->resname, ulColId);
+ plTE = gpdb::PlAppendElement(plTE, pteCopy);
+
+ const ULONG ulSize = pstatedxltoquery->UlLength();
+
+ // Add grouping and ordering columns that are not in the query output in the
+ // target list as resjunk entries.
+ ULONG ulCounter = 0;
+
+ for (ULONG ul = 0; ul < ulSize ; ul++)
+ {
+ TargetEntry *pteCurr = pstatedxltoquery->PteColumn(ul);
+ GPOS_ASSERT(NULL != pteCurr);
+
+ // we are only interested in grouping and ordering columns
+ if(pteCurr->ressortgroupref > 0)
+ {
+ // check if we have already added the corresponding pte entry in pplTE
+ BOOL fres = pstatedxltoqueryOutput->FTEFound(pteCurr);
+
+ if(!fres)
+ {
+ ulResno++;
+ // copy the entries
+ TargetEntry *pteCopyCurr = (TargetEntry*) gpdb::PvCopyObject(pteCurr);
+ pteCopyCurr->resno = (AttrNumber) ulResno;
+ pteCopyCurr->resjunk = true;
+
+ pstatedxltoqueryOutput->AddOutputColumnEntry
+ (
+ pteCopyCurr,
+ pteCopyCurr->resname,
+ pstatedxltoquery->UlColId(ul)
+ );
+ plTE = gpdb::PlAppendElement(plTE, pteCopyCurr);
+ }
+ }
+ ulCounter++;
+ }
+
+ pstatedxltoquery->Reload(pstatedxltoqueryOutput);
+ GPOS_DELETE(pstatedxltoqueryOutput);
+
+ pquery->targetList = plTE;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::SetQueryOutput
+//
+// @doc:
+// Set query target list based on the DXL query output
+//
+//---------------------------------------------------------------------------
+void
+CTranslatorDXLToQuery::SetQueryOutput
+ (
+ const DrgPdxln *pdrgpdxlnQueryOutput,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ )
+{
+ GPOS_ASSERT(NULL != pdrgpdxlnQueryOutput && NULL != pquery);
+
+ CStateDXLToQuery *pstatedxltoqueryOutput = GPOS_NEW(m_pmp) CStateDXLToQuery(m_pmp);
+
+ List *plTE = NIL;
+
+ ULONG ulResno = 0;
+ const ULONG ulLen = pdrgpdxlnQueryOutput->UlLength();
+ // translate each DXL scalar ident into a target entry
+ for (ULONG ul = 0; ul < ulLen; ul++)
+ {
+ CDXLNode *pdxlnIdent = (*pdrgpdxlnQueryOutput)[ul];
+ CDXLScalarIdent *pdxlop = CDXLScalarIdent::PdxlopConvert(pdxlnIdent->Pdxlop());
+ const CDXLColRef *pdxlcr = pdxlop->Pdxlcr();
+
+ GPOS_ASSERT(NULL != pdxlcr);
+ const ULONG ulColId = pdxlcr->UlID();
+ const CMDName *pmdname = pdxlcr->Pmdname();
+ const TargetEntry *pte = pmapcidvarquery->Pte(ulColId);
+
+ ulResno++;
+ TargetEntry *pteCopy = (TargetEntry*) gpdb::PvCopyObject(const_cast<TargetEntry*>(pte));
+ pteCopy->resname = CTranslatorUtils::SzFromWsz(pmdname->Pstr()->Wsz());
+ pteCopy->resno = (AttrNumber) ulResno;
+
+ pstatedxltoqueryOutput->AddOutputColumnEntry(pteCopy, pteCopy->resname, ulColId);
+ plTE = gpdb::PlAppendElement(plTE, pteCopy);
+ }
+
+ const ULONG ulSize = pstatedxltoquery->UlLength();
+
+ // Add grouping and ordering columns that are not in the query output in the
+ // target list as resjunk entries.
+
+ ULONG ulCounter = 0;
+
+ for (ULONG ul = 0; ul < ulSize ; ul++)
+ {
+ TargetEntry *pte = pstatedxltoquery->PteColumn(ul);
+ GPOS_ASSERT(NULL != pte);
+
+ // we are only interested in grouping and ordering columns
+ if(pte->ressortgroupref > 0)
+ {
+ // check if we have already added the corresponding pte entry in pplTE
+ BOOL fres = pstatedxltoqueryOutput->FTEFound(pte);
+
+ if(!fres)
+ {
+ ULONG ulColId = pstatedxltoquery->UlColId(ul);
+
+ ulResno++;
+ // copy the entries
+ TargetEntry *pteCopy = (TargetEntry*) gpdb::PvCopyObject(pte);
+ pteCopy->resno = (AttrNumber) ulResno;
+ pteCopy->resjunk = true;
+
+ pstatedxltoqueryOutput->AddOutputColumnEntry(pteCopy, pteCopy->resname, ulColId);
+ plTE = gpdb::PlAppendElement(plTE, pteCopy);
+ }
+ }
+ ulCounter++;
+ }
+
+ pstatedxltoquery->Reload(pstatedxltoqueryOutput);
+ GPOS_DELETE(pstatedxltoqueryOutput);
+
+ pquery->targetList = plTE;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::TranslateLogicalOp
+//
+// @doc:
+// Translates a DXL tree into a Query node
+//
+//---------------------------------------------------------------------------
+void
+CTranslatorDXLToQuery::TranslateLogicalOp
+ (
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ )
+{
+ STranslatorElem rgTranslators[] =
+ {
+ {EdxlopLogicalGet, &CTranslatorDXLToQuery::TranslateGet},
+ {EdxlopLogicalProject, &CTranslatorDXLToQuery::TranslateProject},
+ {EdxlopLogicalSelect, &CTranslatorDXLToQuery::TranslateSelect},
+ {EdxlopLogicalJoin, &CTranslatorDXLToQuery::TranslateJoin},
+ {EdxlopLogicalGrpBy, &CTranslatorDXLToQuery::TranslateGroupBy},
+ {EdxlopLogicalLimit, &CTranslatorDXLToQuery::TranslateLimit},
+ {EdxlopLogicalTVF, &CTranslatorDXLToQuery::TranslateTVF},
+ {EdxlopLogicalSetOp, &CTranslatorDXLToQuery::TranslateSetOp},
+ };
+
+ const ULONG ulTranslators = GPOS_ARRAY_SIZE(rgTranslators);
+
+ GPOS_ASSERT(NULL != pdxln);
+ GPOS_ASSERT(NULL != pquery);
+ Edxlopid eopid = pdxln->Pdxlop()->Edxlop();
+
+ // find translator for the node type
+ PfPexpr pf = NULL;
+ for (ULONG ul = 0; ul < ulTranslators; ul++)
+ {
+ STranslatorElem elem = rgTranslators[ul];
+ if (eopid == elem.eopid)
+ {
+ pf = elem.pf;
+ break;
+ }
+ }
+
+ if (NULL == pf)
+ {
+ GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXLUnrecognizedOperator, pdxln->Pdxlop()->PstrOpName()->Wsz());
+ }
+
+ (this->*pf)(pdxln, pquery, pstatedxltoquery, pmapcidvarquery);
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::TranslateGet
+//
+// @doc:
+// Translate a logical get operator
+//
+//---------------------------------------------------------------------------
+void
+CTranslatorDXLToQuery::TranslateGet
+(
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+)
+{
+ // This function must be called only for single table queries.
+ // For multi-table queries, see TranslateDXLLgJoin
+
+ RangeTblRef *prtref = PrtrefFromDXLLgGet(pdxln, pquery, pstatedxltoquery, pmapcidvarquery);
+
+ GPOS_ASSERT(NULL == pquery->jointree);
+
+ FromExpr *pfromexpr = MakeNode(FromExpr);
+ pfromexpr->fromlist = NULL;
+ pfromexpr->quals = NULL;
+ pfromexpr->fromlist = gpdb::PlAppendElement(pfromexpr->fromlist, prtref);
+ pquery->jointree = pfromexpr;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::TranslateTVF
+//
+// @doc:
+// Translate a logical TVF operator
+//
+//---------------------------------------------------------------------------
+void
+CTranslatorDXLToQuery::TranslateTVF
+(
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+)
+{
+ RangeTblRef *prtref = PrtrefFromDXLLgTVF(pdxln, pquery, pstatedxltoquery, pmapcidvarquery);
+
+ GPOS_ASSERT(NULL == pquery->jointree);
+
+ FromExpr *pfromexpr = MakeNode(FromExpr);
+ pfromexpr->fromlist = NULL;
+ pfromexpr->quals = NULL;
+ pfromexpr->fromlist = gpdb::PlAppendElement(pfromexpr->fromlist, prtref);
+ pquery->jointree = pfromexpr;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::TranslateSelect
+//
+// @doc:
+// Translate a logical select operator
+//
+//---------------------------------------------------------------------------
+void
+CTranslatorDXLToQuery::TranslateSelect
+(
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+)
+{
+ // translate children
+ CDXLNode *pdxlnCond = (*pdxln)[0];
+ CDXLNode *pdxlnChild = (*pdxln)[1];
+
+ // creating a range table entry because we could have the condition on an aggregate or a computed column
+ RangeTblRef *prtref = PrtrefFromDXLLgOp(pdxlnChild, pquery, pstatedxltoquery, pmapcidvarquery);
+ FromExpr *pfromexpr = MakeNode(FromExpr);
+ pfromexpr->fromlist = NULL;
+ pfromexpr->quals = NULL;
+ pfromexpr->fromlist = gpdb::PlAppendElement(pfromexpr->fromlist, prtref);
+ pquery->jointree = pfromexpr;
+
+ Expr *pexpr = m_pdxlsctranslator->PexprFromDXLNodeScalar
+ (
+ pdxlnCond,
+ pmapcidvarquery
+ );
+ GPOS_ASSERT(NULL == pquery->jointree->quals);
+
+ pquery->jointree->quals = (Node*) pexpr;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::TranslateSetOp
+//
+// @doc:
+// Translate a logical set operator
+//
+//---------------------------------------------------------------------------
+void
+CTranslatorDXLToQuery::TranslateSetOp
+ (
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ )
+{
+ // TODO: venky, Oct 24th 2012, we currently assume during DXL->Query translations that
+ // set ops are binary in nature which is not the case.
+ GPOS_ASSERT(2 == pdxln->UlArity());
+
+ CDXLLogicalSetOp *pdxlop = CDXLLogicalSetOp::PdxlopConvert(pdxln->Pdxlop());
+ EdxlSetOpType edxlsetop = pdxlop->Edxlsetoptype();
+
+ SetOperationStmt *psetop = MakeNode(SetOperationStmt);
+ psetop->op = CTranslatorUtils::Setoptype(pdxlop->Edxlsetoptype());
+ psetop->all = false;
+
+ if (EdxlsetopUnionAll == edxlsetop ||
+ EdxlsetopIntersectAll == edxlsetop ||
+ EdxlsetopDifferenceAll == edxlsetop
+ )
+ {
+ psetop->all = true;
+ }
+
+ // translate children
+ const ULONG ulArity = pdxln->UlArity();
+ for (ULONG ul = 0; ul < ulArity; ul++)
+ {
+ CDXLNode *pdxlnChild = (*pdxln)[ul];
+
+ CStateDXLToQuery *pstatedxltoqueryChild = GPOS_NEW(m_pmp) CStateDXLToQuery(m_pmp);
+ RangeTblRef *prtrefChild = PrtrefFromDXLLgOp(pdxlnChild, pquery, pstatedxltoqueryChild, pmapcidvarquery);
+ MarkUnusedColumns(pquery, prtrefChild, pstatedxltoqueryChild, pdxlop->Pdrgpul(ul) /*array of colids of the first child*/);
+ GPOS_DELETE(pstatedxltoqueryChild);
+
+ if (0 == ul)
+ {
+ psetop->larg = (Node*) prtrefChild;
+ }
+ else
+ {
+ psetop->rarg = (Node*) prtrefChild;
+ }
+ }
+
+ // add the output columns to the translator state
+ // add type information of the output columns to the set operator
+ psetop->colTypes = NIL;
+ psetop->colTypmods = NIL;
+
+ const DrgPdxlcd *pdrgpdxlcd = pdxlop->Pdrgpdxlcd();
+ const ULONG ulLen = pdrgpdxlcd->UlLength();
+ for (ULONG ul = 0; ul < ulLen; ul++)
+ {
+ const CDXLColDescr *pdxlcd = (*pdrgpdxlcd)[ul];
+ OID oid = CMDIdGPDB::PmdidConvert(pdxlcd->PmdidType())->OidObjectId();
+ psetop->colTypes = gpdb::PlAppendOid(psetop->colTypes, oid);
+ psetop->colTypmods = gpdb::PlAppendInt(psetop->colTypmods, -1);
+
+ TargetEntry *pte = MakeNode(TargetEntry);
+ Var *pvar = gpdb::PvarMakeVar(1, (AttrNumber) (ul + 1), oid, -1, 0);
+ pte->expr = (Expr*) pvar;
+ pte->resname = CTranslatorUtils::SzFromWsz(pdxlcd->Pmdname()->Pstr()->Wsz());
+ pte->resno = 1;
+
+ pstatedxltoquery->AddOutputColumnEntry(pte, pte->resname, pdxlcd->UlID());
+ }
+
+ pquery->jointree = MakeNode(FromExpr); // GPDB expects a from expr clause
+ pquery->setOperations = (Node *) psetop;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::MarkUnusedColumns
+//
+// @doc:
+// Mark unused target list entries in the setop child
+//
+//---------------------------------------------------------------------------
+void
+CTranslatorDXLToQuery::MarkUnusedColumns
+ (
+ Query *pquery,
+ RangeTblRef *prtref,
+ CStateDXLToQuery *pstatedxltoquery,
+ const DrgPul *pdrgpulColids
+ )
+{
+ const ULONG ulRTIndex = prtref->rtindex;
+ RangeTblEntry *prte = (RangeTblEntry*) gpdb::PvListNth(pquery->rtable, ulRTIndex -1);
+
+ GPOS_ASSERT(RTE_SUBQUERY == prte->rtekind);
+ Query *pqueryDerTbl = prte->subquery;
+
+ // maintain the list of used columns in a bit set
+ CBitSet *pds = GPOS_NEW(m_pmp) CBitSet(m_pmp);
+ const ULONG ulLen = pdrgpulColids->UlLength();
+ for (ULONG ul = 0; ul < ulLen; ul++)
+ {
+ ULONG ulValue = *((*pdrgpulColids)[ul]);
+ (void) pds->FExchangeSet(ulValue);
+ }
+
+ // Mark all columns that are not in the list of required input columns as being unused
+ const ULONG ulSize = pstatedxltoquery->UlLength();
+ for (ULONG ul = 0; ul < ulSize; ul++)
+ {
+ ULONG ulColId = pstatedxltoquery->UlColId(ul);
+ BOOL fSet = pds->FBit(ulColId);
+
+ if (!fSet)
+ {
+ // mark the column as unused in the query
+ TargetEntry *pte2 = (TargetEntry*) gpdb::PvListNth(pqueryDerTbl->targetList, ul);
+ pte2->resjunk = true;
+
+ // mark the column as unused in the state
+ TargetEntry *pte = pstatedxltoquery->PteColumn(ul);
+ pte->resjunk = true;
+ }
+ }
+
+ pds->Release();
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::TranslateGroupBy
+//
+// @doc:
+// Translate a logical groupby operator
+//
+//---------------------------------------------------------------------------
+void
+CTranslatorDXLToQuery::TranslateGroupBy
+(
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+)
+{
+ CDXLOperator *pdxlop = pdxln->Pdxlop();
+ CDXLLogicalGroupBy *pdxlnlggrpby = CDXLLogicalGroupBy::PdxlopConvert(pdxlop);
+
+ // translate children
+ CDXLNode *pdxlnProjectList = (*pdxln)[0];
+ CDXLNode *pdxlnChild = (*pdxln)[1];
+
+ RangeTblRef *prtref = PrtrefFromDXLLgOp(pdxlnChild, pquery, pstatedxltoquery, pmapcidvarquery);
+ FromExpr *pfromexpr = MakeNode(FromExpr);
+ pfromexpr->fromlist = NULL;
+ pfromexpr->quals = NULL;
+ pfromexpr->fromlist = gpdb::PlAppendElement(pfromexpr->fromlist, prtref);
+ pquery->jointree = pfromexpr;
+
+ TranslateGroupByColumns(pdxlnlggrpby, pquery, pstatedxltoquery, pmapcidvarquery);
+ TranslateProjList(pdxlnProjectList, pstatedxltoquery, pmapcidvarquery, pdxlnlggrpby->PdrgpulGroupingCols()->UlLength());
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::TranslateGroupByColumns
+//
+// @doc:
+// Translate a logical group by columns
+//
+//---------------------------------------------------------------------------
+void
+CTranslatorDXLToQuery::TranslateGroupByColumns
+ (
+ const CDXLLogicalGroupBy *pdxlnlggrpby,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ )
+{
+ pquery->hasAggs = true;
+ List *plGrpCl = NIL;
+
+ const DrgPul *pdrgpulGrpColId = pdxlnlggrpby->PdrgpulGroupingCols();
+
+ // discard the previously inserted entries in the TE
+ // as the query output will be composed of the grouping columns and the
+ // project list defined in the group by operator
+ pstatedxltoquery->Clear();
+
+ if (NULL != pdrgpulGrpColId)
+ {
+ for (ULONG ul = 0; ul < pdrgpulGrpColId->UlLength(); ul++)
+ {
+ GPOS_ASSERT(NULL != (*pdrgpulGrpColId)[ul]);
+ ULONG ulGroupingCol = *((*pdrgpulGrpColId)[ul]);
+
+ GroupClause *pgrpcl = MakeNode(GroupClause);
+ m_ulSortgrouprefCounter++;
+ pgrpcl->tleSortGroupRef = m_ulSortgrouprefCounter;
+ plGrpCl = gpdb::PlAppendElement(plGrpCl, pgrpcl);
+
+ TargetEntry *pte = const_cast<TargetEntry *>(pmapcidvarquery->Pte(ulGroupingCol));
+
+ OID oid = gpdb::OidExprType((Node*) pte->expr);
+ CMDIdGPDB *pmdid = CTranslatorUtils::PmdidWithVersion(m_pmp, oid);
+ const IMDType *pmdtype = m_pmda->Pmdtype(pmdid);
+ pmdid->Release();
+
+ const CMDIdGPDB *pmdidSortOp = CMDIdGPDB::PmdidConvert(pmdtype->PmdidCmp(IMDType::EcmptL));
+ pgrpcl->sortop = pmdidSortOp->OidObjectId();
+
+ GPOS_ASSERT(NULL != pte);
+
+ pte->resno = (AttrNumber) (ul + 1);
+ pte->ressortgroupref = pgrpcl->tleSortGroupRef;
+ pstatedxltoquery->AddOutputColumnEntry(pte, pte->resname, ulGroupingCol);
+ }
+ }
+ pquery->groupClause = plGrpCl;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::TranslateProject
+//
+// @doc:
+// Translate a logical project operator
+//
+//---------------------------------------------------------------------------
+void
+CTranslatorDXLToQuery::TranslateProject
+(
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+)
+{
+ // translate children
+ CDXLNode *pdxlnProjectList = (*pdxln)[0];
+ CDXLNode *pdxlnChild = (*pdxln)[1];
+
+ RangeTblRef *prtref = PrtrefFromDXLLgOp(pdxlnChild, pquery, pstatedxltoquery, pmapcidvarquery);
+
+ FromExpr *pfromexpr = MakeNode(FromExpr);
+ pfromexpr->fromlist = NULL;
+ pfromexpr->quals = NULL;
+ pfromexpr->fromlist = gpdb::PlAppendElement(pfromexpr->fromlist, prtref);
+ pquery->jointree = pfromexpr;
+
+ TranslateProjList(pdxlnProjectList, pstatedxltoquery, pmapcidvarquery, 0);
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::TranslateJoin
+//
+// @doc:
+// Translate a logical join operator
+//
+//---------------------------------------------------------------------------
+void
+CTranslatorDXLToQuery::TranslateJoin
+ (
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ )
+{
+ GPOS_ASSERT(NULL == pquery->jointree);
+
+ ULONG ulChildCount = pdxln->UlArity();
+ GPOS_ASSERT(2 < ulChildCount);
+
+ FromExpr *pfromexpr = MakeNode(FromExpr);
+ pfromexpr->fromlist = NULL;
+ pfromexpr->quals = NULL;
+ pquery->jointree = pfromexpr;
+
+ if (3 == ulChildCount)
+ {
+ // Convert pdxln into a JoinExpr
+ pfromexpr->fromlist = gpdb::PlAppendElement(pfromexpr->fromlist, PjoinexprFromDXLLgJoin(pdxln, pquery, pstatedxltoquery, pmapcidvarquery));
+ }
+ else
+ {
+ // An n-ary (where n > 2) join is:
+ // 1. stored as a list of (RangeTableRef or JoinExpr) in pfromexpr->fromlist
+ // 2. always of join type "inner" (All other join types are required to be a 2-way join)
+
+ GPOS_ASSERT(EdxljtInner == CDXLLogicalJoin::PdxlopConvert(pdxln->Pdxlop())->Edxltype());
+
+ ULONG ulResno=0;
+ for (ULONG ulI = 0; ulI < ulChildCount-1; ++ulI)
+ {
+ CDXLNode *pdxlnChild = (*pdxln)[ulI];
+
+ CStateDXLToQuery statedxltoqueryChild(m_pmp);
+
+ pfromexpr->fromlist = gpdb::PlAppendElement(pfromexpr->fromlist, PnodeFromDXLLgJoinChild(pdxlnChild, pquery, &statedxltoqueryChild, pmapcidvarquery));
+
+ ULONG ulSize = statedxltoqueryChild.UlLength();
+
+ // insert alias names from the right child to its parent
+ for(ULONG ulJ = 0; ulJ < ulSize; ulJ++)
+ {
+ ulResno++;
+ TargetEntry *pte = statedxltoqueryChild.PteColumn(ulJ);
+ CHAR *szColName = statedxltoqueryChild.SzColumnName(ulJ);
+ GPOS_ASSERT(NULL != pte && NULL != szColName);
+
+ TargetEntry *pteCopy = (TargetEntry*) gpdb::PvCopyObject(pte);
+ pteCopy->resno = (AttrNumber) ulResno;
+
+ pstatedxltoquery->AddOutputColumnEntry(pteCopy, szColName, statedxltoqueryChild.UlColId(ulJ));
+ }
+
+ }
+
+ // An n-ary (n > 2) with a where clause is represented as a: CDXLLogicalSelect on top of a CDXLLogicalJoin
+ // The last child (CDXLScalar) will be CDXLScalarConstValue representing "true" to signify a cross product.
+
+ GPOS_ASSERT(NULL != (*pdxln)[ulChildCount-1]);
+
+ // translate scalar condition representing the joinqual
+ CDXLNode *pdxlnCond = (*pdxln)[ulChildCount-1];
+
+ Expr *pexpr = m_pdxlsctranslator->PexprFromDXLNodeScalar
+ (
+ pdxlnCond,
+ pmapcidvarquery
+ );
+
+ pquery->jointree->quals = (Node*) pexpr;
+ }
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::TranslateLimit
+//
+// @doc:
+// Translate a logical limit operator
+//
+//---------------------------------------------------------------------------
+void
+CTranslatorDXLToQuery::TranslateLimit
+ (
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ )
+{
+ List *plSortCl = NIL;
+
+ GPOS_ASSERT(4 == pdxln->UlArity());
+
+ // get children
+ CDXLNode *pdxlnSortColList = (*pdxln)[0];
+ CDXLNode *pdxlnLimitCount = (*pdxln)[1];
+ CDXLNode *pdxlnLimitOffset = (*pdxln)[2];
+ CDXLNode *pdxlnChild = (*pdxln)[3];
+
+ // translate child node
+ TranslateLogicalOp(pdxlnChild, pquery, pstatedxltoquery, pmapcidvarquery);
+
+ // translate sorting column lists
+ const ULONG ulNumSortCols = pdxlnSortColList->UlArity();
+ if (0 < ulNumSortCols)
+ {
+ for (ULONG ul = 0; ul < ulNumSortCols; ul++)
+ {
+ CDXLNode *pdxlnSortCol = (*pdxlnSortColList)[ul];
+ CDXLScalarSortCol *pdxlopSortCol = CDXLScalarSortCol::PdxlopConvert(pdxlnSortCol->Pdxlop());
+
+ // get the target entry and the set the sortgroupref
+ ULONG ulSortColId = pdxlopSortCol->UlColId();
+ TargetEntry *pte = const_cast<TargetEntry *>(pmapcidvarquery->Pte(ulSortColId));
+ GPOS_ASSERT(NULL != pte);
+
+ // create the sort clause
+ SortClause *psortcl = MakeNode(SortClause);
+ psortcl->sortop = CMDIdGPDB::PmdidConvert(pdxlopSortCol->PmdidSortOp())->OidObjectId();
+ plSortCl = gpdb::PlAppendElement(plSortCl, psortcl);
+
+ // If ressortgroupref is not set then this column
+ // was not used as a grouping column.
+ if(0 == pte->ressortgroupref)
+ {
+ m_ulSortgrouprefCounter++;
+ pte->ressortgroupref = m_ulSortgrouprefCounter;
+ }
+
+ psortcl->tleSortGroupRef = pte->ressortgroupref;
+
+ if(!pstatedxltoquery->FTEFound(pte))
+ {
+ pstatedxltoquery->AddOutputColumnEntry(pte, pte->resname, ulSortColId);
+ }
+ }
+ }
+
+ GPOS_ASSERT(NULL != pdxlnLimitCount && NULL != pdxlnLimitOffset);
+
+ // translate the limit count and offset;
+ if(pdxlnLimitCount->UlArity() >0)
+ {
+ Expr *pexprCount = m_pdxlsctranslator->PexprFromDXLNodeScalar
+ (
+ (*pdxlnLimitCount)[0],
+ pmapcidvarquery
+ );
+
+ pquery->limitCount = (Node *) pexprCount;
+ }
+
+ if(pdxlnLimitOffset->UlArity() >0)
+ {
+ Expr *pexprOffset = m_pdxlsctranslator->PexprFromDXLNodeScalar
+ (
+ (*pdxlnLimitOffset)[0],
+ pmapcidvarquery
+ );
+
+ pquery->limitOffset = (Node *) pexprOffset;
+ }
+
+ pquery->sortClause = plSortCl;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::PrtrefFromDXLLgGet
+//
+// @doc:
+// Create a range table reference for a CDXLLogicalGet node
+//
+//---------------------------------------------------------------------------
+RangeTblRef *
+CTranslatorDXLToQuery::PrtrefFromDXLLgGet
+ (
+ const CDXLNode *pdxlnGet,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ )
+{
+ // For each CDXLLogicalGet node:
+ // 1. Add an rtable entry to query->rtable
+ // 2. Create an rtable reference to the newly generated rtable entry
+ // 3. Return the rtref
+
+ GPOS_ASSERT(NULL != pquery);
+
+ // translate table descriptor into a range table entry
+ CDXLLogicalGet *pdxlopGet = CDXLLogicalGet::PdxlopConvert(pdxlnGet->Pdxlop());
+
+ // we will add the new range table entry as the last element of the range table
+ Index iRel = gpdb::UlListLength(pquery->rtable) + 1;
+
+ RangeTblEntry *prte = PrteFromTblDescr(pdxlopGet->Pdxltabdesc(), iRel, pstatedxltoquery, pmapcidvarquery);
+
+ GPOS_ASSERT(NULL != prte);
+
+ pquery->rtable = gpdb::PlAppendElement(pquery->rtable, prte);
+
+ RangeTblRef *prtref = MakeNode(RangeTblRef);
+ prtref->rtindex = iRel;
+ return prtref;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::PnodeFromDXLLgJoinChild
+//
+// @doc:
+// Translate a child of a CDXLogicalJoin node into a GPDB Node
+//
+//---------------------------------------------------------------------------
+Node *
+CTranslatorDXLToQuery::PnodeFromDXLLgJoinChild
+ (
+ const CDXLNode *pdxlnChild,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ )
+{
+ Node *pnode = NULL;
+
+ switch (pdxlnChild->Pdxlop()->Edxlop())
+ {
+ case EdxlopLogicalGet:
+ pnode = (Node*) PrtrefFromDXLLgGet(pdxlnChild, pquery, pstatedxltoquery, pmapcidvarquery);
+ break;
+ case EdxlopLogicalJoin:
+ pnode = (Node*) PjoinexprFromDXLLgJoin(pdxlnChild, pquery, pstatedxltoquery, pmapcidvarquery);
+ break;
+ case EdxlopLogicalTVF:
+ pnode = (Node*) PrtrefFromDXLLgTVF(pdxlnChild, pquery, pstatedxltoquery, pmapcidvarquery);
+ break;
+ default:
+ pnode = (Node*) PrtrefFromDXLLgOp(pdxlnChild, pquery, pstatedxltoquery, pmapcidvarquery);
+ break;
+ }
+ return pnode;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::PrtrefFromDXLLgOp
+//
+// @doc:
+// Translate a CDXL Logical Node into derived table
+//
+//---------------------------------------------------------------------------
+RangeTblRef *
+CTranslatorDXLToQuery::PrtrefFromDXLLgOp
+ (
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ )
+{
+ GPOS_ASSERT(EdxloptypeLogical == pdxln->Pdxlop()->Edxloperatortype());
+
+ // initialize hash tables that maintains the mapping between ColId and TE and ColId and query level
+ TEMap *ptemapDerTbl = CTranslatorUtils::PtemapCopy(m_pmp, pmapcidvarquery->Ptemap());
+
+ CStateDXLToQuery statedxltoqueryDerived = CStateDXLToQuery(m_pmp);
+
+ // translate the CDXLNode representing the derived table
+ Query *pqueryDerTbl = PqueryFromDXL
+ (
+ pdxln,
+ NULL, // NULL stands for the fact that we do not care about the output columns of derived table (This is not true for subqueries)
+ &statedxltoqueryDerived,
+ ptemapDerTbl,
+ pmapcidvarquery->UlQueryLevel()+1
+ );
+
+ CRefCount::SafeRelease(ptemapDerTbl);
+
+ // create a rtable entry for the derived table
+ RangeTblEntry *prte = MakeNode(RangeTblEntry);
+
+ prte->subquery = pqueryDerTbl;
+ prte->rtekind = RTE_SUBQUERY;
+ prte->inFromCl = false;
+ pquery->rtable = gpdb::PlAppendElement(pquery->rtable, prte);
+
+ ULONG ulRTIndex = gpdb::UlListLength(pquery->rtable);
+ ULONG ulResno = 0;
+ // create alias
+ Alias *palias = MakeNode(Alias);
+
+
+ ULONG ulDerivedOutputColumnSize = statedxltoqueryDerived.UlLength();
+
+ // from each target list entry of the derived table
+ // 1. create a target list entry and map col->TE at query current level
+ // 2. insert the alias name in the joinaliasvars
+
+ for(ULONG ul=0; ul<ulDerivedOutputColumnSize; ul++)
+ {
+ ulResno++;
+ TargetEntry *pte = statedxltoqueryDerived.PteColumn(ul);
+ CHAR *szColName = statedxltoqueryDerived.SzColumnName(ul);
+ ULONG ulColId = statedxltoqueryDerived.UlColId(ul);
+
+ if (!pte->resjunk)
+ {
+ TargetEntry *pteCopy = MakeNode(TargetEntry);
+ Var *pvarNew = NULL;
+
+ if (IsA(pte->expr, Var))
+ {
+ prte->joinaliasvars = gpdb::PlAppendElement(prte->joinaliasvars, pte->expr);
+ Var *pvar = (Var*) pte->expr;
+
+ pvarNew = gpdb::PvarMakeVar(ulRTIndex, (AttrNumber) ulResno, pvar->vartype, pvar->vartypmod, 0);
+ }
+ else
+ {
+ pvarNew = gpdb::PvarMakeVar(ulRTIndex, (AttrNumber) ulResno, gpdb::OidExprType( (Node*) pte->expr), -1, 0);
+ }
+
+ pteCopy->resno = (AttrNumber) ulResno;
+ pteCopy->expr = (Expr*) pvarNew;
+ pteCopy->resname = PStrDup(szColName);
+
+ pmapcidvarquery->FInsertMapping(ulColId, pteCopy);
+ palias->colnames = gpdb::PlAppendElement(palias->colnames, gpdb::PvalMakeString(szColName));
+ pstatedxltoquery->AddOutputColumnEntry(pteCopy, pteCopy->resname, ulColId);
+ }
+ }
+
+ prte->alias = palias;
+ prte->eref = palias;
+
+ RangeTblRef *prtref = MakeNode(RangeTblRef);
+ prtref->rtindex = ulRTIndex;
+
+ return prtref;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::PjoinexprFromDXLLgJoin
+//
+// @doc:
+// Translate a Logical Join Node into a GPDB JoinExpr
+//
+//---------------------------------------------------------------------------
+JoinExpr *
+CTranslatorDXLToQuery::PjoinexprFromDXLLgJoin
+ (
+ const CDXLNode *pdxlnJoin,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ )
+{
+ GPOS_ASSERT(NULL != pquery && NULL != pdxlnJoin);
+ const ULONG ulChildCount = pdxlnJoin->UlArity();
+ GPOS_ASSERT(3 == ulChildCount);
+
+ // create a joinexpr
+ JoinExpr *pjoinexpr = MakeNode(JoinExpr);
+
+ // translate the left child
+ CDXLNode *pdxlnLeft = (*pdxlnJoin)[0];
+
+ CStateDXLToQuery statedxltoqueryLeft = CStateDXLToQuery(m_pmp);
+ pjoinexpr->larg = PnodeFromDXLLgJoinChild(pdxlnLeft, pquery, &statedxltoqueryLeft, pmapcidvarquery);
+
+ // translate the right child
+ CDXLNode *pdxlnRight = (*pdxlnJoin)[1];
+
+ CStateDXLToQuery statedxltoqueryRight = CStateDXLToQuery(m_pmp);
+ pjoinexpr->rarg = PnodeFromDXLLgJoinChild(pdxlnRight, pquery, &statedxltoqueryRight, pmapcidvarquery);
+
+ // set the join type
+ CDXLLogicalJoin *pdxlopJoin = CDXLLogicalJoin::PdxlopConvert(pdxlnJoin->Pdxlop());
+ pjoinexpr->jointype = CTranslatorDXLToPlStmt::JtFromEdxljt(pdxlopJoin->Edxltype());
+
+ // translate scalar condition representing the joinqual
+ CDXLNode *pdxlnCond = (*pdxlnJoin)[ulChildCount-1];
+
+ Expr *pexpr = m_pdxlsctranslator->PexprFromDXLNodeScalar
+ (
+ pdxlnCond,
+ pmapcidvarquery
+ );
+
+ // Add the new range table entry for the join to the range table
+ Index iRel = gpdb::UlListLength(pquery->rtable) + 1;
+ pjoinexpr->rtindex = iRel;
+ RangeTblEntry *prte = MakeNode(RangeTblEntry);
+
+ prte->rtekind = RTE_JOIN;
+ prte->jointype = pjoinexpr->jointype;
+ prte->inFromCl = false;
+
+ Alias *palias = MakeNode(Alias);
+ ULONG ulResno = 0;
+ const ULONG ulLeftOutputColumnSize = statedxltoqueryLeft.UlLength();
+ // insert alias names from the left child to its parent
+ for(ULONG ul = 0; ul < ulLeftOutputColumnSize; ul++)
+ {
+ TargetEntry *pte = statedxltoqueryLeft.PteColumn(ul);
+ CHAR *szColName = statedxltoqueryLeft.SzColumnName(ul);
+
+ ulResno++;
+ TargetEntry *pteCopy = (TargetEntry*) gpdb::PvCopyObject(pte);
+ pteCopy->resno = (AttrNumber) ulResno;
+
+ if(IsA(pteCopy->expr, Var))
+ {
+ prte->joinaliasvars = gpdb::PlAppendElement(prte->joinaliasvars, pteCopy->expr);
+ }
+
+ pstatedxltoquery->AddOutputColumnEntry(pteCopy, szColName, statedxltoqueryLeft.UlColId(ul));
+ palias->colnames = gpdb::PlAppendElement(palias->colnames, gpdb::PvalMakeString(szColName));
+ }
+
+ const ULONG ulRightOutputColumnSize = statedxltoqueryRight.UlLength();
+
+ // insert alias names from the right child to its parent
+ for(ULONG ul = 0; ul < ulRightOutputColumnSize; ul++)
+ {
+ TargetEntry *pte = statedxltoqueryRight.PteColumn(ul);
+ CHAR *szColName = statedxltoqueryRight.SzColumnName(ul);
+
+ ulResno++;
+ TargetEntry *pteCopy = (TargetEntry*) gpdb::PvCopyObject(pte);
+ pteCopy->resno = (AttrNumber) ulResno;
+
+ if(IsA(pteCopy->expr, Var))
+ {
+ prte->joinaliasvars = gpdb::PlAppendElement(prte->joinaliasvars, pteCopy->expr);
+ }
+
+ pstatedxltoquery->AddOutputColumnEntry(pteCopy, szColName, statedxltoqueryRight.UlColId(ul));
+ palias->colnames = gpdb::PlAppendElement(palias->colnames, gpdb::PvalMakeString(szColName));
+ }
+
+ prte->alias = palias;
+ prte->eref = palias;
+
+ pjoinexpr->quals = (Node*) pexpr;
+
+ pquery->rtable = gpdb::PlAppendElement(pquery->rtable, prte);
+
+ return pjoinexpr;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::TranslateProjList
+//
+// @doc:
+// Translates a DXL projection list
+//
+//---------------------------------------------------------------------------
+void
+CTranslatorDXLToQuery::TranslateProjList
+ (
+ const CDXLNode *pdxlnPrL,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery,
+ ULONG ulTargetEntryIndex
+ )
+{
+ if (NULL != pdxlnPrL)
+ {
+ // translate each DXL project element into a target entry
+ const ULONG ulArity = pdxlnPrL->UlArity();
+ for (ULONG ul = 0; ul < ulArity; ++ul)
+ {
+ CDXLNode *pdxlnPrEl = (*pdxlnPrL)[ul];
+ CDXLScalarProjElem *pdxlopPrEl = CDXLScalarProjElem::PdxlopConvert(pdxlnPrEl->Pdxlop());
+
+ GPOS_ASSERT(1 == pdxlnPrEl->UlArity());
+ // translate proj element expression
+ CDXLNode *pdxlnExpr = (*pdxlnPrEl)[0];
+
+ Expr *pexpr = m_pdxlsctranslator->PexprFromDXLNodeScalar(pdxlnExpr, pmapcidvarquery);
+
+ GPOS_ASSERT(NULL != pexpr);
+
+ TargetEntry *pte = MakeNode(TargetEntry);
+ pte->expr = pexpr;
+ pte->resname = CTranslatorUtils::SzFromWsz(pdxlopPrEl->PmdnameAlias()->Pstr()->Wsz());
+ pte->resno = (AttrNumber) (ulTargetEntryIndex + ul + 1);
+
+ pstatedxltoquery->AddOutputColumnEntry(pte, pte->resname, pdxlopPrEl->UlId());
+ //save mapping col id -> Var in the query translation context
+ pmapcidvarquery->FInsertMapping(pdxlopPrEl->UlId(), pte);
+ }
+ }
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::PrteFromTblDescr
+//
+// @doc:
+// Translates a DXL table descriptor into a range table entry
+//
+//---------------------------------------------------------------------------
+RangeTblEntry *
+CTranslatorDXLToQuery::PrteFromTblDescr
+ (
+ const CDXLTableDescr *pdxltabdesc,
+ Index iRel,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ )
+{
+ GPOS_ASSERT(0 == pstatedxltoquery->UlLength());
+
+ RangeTblEntry *prte = MakeNode(RangeTblEntry);
+ prte->rtekind = RTE_RELATION;
+
+ // get oid for table
+ CMDIdGPDB *pmdid = CMDIdGPDB::PmdidConvert(pdxltabdesc->Pmdid());
+ prte->relid = pmdid->OidObjectId();
+
+ Alias *palias = MakeNode(Alias);
+ palias->colnames = NIL;
+
+ // get table alias
+ palias->aliasname = CTranslatorUtils::SzFromWsz(pdxltabdesc->Pmdname()->Pstr()->Wsz());
+
+ // get column names
+ const ULONG ulArity = pdxltabdesc->UlArity();
+ for (ULONG ul = 0; ul < ulArity; ++ul)
+ {
+ const CDXLColDescr *pdxlcd = pdxltabdesc->Pdxlcd(ul);
+
+ CHAR *szColName = CTranslatorUtils::SzFromWsz(pdxlcd->Pmdname()->Pstr()->Wsz());
+ GPOS_ASSERT(NULL != pdxlcd);
+ GPOS_ASSERT(0 != pdxlcd->IAttno());
+
+ Value *pvalColName = gpdb::PvalMakeString(szColName);
+ palias->colnames = gpdb::PlAppendElement(palias->colnames, pvalColName);
+
+ const CMDIdGPDB *pmdidColType = CMDIdGPDB::PmdidConvert(pdxlcd->PmdidType());
+ OID oidAttType = pmdidColType->OidObjectId();
+ GPOS_ASSERT(InvalidOid != oidAttType);
+
+ Var *pvar = gpdb::PvarMakeVar
+ (
+ iRel,
+ (AttrNumber) pdxlcd->IAttno(),
+ oidAttType,
+ -1, // vartypmod
+ 0
+ );
+
+ TargetEntry *pte = MakeNode(TargetEntry);
+ pte->expr = (Expr*) pvar;
+ pte->resname = szColName;
+ pte->resno = (AttrNumber) pdxlcd->IAttno();
+
+ //save mapping col id -> Var in the query translation context
+ pmapcidvarquery->FInsertMapping(pdxlcd->UlID(), pte);
+
+ pstatedxltoquery->AddOutputColumnEntry(pte, pte->resname, pdxlcd->UlID());
+ }
+
+ prte->eref = palias;
+
+ return prte;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToQuery::PrtrefFromDXLLgTVF
+//
+// @doc:
+// Create a range table reference for a CDXLLogicalTVF node
+//
+//---------------------------------------------------------------------------
+RangeTblRef *
+CTranslatorDXLToQuery::PrtrefFromDXLLgTVF
+ (
+ const CDXLNode *pdxlnTVF,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ )
+{
+ GPOS_ASSERT(0 == pstatedxltoquery->UlLength());
+
+ Index iRel = gpdb::UlListLength(pquery->rtable) + 1;
+
+ CDXLLogicalTVF *pdxlopTVF = CDXLLogicalTVF::PdxlopConvert(pdxlnTVF->Pdxlop());
+
+ RangeTblEntry *prte = MakeNode(RangeTblEntry);
+ prte->rtekind = RTE_FUNCTION;
+
+ FuncExpr *pfuncexpr = MakeNode(FuncExpr);
+
+ pfuncexpr->funcid = CMDIdGPDB::PmdidConvert(pdxlopTVF->PmdidFunc())->OidObjectId();
+ pfuncexpr->funcretset = true;
+ // this is a function call, as opposed to a cast
+ pfuncexpr->funcformat = COERCE_EXPLICIT_CALL;
+ pfuncexpr->funcresulttype = CMDIdGPDB::PmdidConvert(pdxlopTVF->PmdidRetType())->OidObjectId();
+
+ Alias *palias = MakeNode(Alias);
+ palias->colnames = NIL;
+
+ // get function alias
+ palias->aliasname = CTranslatorUtils::SzFromWsz(pdxlopTVF->Pmdname()->Pstr()->Wsz());
+
+ // get column names and types
+ const ULONG ulColumns = pdxlopTVF->UlArity();
+ for (ULONG ul = 0; ul < ulColumns; ++ul)
+ {
+ const CDXLColDescr *pdxlcd = pdxlopTVF->Pdxlcd(ul);
+
+ CHAR *szColName = CTranslatorUtils::SzFromWsz(pdxlcd->Pmdname()->Pstr()->Wsz());
+ GPOS_ASSERT(NULL != pdxlcd);
+ GPOS_ASSERT(0 != pdxlcd->IAttno());
+
+ Value *pvalColName = gpdb::PvalMakeString(szColName);
+ palias->colnames = gpdb::PlAppendElement(palias->colnames, pvalColName);
+
+ const CMDIdGPDB *pmdidColType = CMDIdGPDB::PmdidConvert(pdxlcd->PmdidType());
+ OID oidAttType = pmdidColType->OidObjectId();
+ GPOS_ASSERT(InvalidOid != oidAttType);
+
+ prte->funccoltypes = gpdb::PlAppendOid(prte->funccoltypes, oidAttType);
+ prte->funccoltypmods = gpdb::PlAppendInt(prte->funccoltypmods, -1);
+
+ Var *pvar = gpdb::PvarMakeVar
+ (
+ iRel,
+ (AttrNumber) pdxlcd->IAttno(),
+ oidAttType,
+ -1, // vartypmod
+ 0
+ );
+
+ TargetEntry *pte = MakeNode(TargetEntry);
+ pte->expr = (Expr*) pvar;
+ pte->resname = szColName;
+ pte->resno = (AttrNumber) pdxlcd->IAttno();
+
+ //save mapping col id -> Var in the query translation context
+ pmapcidvarquery->FInsertMapping(pdxlcd->UlID(), pte);
+
+ pstatedxltoquery->AddOutputColumnEntry(pte, pte->resname, pdxlcd->UlID());
+ }
+
+ // function arguments
+ const ULONG ulArity = pdxlnTVF->UlArity();
+ for (ULONG ul = 0; ul < ulArity; ++ul)
+ {
+ CDXLNode *pdxlnFuncArg = (*pdxlnTVF)[ul];
+ Expr *pexprFuncArg = m_pdxlsctranslator->PexprFromDXLNodeScalar(pdxlnFuncArg, pmapcidvarquery);
+ pfuncexpr->args = gpdb::PlAppendElement(pfuncexpr->args, pexprFuncArg);
+ }
+
+ prte->funcexpr = (Node *)pfuncexpr;
+ prte->inFromCl = true;
+ prte->eref = palias;
+
+ pquery->rtable = gpdb::PlAppendElement(pquery->rtable, prte);
+
+ RangeTblRef *prtref = MakeNode(RangeTblRef);
+ prtref->rtindex = iRel;
+ return prtref;
+}
+
+// EOF
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/3d11a580/src/backend/gpopt/translate/CTranslatorDXLToScalar.cpp
----------------------------------------------------------------------
diff --git a/src/backend/gpopt/translate/CTranslatorDXLToScalar.cpp b/src/backend/gpopt/translate/CTranslatorDXLToScalar.cpp
index 838dd3c..7d0b0ce 100644
--- a/src/backend/gpopt/translate/CTranslatorDXLToScalar.cpp
+++ b/src/backend/gpopt/translate/CTranslatorDXLToScalar.cpp
@@ -42,6 +42,7 @@
#include "gpopt/base/COptCtxt.h"
#include "gpopt/translate/CTranslatorDXLToScalar.h"
#include "gpopt/translate/CTranslatorDXLToPlStmt.h"
+#include "gpopt/translate/CTranslatorDXLToQuery.h"
#include "gpopt/translate/CTranslatorUtils.h"
#include "gpopt/translate/CMappingColIdVarPlStmt.h"
@@ -124,6 +125,10 @@ CTranslatorDXLToScalar::PexprFromDXLNodeScalar
{EdxlopScalarCoerceToDomain, &CTranslatorDXLToScalar::PcoerceFromDXLNodeScCoerce},
{EdxlopScalarInitPlan, &CTranslatorDXLToScalar::PparamFromDXLNodeScInitPlan},
{EdxlopScalarSubPlan, &CTranslatorDXLToScalar::PsubplanFromDXLNodeScSubPlan},
+ {EdxlopScalarSubquery, &CTranslatorDXLToScalar::PsublinkFromDXLNodeScalarSubquery},
+ {EdxlopScalarSubqueryExists, &CTranslatorDXLToScalar::PsublinkFromDXLNodeSubqueryExists},
+ {EdxlopScalarSubqueryAny, &CTranslatorDXLToScalar::PexprFromDXLNodeSubqueryAnyAll},
+ {EdxlopScalarSubqueryAll, &CTranslatorDXLToScalar::PexprFromDXLNodeSubqueryAnyAll},
{EdxlopScalarArray, &CTranslatorDXLToScalar::PexprArray},
{EdxlopScalarArrayRef, &CTranslatorDXLToScalar::PexprArrayRef},
{EdxlopScalarDMLAction, &CTranslatorDXLToScalar::PexprDMLAction},
@@ -981,6 +986,213 @@ CTranslatorDXLToScalar::PparamFromMapping
return pparam;
}
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToScalar::PexprFromDXLNodeSubqueryAnyAll
+//
+// @doc:
+// Translates a DXL scalar ANY/ALL subquery into a GPDB Expr
+//
+//---------------------------------------------------------------------------
+Expr *
+CTranslatorDXLToScalar::PexprFromDXLNodeSubqueryAnyAll
+ (
+ const CDXLNode *pdxlnSubqueryAnyAll,
+ CMappingColIdVar *pmapcidvar
+ )
+{
+ GPOS_ASSERT(2 == pdxlnSubqueryAnyAll->UlArity());
+
+ // translate subquery into a sublink
+ return (Expr*) PsublinkFromDXLNodeQuantifiedSubquery(pdxlnSubqueryAnyAll, pmapcidvar);
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToScalar::PsublinkFromDXLNodeSubqueryExists
+//
+// @doc:
+// Translates a DXL scalar EXISTS subquery into a GPDB EXISTS sublink
+//
+//---------------------------------------------------------------------------
+Expr *
+CTranslatorDXLToScalar::PsublinkFromDXLNodeSubqueryExists
+ (
+ const CDXLNode *pdxlnSubqueryExists,
+ CMappingColIdVar *pmapcidvar
+ )
+{
+ GPOS_ASSERT(1 == pdxlnSubqueryExists->UlArity());
+ CDXLNode *pdxlnChild = (*pdxlnSubqueryExists)[0];
+
+ CTranslatorDXLToQuery trdxlquery(m_pmp, m_pmda, m_ulSegments);
+ CStateDXLToQuery *pstatedxltoquery = GPOS_NEW(m_pmp) CStateDXLToQuery(m_pmp);
+
+ // empty list of output columns
+ DrgPdxln *pdrgpdxlnOutputCols = GPOS_NEW(m_pmp) DrgPdxln(m_pmp);
+ CMappingColIdVarQuery *pmapcidvarquery = dynamic_cast<CMappingColIdVarQuery *>(pmapcidvar);
+ TEMap *ptemapCopy = CTranslatorUtils::PtemapCopy(m_pmp, pmapcidvarquery->Ptemap());
+
+ Query *pquery = trdxlquery.PqueryFromDXL
+ (
+ pdxlnChild,
+ pdrgpdxlnOutputCols,
+ pstatedxltoquery,
+ ptemapCopy,
+ pmapcidvarquery->UlQueryLevel() + 1
+ );
+
+ // clean up
+ pdrgpdxlnOutputCols->Release();
+ GPOS_DELETE(pstatedxltoquery);
+ CRefCount::SafeRelease(ptemapCopy);
+
+ SubLink *psublink = MakeNode(SubLink);
+ psublink->subLinkType = EXISTS_SUBLINK;
+ psublink->subselect = (Node*) pquery;
+ m_fHasSubqueries = true;
+
+ return (Expr *)psublink;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToScalar::PsublinkFromDXLNodeQuantifiedSubquery
+//
+// @doc:
+// Translates a DXL scalar ANY/ALL subquery into a GPDB ANY/ALL sublink
+//
+//---------------------------------------------------------------------------
+SubLink *
+CTranslatorDXLToScalar::PsublinkFromDXLNodeQuantifiedSubquery
+ (
+ const CDXLNode *pdxlnQuantifiedSubquery,
+ CMappingColIdVar *pmapcidvar
+ )
+{
+ GPOS_ASSERT(2 == pdxlnQuantifiedSubquery->UlArity());
+ GPOS_ASSERT((EdxlopScalarSubqueryAll == pdxlnQuantifiedSubquery->Pdxlop()->Edxlop())
+ || (EdxlopScalarSubqueryAny == pdxlnQuantifiedSubquery->Pdxlop()->Edxlop()));
+
+ ULONG ulColId = 0;
+ // create the test expression
+ OpExpr *popexpr = MakeNode(OpExpr);;
+ // create a subquery node
+ SubLink *psublink = MakeNode(SubLink);
+
+ CDXLScalarSubqueryQuantified *pdxlopQuantified =
+ CDXLScalarSubqueryQuantified::PdxlopConvert(pdxlnQuantifiedSubquery->Pdxlop());
+ ulColId = pdxlopQuantified->UlColId();
+ popexpr->opno = CMDIdGPDB::PmdidConvert(pdxlopQuantified->PmdidScalarOp())->OidObjectId();
+
+ if (EdxlopScalarSubqueryAll == pdxlnQuantifiedSubquery->Pdxlop()->Edxlop())
+ {
+ psublink->subLinkType = ALL_SUBLINK;
+ }
+ else
+ {
+ psublink->subLinkType = ANY_SUBLINK;
+ }
+
+ popexpr->opresulttype = CMDIdGPDB::PmdidConvert(m_pmda->PtMDType<IMDTypeBool>()->Pmdid())->OidObjectId();
+ popexpr->opretset = false;
+ psublink->testexpr = (Node*) popexpr;
+
+ GPOS_ASSERT(0 < ulColId);
+
+ CDXLNode *pdxlnOuter = (*pdxlnQuantifiedSubquery)[0];
+ CDXLNode *pdxlnInner = (*pdxlnQuantifiedSubquery)[1];
+
+ CTranslatorDXLToQuery trdxlquery(m_pmp, m_pmda, m_ulSegments);
+ CMappingColIdVarQuery *pmapcidvarquery = dynamic_cast<CMappingColIdVarQuery *>(pmapcidvar);
+
+ CStateDXLToQuery *pstatedxltoquery = GPOS_NEW(m_pmp) CStateDXLToQuery(m_pmp);
+
+ TEMap *ptemapCopy = CTranslatorUtils::PtemapCopy(m_pmp, pmapcidvarquery->Ptemap());
+
+ // translate inner side (with the output column referred to by the colid)
+ Query *pqueryInner = trdxlquery.PqueryFromDXLSubquery
+ (
+ pdxlnInner,
+ ulColId,
+ pstatedxltoquery,
+ ptemapCopy,
+ pmapcidvarquery->UlQueryLevel() + 1
+ );
+ psublink->subselect = (Node*) pqueryInner;
+
+ // translate the outer side
+ Expr *pexprOuter = PexprFromDXLNodeScalar(pdxlnOuter, pmapcidvar);
+ popexpr->args = gpdb::PlAppendElement(popexpr->args, pexprOuter);
+
+ Param *pparam = MakeNode(Param);
+ pparam->paramkind = PARAM_SUBLINK;
+ pparam->paramid = 1;
+
+ const CMappingElementColIdTE *pmappingelement = ptemapCopy->PtLookup(&ulColId);
+ if (NULL == pmappingelement)
+ {
+ GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXL2PlStmtAttributeNotFound, ulColId);
+ }
+ TargetEntry *pte = const_cast<TargetEntry *>(pmappingelement->Pte());
+
+ pparam->paramtype = gpdb::OidExprType((Node*) pte->expr);
+ popexpr->args = gpdb::PlAppendElement(popexpr->args, pparam);
+
+ m_fHasSubqueries = true;
+
+ // clean up
+ ptemapCopy->Release();
+ GPOS_DELETE(pstatedxltoquery);
+
+ return psublink;
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// CTranslatorDXLToScalar::PsublinkFromDXLNodeScalarSubquery
+//
+// @doc:
+// Translates a DXL scalar subquery into a GPDB scalar expression sublink
+//
+//---------------------------------------------------------------------------
+Expr *
+CTranslatorDXLToScalar::PsublinkFromDXLNodeScalarSubquery
+ (
+ const CDXLNode *pdxlnSubquery,
+ CMappingColIdVar *pmapcidvar
+ )
+{
+ GPOS_ASSERT(1 == pdxlnSubquery->UlArity());
+ ULONG ulColId = CDXLScalarSubquery::PdxlopConvert(pdxlnSubquery->Pdxlop())->UlColId();
+ CDXLNode *pdxlnChild = (*pdxlnSubquery)[0];
+
+ CTranslatorDXLToQuery trdxlquery(m_pmp, m_pmda, m_ulSegments);
+ CStateDXLToQuery *pstatedxltoquery = GPOS_NEW(m_pmp) CStateDXLToQuery(m_pmp);
+
+ CMappingColIdVarQuery *pmapcidvarquery = dynamic_cast<CMappingColIdVarQuery *>(pmapcidvar);
+ TEMap *ptemapCopy = CTranslatorUtils::PtemapCopy(m_pmp, pmapcidvarquery->Ptemap());
+
+ Query *pquery = trdxlquery.PqueryFromDXLSubquery
+ (
+ pdxlnChild,
+ ulColId,
+ pstatedxltoquery,
+ ptemapCopy,
+ pmapcidvarquery->UlQueryLevel() + 1
+ );
+
+ // clean up
+ CRefCount::SafeRelease(ptemapCopy);
+ GPOS_DELETE(pstatedxltoquery);
+
+ SubLink *psublink = MakeNode(SubLink);
+ psublink->subLinkType = EXPR_SUBLINK;
+ psublink->subselect = (Node*) pquery;
+ m_fHasSubqueries = true;
+
+ return (Expr *)psublink;
+}
//---------------------------------------------------------------------------
// @function:
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/3d11a580/src/backend/gpopt/translate/Makefile
----------------------------------------------------------------------
diff --git a/src/backend/gpopt/translate/Makefile b/src/backend/gpopt/translate/Makefile
index c3cf7ac..1bd2a48 100644
--- a/src/backend/gpopt/translate/Makefile
+++ b/src/backend/gpopt/translate/Makefile
@@ -31,6 +31,7 @@ OBJS = CMappingColIdVar.o \
CTranslatorDXLToScalar.o \
CTranslatorUtils.o \
CTranslatorRelcacheToDXL.o \
+ CTranslatorDXLToQuery.o \
CTranslatorQueryToDXL.o \
CTranslatorDXLToPlStmt.o \
CTranslatorPlStmtToDXL.o
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/3d11a580/src/backend/gpopt/utils/COptTasks.cpp
----------------------------------------------------------------------
diff --git a/src/backend/gpopt/utils/COptTasks.cpp b/src/backend/gpopt/utils/COptTasks.cpp
index e527f4e..4de4cdb 100644
--- a/src/backend/gpopt/utils/COptTasks.cpp
+++ b/src/backend/gpopt/utils/COptTasks.cpp
@@ -1388,6 +1388,66 @@ COptTasks::PvPlstmtFromDXLTask
return NULL;
}
+
+//---------------------------------------------------------------------------
+// @function:
+// COptTasks::PvQueryFromDXLTask
+//
+// @doc:
+// task that does the translation from xml to dxl to pquery
+//
+//---------------------------------------------------------------------------
+void*
+COptTasks::PvQueryFromDXLTask
+ (
+ void *pv
+ )
+{
+ GPOS_ASSERT(NULL != pv);
+
+ SOptContext *poctx = SOptContext::PoptctxtConvert(pv);
+
+ GPOS_ASSERT(NULL == poctx->m_pquery);
+ GPOS_ASSERT(NULL != poctx->m_szQueryDXL);
+
+ AUTO_MEM_POOL(amp);
+ IMemoryPool *pmp = amp.Pmp();
+
+ CWStringDynamic str(pmp);
+ COstreamString oss(&str);
+
+ // parse the DXL
+ CQueryToDXLResult *ptroutput = CDXLUtils::PdxlnParseDXLQuery(pmp, poctx->m_szQueryDXL, NULL);
+
+ GPOS_ASSERT(NULL != ptroutput->Pdxln());
+
+ // relcache MD provider
+ CMDProviderRelcache *pmdpr = GPOS_NEW(pmp) CMDProviderRelcache(pmp);
+
+ {
+ CAutoMDAccessor amda(pmp, pmdpr, sysidDefault);
+
+ // initialize hash table that maintains the mapping between ColId and Var
+ TEMap *ptemap = GPOS_NEW(pmp) TEMap(pmp);
+
+ CTranslatorDXLToQuery trdxlquery(pmp, amda.Pmda(), gpdb::UlSegmentCountGP());
+ CStateDXLToQuery statedxltoquery(pmp);
+
+ Query *pquery = trdxlquery.PqueryFromDXL(ptroutput->Pdxln(), ptroutput->PdrgpdxlnOutputCols(), &statedxltoquery, ptemap, GPDXL_QUERY_LEVEL);
+
+ CRefCount::SafeRelease(ptemap);
+ GPOS_DELETE(ptroutput);
+
+ GPOS_ASSERT(NULL != pquery);
+ GPOS_ASSERT(NULL != CurrentMemoryContext);
+
+ poctx->m_pquery = pquery;
+ }
+
+ return NULL;
+}
+
+
//---------------------------------------------------------------------------
// @function:
// COptTasks::PvDXLFromMDObjsTask
@@ -1762,6 +1822,33 @@ COptTasks::SzDXL
//---------------------------------------------------------------------------
// @function:
+// COptTasks::PqueryFromXML
+//
+// @doc:
+// deserializes query from DXL
+//
+//---------------------------------------------------------------------------
+Query *
+COptTasks::PqueryFromXML
+ (
+ char *szDXL
+ )
+{
+ Assert(NULL != szDXL);
+
+ SOptContext octx;
+ octx.m_szQueryDXL = szDXL;
+ Execute(&PvQueryFromDXLTask, &octx);
+
+ // clean up context
+ octx.Free(octx.epinQueryDXL, octx.epinQuery);
+
+ return (Query *) octx.m_pquery;
+}
+
+
+//---------------------------------------------------------------------------
+// @function:
// COptTasks::PplstmtFromXML
//
// @doc:
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/3d11a580/src/backend/gpopt/utils/funcs.cpp
----------------------------------------------------------------------
diff --git a/src/backend/gpopt/utils/funcs.cpp b/src/backend/gpopt/utils/funcs.cpp
index 06f73f0..c36a7e3 100644
--- a/src/backend/gpopt/utils/funcs.cpp
+++ b/src/backend/gpopt/utils/funcs.cpp
@@ -81,6 +81,8 @@ PG_FUNCTION_INFO_V1(RestoreQueryFromFile);
PG_FUNCTION_INFO_V1(DumpQueryDXL);
PG_FUNCTION_INFO_V1(DumpQueryToDXLFile);
PG_FUNCTION_INFO_V1(DumpQueryFromFileToDXLFile);
+PG_FUNCTION_INFO_V1(RestoreQueryDXL);
+PG_FUNCTION_INFO_V1(RestoreQueryFromDXLFile);
PG_FUNCTION_INFO_V1(DisableXform);
PG_FUNCTION_INFO_V1(EnableXform);
PG_FUNCTION_INFO_V1(LibraryVersion);
@@ -100,6 +102,7 @@ static char *getPlannedStmtBinary(char *szSqlText, size_t *piLength);
static int extractFrozenPlanAndExecute(char *pcSerializedPS);
static int extractFrozenQueryPlanAndExecute(char *pcQuery);
static int executeXMLPlan(char *szXml);
+static int executeXMLQuery(char *szXml);
static int translateQueryToFile(char *szSqlText, char *szFilename);
//---------------------------------------------------------------------------
@@ -499,6 +502,80 @@ DumpQueryFromFileToDXLFile(PG_FUNCTION_ARGS)
//---------------------------------------------------------------------------
// @function:
+// RestoreQueryDXL
+//
+// @doc:
+// Take an xml representation of a plan and execute it. Restores a query,
+// along with meta-data from a bytea, executes it and returns number of rows.
+// Input: bytea corresponding to serialized query
+// Output: number of rows corresponding to execution of plan.
+//
+//---------------------------------------------------------------------------
+
+extern "C" {
+Datum
+RestoreQueryDXL(PG_FUNCTION_ARGS)
+{
+ char *szXmlString = textToString(PG_GETARG_TEXT_P(0));
+
+ int iProcessed = executeXMLQuery(szXmlString);
+
+ StringInfoData str;
+ initStringInfo(&str);
+ appendStringInfo(&str, "processed %d rows", iProcessed);
+
+ text *ptResult = stringToText(str.data);
+
+ PG_RETURN_TEXT_P(ptResult);
+}
+}
+
+//---------------------------------------------------------------------------
+// @function:
+// RestoreQueryFromDXLFile
+//
+// @doc:
+// Restores a query specified in DXL format in an XML file, executes it
+// and returns number of rows.
+// Input: bytea corresponding to XML file name
+// Output: number of rows corresponding to execution of plan.
+//
+//---------------------------------------------------------------------------
+
+extern "C" {
+Datum
+RestoreQueryFromDXLFile(PG_FUNCTION_ARGS)
+{
+ char *szFilename = textToString(PG_GETARG_TEXT_P(0));
+
+ CFileReader fr;
+ fr.Open(szFilename);
+ ULLONG ullSize = fr.UllSize();
+
+ char *pcBuf = (char*) gpdb::GPDBAlloc(ullSize + 1);
+ fr.UlpRead((BYTE*)pcBuf, ullSize);
+ pcBuf[ullSize] = '\0';
+
+ fr.Close();
+
+ int iProcessed = executeXMLQuery(pcBuf);
+
+ elog(NOTICE, "Processed %d rows.", iProcessed);
+ gpdb::GPDBFree(pcBuf);
+
+ StringInfoData str;
+ initStringInfo(&str);
+
+ appendStringInfo(&str, "Query processed %d rows", iProcessed);
+ text *ptResult = stringToText(str.data);
+
+ PG_RETURN_TEXT_P(ptResult);
+}
+}
+
+
+//---------------------------------------------------------------------------
+// @function:
// EvalExprFromDXLFile
//
// @doc:
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/3d11a580/src/include/gpopt/translate/CTranslatorDXLToQuery.h
----------------------------------------------------------------------
diff --git a/src/include/gpopt/translate/CTranslatorDXLToQuery.h b/src/include/gpopt/translate/CTranslatorDXLToQuery.h
new file mode 100644
index 0000000..f160364
--- /dev/null
+++ b/src/include/gpopt/translate/CTranslatorDXLToQuery.h
@@ -0,0 +1,317 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+//---------------------------------------------------------------------------
+// @filename:
+// CTranslatorDXLToQuery.h
+//
+// @doc:
+// Class providing methods for translating from DXL tree to GPDB's Query.
+//
+// @test:
+//
+//
+//---------------------------------------------------------------------------
+
+#ifndef GPDXL_CTranslatorDXLToQuery_H
+#define GPDXL_CTranslatorDXLToQuery_H
+#define GPDXL_QUERY_LEVEL 0
+
+#include "gpopt/translate/CMappingColIdVarQuery.h"
+#include "gpopt/translate/CDXLTranslateContext.h"
+#include "gpopt/translate/CTranslatorDXLToScalar.h"
+#include "gpopt/translate/CDXLTranslateContextBaseTable.h"
+#include "gpopt/translate/CStateDXLToQuery.h"
+
+#include "gpos/base.h"
+
+#include "naucrates/dxl/CIdGenerator.h"
+#include "naucrates/dxl/operators/dxlops.h"
+
+// fwd declarations
+namespace gpopt
+{
+ class CMDAccessor;
+}
+
+struct JoinExpr;
+struct Node;
+struct Query;
+struct RangeTblEntry;
+struct RangeTblRef;
+struct TargetEntry;
+struct SortClause;
+
+namespace gpdxl
+{
+
+ using namespace gpopt;
+
+ // gpdb type
+ typedef SortClause GroupClause;
+
+ //---------------------------------------------------------------------------
+ // @class:
+ // CTranslatorDXLToQuery
+ //
+ // @doc:
+ // Class providing methods for translating from DXL tree to GPDB's Query.
+ //
+ //---------------------------------------------------------------------------
+ class CTranslatorDXLToQuery
+ {
+ // shorthand for functions for translating DXL nodes to GPDB expressions
+ typedef void (CTranslatorDXLToQuery::*PfPexpr)(const CDXLNode *pdxln, Query *pquery, CStateDXLToQuery *pstatedxltoquery, CMappingColIdVarQuery *pmapcidvarquery);
+
+ private:
+
+ // pair of DXL op id and translator function
+ struct STranslatorElem
+ {
+ Edxlopid eopid;
+ PfPexpr pf;
+ };
+
+ // memory pool
+ IMemoryPool *m_pmp;
+
+ // meta data accessor
+ CMDAccessor *m_pmda;
+
+ // counter for grouping and ordering columns
+ ULONG m_ulSortgrouprefCounter;
+
+ CTranslatorDXLToScalar *m_pdxlsctranslator;
+
+ // number of segments
+ ULONG m_ulSegments;
+
+ // private copy ctor
+ CTranslatorDXLToQuery(const CTranslatorDXLToQuery&);
+
+ void SetSubqueryOutput
+ (
+ ULONG ulColId, // output column id
+ Query *pquery, // the newly generated GPDB query object
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ void SetQueryOutput
+ (
+ const DrgPdxln *pdrgpdxlnQueryOutput, // list of output columns
+ Query *pquery, // the newly generated GPDB query object
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // translate DXL operator node into a Query node
+ void TranslateLogicalOp
+ (
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // translate a logical TVF operator
+ void TranslateTVF
+ (
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // translate a logical get operator
+ void TranslateGet
+ (
+ const CDXLNode *pdxl,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // translate a logical select operator
+ void TranslateSelect
+ (
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // translate a logical group by operator
+ void TranslateGroupBy
+ (
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // translate a logical group by columns
+ void TranslateGroupByColumns
+ (
+ const CDXLLogicalGroupBy *pdxlnlggrpby,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ void TranslateProject
+ (
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // translate a logical limit by operator
+ void TranslateLimit
+ (
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // translate a logical set operator
+ void TranslateSetOp
+ (
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // resjunk unused target list entry of the set op child
+ void MarkUnusedColumns
+ (
+ Query *pquery,
+ RangeTblRef *prtref,
+ CStateDXLToQuery *pstatedxltoquery,
+ const DrgPul *pdrgpulColids
+ );
+
+ // translate a logical join operator
+ void TranslateJoin
+ (
+ const CDXLNode *pdxl,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // create range table entry from a table descriptor
+ RangeTblEntry *PrteFromTblDescr
+ (
+ const CDXLTableDescr *,
+ Index,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // create range table reference for a logical get
+ RangeTblRef *PrtrefFromDXLLgGet
+ (
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // create range table reference for a logical TVF
+ RangeTblRef *PrtrefFromDXLLgTVF
+ (
+ const CDXLNode *pdxlnFnGet,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // create a range table reference for CDXLNode representing a derived table
+ RangeTblRef *PrtrefFromDXLLgOp
+ (
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // create join expr for a logical join node
+ JoinExpr *PjoinexprFromDXLLgJoin
+ (
+ const CDXLNode *pdxln,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // create a node from a child node of CDXLLogicalJoin
+ Node *PnodeFromDXLLgJoinChild
+ (
+ const CDXLNode *pdxlnChild,
+ Query *pquery,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery
+ );
+
+ // translate the project list CDXLNode
+ void TranslateProjList
+ (
+ const CDXLNode *pdxlnPrL,
+ CStateDXLToQuery *pstatedxltoquery,
+ CMappingColIdVarQuery *pmapcidvarquery,
+ ULONG ulTargetEntryIndex
+ );
+
+
+ public:
+ // ctor
+ CTranslatorDXLToQuery(IMemoryPool *pmp, CMDAccessor *pmda, ULONG ulSegments);
+
+ // dtor
+ ~CTranslatorDXLToQuery();
+
+ // main translation routine for DXL tree -> Query
+ Query *PqueryFromDXL
+ (
+ const CDXLNode *pdxln,
+ const DrgPdxln *pdrgpdxlnQueryOutput, // array of dxl nodes representing the list of output columns
+ CStateDXLToQuery *pstatedxltoquery,
+ TEMap *ptemap, // hash map storing the mapping of ColId->TE
+ ULONG ulQueryLevel // the level of the query being translated
+ );
+
+ // main translation routine for DXL tree -> Query
+ Query *PqueryFromDXLSubquery
+ (
+ const CDXLNode *pdxln,
+ ULONG ulColId, // output column id
+ CStateDXLToQuery *pstatedxltoquery,
+ TEMap *ptemap, // hash map storing the mapping of ColId->Var
+ ULONG ulQueryLevel // the level of the query being translated
+ );
+ };
+}
+
+#endif // !GPDXL_CTranslatorDXLToQuery_H
+
+// EOF
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/3d11a580/src/include/gpopt/translate/CTranslatorDXLToScalar.h
----------------------------------------------------------------------
diff --git a/src/include/gpopt/translate/CTranslatorDXLToScalar.h b/src/include/gpopt/translate/CTranslatorDXLToScalar.h
index 739e57c..01a73d4 100644
--- a/src/include/gpopt/translate/CTranslatorDXLToScalar.h
+++ b/src/include/gpopt/translate/CTranslatorDXLToScalar.h
@@ -263,6 +263,31 @@ namespace gpdxl
const CMappingElementColIdParamId *pmecolidparamid
);
+ Expr *PsublinkFromDXLNodeScalarSubquery
+ (
+ const CDXLNode *pdxlnSubquery,
+ CMappingColIdVar *pmapcidvar
+ );
+
+ SubLink *PsublinkFromDXLNodeQuantifiedSubquery
+ (
+ const CDXLNode *pdxlnQuantifiedSubquery,
+ CMappingColIdVar *pmapcidvar
+ );
+
+ Expr *PsublinkFromDXLNodeSubqueryExists
+ (
+ const CDXLNode *pdxlnSubqueryExists,
+ CMappingColIdVar *pmapcidvar
+ );
+
+ // translate a DXL scalar ANY/ALL subquery
+ Expr *PexprFromDXLNodeSubqueryAnyAll
+ (
+ const CDXLNode *pdxlnSubqueryAnyAll,
+ CMappingColIdVar *pmapcidvar
+ );
+
// translate a scalar coalesce
Expr *PcoalesceFromDXLNodeScCoalesce
(
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/3d11a580/src/include/gpopt/utils/COptTasks.h
----------------------------------------------------------------------
diff --git a/src/include/gpopt/utils/COptTasks.h b/src/include/gpopt/utils/COptTasks.h
index 7f9c73e..cad5e29 100644
--- a/src/include/gpopt/utils/COptTasks.h
+++ b/src/include/gpopt/utils/COptTasks.h
@@ -191,6 +191,10 @@ class COptTasks
static
void* PvDXLFromQueryTask(void *pv);
+ // task that does the translation from xml to dxl to pquery
+ static
+ void* PvQueryFromDXLTask(void *pv);
+
// dump relcache info for an object into DXL
static
void* PvDXLFromMDObjsTask(void *pv);