blob: f5bbd189c9fa20be78b9ad34b1ce89401f3a7981 [file] [log] [blame]
/*
* 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:
// CQueryMutators.h
//
// @doc:
// Class providing methods for translating a GPDB Query object into a
// DXL Tree
//
// @test:
//
//
//---------------------------------------------------------------------------
#ifndef GPDXL_CWalkerUtils_H
#define GPDXL_CWalkerUtils_H
#define GPDXL_QUERY_ID_START 0
#include "gpopt/translate/CMappingVarColId.h"
#include "gpopt/translate/CTranslatorScalarToDXL.h"
#include "gpopt/translate/CTranslatorUtils.h"
#include "gpos/base.h"
#include "naucrates/dxl/operators/CDXLNode.h"
#include "naucrates/md/IMDType.h"
#include "naucrates/md/IMDType.h"
// fwd declarations
namespace gpopt
{
class CMDAccessor;
}
struct Query;
struct RangeTblEntry;
struct GroupingClause;
struct SortClause;
typedef SortClause GroupClause;
struct Const;
struct List;
namespace gpdxl
{
//---------------------------------------------------------------------------
// @class:
// CQueryMutators
//
// @doc:
// Class providing methods for translating a GPDB Query object into a
// DXL Tree.
//
//---------------------------------------------------------------------------
class CQueryMutators
{
typedef Node *(*Pfnode) ();
typedef BOOL (*PfFallback) ();
typedef struct SContextHavingQualMutator
{
public:
// memory pool
IMemoryPool *m_pmp;
// MD accessor for function names
CMDAccessor *m_pmda;
// the counter for Query's total number of target entries
ULONG m_ulTECount;
// the target list of the new group by query
List *m_plTENewGroupByQuery;
// the current query level
ULONG m_ulCurrLevelsUp;
// indicate whether we are mutating the argument of an aggregate
BOOL m_fAggregateArg;
// indicate the levels up of the aggregate we are mutating
ULONG m_ulAggregateLevelUp;
// fall back to the planner by raising an expression since we encountered an
// expression / attribute that we could not resolve
BOOL m_fFallbackToPlanner;
// ctor
SContextHavingQualMutator
(
IMemoryPool *pmp,
CMDAccessor *pmda,
ULONG ulTECount,
List *plTENewGroupByQuery
)
:
m_pmp(pmp),
m_pmda(pmda),
m_ulTECount(ulTECount),
m_plTENewGroupByQuery(plTENewGroupByQuery),
m_ulCurrLevelsUp(0),
m_fAggregateArg(false),
m_ulAggregateLevelUp(ULONG_MAX),
m_fFallbackToPlanner(false)
{
GPOS_ASSERT(NULL != plTENewGroupByQuery);
}
// dtor
~SContextHavingQualMutator()
{}
} CContextHavingQualMutator;
typedef struct SContextGrpbyPlMutator
{
public:
// memory pool
IMemoryPool *m_pmp;
// MD accessor to get the function name
CMDAccessor *m_pmda;
// original query
Query *m_pquery;
// the new target list of the group by query
List *m_plTENewGroupByQuery;
// the current query level
ULONG m_ulCurrLevelsUp;
// the sorting / grouping reference of the original target list entry
ULONG m_ulRessortgroupref;
// indicate whether we are mutating the argument of an aggregate
BOOL m_fAggregateArg;
// ctor
SContextGrpbyPlMutator
(
IMemoryPool *pmp,
CMDAccessor *pmda,
Query *pquery,
List *plTENewGroupByQuery
)
:
m_pmp(pmp),
m_pmda(pmda),
m_pquery(pquery),
m_plTENewGroupByQuery(plTENewGroupByQuery),
m_ulCurrLevelsUp(0),
m_ulRessortgroupref(0),
m_fAggregateArg(false)
{
}
// dtor
~SContextGrpbyPlMutator()
{}
} CContextGrpbyPlMutator;
typedef struct SContextIncLevelsupMutator
{
public:
// the current query level
ULONG m_ulCurrLevelsUp;
// fix target list entry of the top level
BOOL m_fFixTargetListTopLevel;
// ctor
SContextIncLevelsupMutator
(
ULONG ulCurrLevelsUp,
BOOL fFixTargetListTopLevel
)
:
m_ulCurrLevelsUp(ulCurrLevelsUp),
m_fFixTargetListTopLevel(fFixTargetListTopLevel)
{
}
// dtor
~SContextIncLevelsupMutator()
{}
} CContextIncLevelsupMutator;
// context for walker that iterates over the expression in the target entry
typedef struct SContextTLWalker
{
public:
// list of target list entries in the query
List *m_plTE;
// list of grouping clauses
List *m_groupClause;
// ctor
SContextTLWalker
(
List *plTE,
List *groupClause
)
:
m_plTE(plTE),
m_groupClause(groupClause)
{
}
// dtor
~SContextTLWalker()
{}
} CContextTLWalker;
private:
// check if the cte levels up needs to be corrected
static
BOOL FNeedsLevelsUpCorrection(SContextIncLevelsupMutator *pctxinclvlmutator, Index idxCtelevelsup);
public:
// fall back during since the target list refers to a attribute which algebrizer at this point cannot resolve
static
BOOL FNeedsToFallback(Node *pnode, void *pctx);
// check if the project list contains expressions on aggregates thereby needing normalization
static
BOOL FNeedsPrLNormalization(const Query *pquery);
// normalize query
static
Query *PqueryNormalize(IMemoryPool *pmp, CMDAccessor *pmda, const Query *pquery, ULONG ulQueryLevel);
// check if the project list contains expressions on window operators thereby needing normalization
static
BOOL FNeedsWindowPrLNormalization(const Query *pquery);
// flatten expressions in window operation project list
static
Query *PqueryNormalizeWindowPrL(IMemoryPool *pmp, CMDAccessor *pmda, const Query *pquery);
// traverse the project list to extract all window functions in an arbitrarily complex project element
static
Node *PnodeWindowPrLMutator(Node *pnode, void *ctx);
// flatten expressions in project list
static
Query *PqueryNormalizeGrpByPrL(IMemoryPool *pmp, CMDAccessor *pmda, const Query *pquery);
// make a copy of the aggref (minus the arguments)
static
Aggref *PaggrefFlatCopy(Aggref *paggrefOld);
// create a new entry in the derived table and return its corresponding var
static
Var *PvarInsertIntoDerivedTable(Node *pnode, SContextHavingQualMutator *context);
// check if a matching node exists in the list of target entries
static
Node *PnodeFind(Node *pnode, SContextHavingQualMutator *pctx);
// increment the levels up of outer references
static
Var *PvarOuterReferenceIncrLevelsUp(Var *pvar);
// pull up having clause into a select
static
Query *PqueryNormalizeHaving(IMemoryPool *pmp, CMDAccessor *pmda, const Query *pquery);
// traverse the expression and fix the levels up of any outer reference
static
Node *PnodeIncrementLevelsupMutator(Node *pnode, void *ctx);
// traverse the expression and fix the levels up of any CTE
static
Node *PnodeFixCTELevelsupMutator(Node *pnode, void *ctx);
// traverse the project list of a groupby operator, to
// extract all aggregate functions in an arbitrarily complex project element,
static
Node *PnodeGrpbyPrLMutator(Node *pnode, void *ctx);
// mutate the grouping columns, fix levels up when necessary
static
Node *PnodeGrpColMutator(Node *pnode, void *pctx);
// fix the level up of grouping columns when necessary
static
Node *PnodeFixGrpCol(Node *pnode, TargetEntry *pteOriginal, SContextGrpbyPlMutator *pctxGrpByMutator);
// return a target entry for the aggregate or percentile expression
static
TargetEntry *PteAggregateOrPercentileExpr(IMemoryPool *pmp, CMDAccessor *pmda, Node *pnode, ULONG ulAttno);
// traverse the having qual to extract all aggregate functions,
// fix correlated vars and return the modified having qual
static
Node *PnodeHavingQualMutator(Node *pnode, void *ctx);
// for a given an TE in the derived table, create a new TE to be added to the top level query
static
TargetEntry *Pte(TargetEntry *pte, ULONG ulVarAttno);
// return the column name of the target entry
static
CHAR* SzTEName(TargetEntry *pte, Query *pquery);
// make the input query into a derived table and return a new root query
static
Query *PqueryConvertToDerivedTable(const Query *pquery, BOOL fFixTargetList, BOOL fFixHavingQual);
// eliminate distinct clause
static
Query *PqueryEliminateDistinctClause(const Query *pquery);
// reassign the sorting clause from the derived table to the new top-level query
static
void ReassignSortClause(Query *pqueryNew, Query *pqueryDrdTbl);
// fix window frame edge boundary when its value is defined by a subquery
static
Query *PqueryFixWindowFrameEdgeBoundary(const Query *pquery);
};
}
#endif // GPDXL_CWalkerUtils_H
//EOF