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 <[email protected]> Authored: Wed Jun 8 10:53:16 2016 +0800 Committer: ivan <[email protected]> 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);
