blob: 3efbb967e1c341d8fe46ac598d76f7b963bc9b13 [file] [log] [blame]
/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// 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.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
#ifndef QUERYDESCRIPTOR_H
#define QUERYDESCRIPTOR_H
/* -*-C++-*-
**************************************************************************
*
* File: QRDescGenerator.h
* Description: MV analyzer class and methods
* Created: 01/24/2008
* Language: C++
*
**************************************************************************
*/
#include "Analyzer.h"
#include "OptRange.h"
#include "XMLUtil.h"
#include "QRDescriptor.h"
#include "QRLogger.h"
#include "QRMessage.h"
/**
* \file
* Contains the class definition for the class used to generate a query
* descriptor from Analyzer structures.
*/
// Classes defined in this file.
class QRDescGenerator;
class EqualitySet;
class SetRefVisitor;
// Other forward declarations.
class OptRangeSpec;
ULng32 hashString(const NAString& str);
ULng32 hashValueId(const QRValueId& vid);
#ifdef _MEMSHAREDPTR
typedef QRIntrusiveSharedPtr<SetRefVisitor> SetRefVisitorPtr;
#else
typedef SetRefVisitor* SetRefVisitorPtr;
#endif
class SetRefVisitor : public Visitor
{
public:
SetRefVisitor(const QRElementHash& idHash,
ADD_MEMCHECK_ARGS_DECL(CollHeap* heap))
: Visitor(ADD_MEMCHECK_ARGS_PASS(heap)),
idHash_(idHash)
{}
virtual Visitor::VisitResult visit(QRElementPtr caller);
private:
const QRElementHash& idHash_;
}; // class SetRefVisitor
ULng32 hashQRValueId(const QRValueId& vid);
/**
* Class that implements the interface specified by the Visitor abstract class
* and is used to traverse the tree structure of a partial descriptor to see
* if that partial descriptor contains something that will generate XML that
* may not be parseable. For example: string literals containing the '%' and
* '&' characters.
*/
class XmlValidatorVisitor : public Visitor
{
public:
XmlValidatorVisitor(ADD_MEMCHECK_ARGS_DECL(CollHeap* heap))
: Visitor(ADD_MEMCHECK_ARGS_PASS(heap)),
foundProblem_(FALSE)
{}
virtual VisitResult visit(QRElementPtr caller);
NABoolean foundProblem() const
{
return foundProblem_;
}
private:
NABoolean foundProblem_;
}; // class XmlValidatorVisitor
#ifdef _MEMSHAREDPTR
typedef QRIntrusiveSharedPtr<XmlValidatorVisitor> XmlValidatorVisitorPtr;
#else
typedef XmlValidatorVisitor* XmlValidatorVisitorPtr;
#endif
/**
* Class representing an equality set, a group of columns, expressions, and
* values that are known to be equal due to equality predicates appearing in
* the query. This is similar to a VEG, but is more inclusive in that it can
* contain expressions, and exploits transitivity more fully than VEGs where
* dynamic parameters are involved.
* \n\n
* An EqualitySet can yield a JoinPred element consisting of one column/expression
* from each of two or more tables. The remaining members of the EqualitySet
* are linked to the JoinPred through either range or residual predicates.
* \n\n
* This class may be treated as a list, since it subclasses a specialization of
* the NAList template class. The list members are the item expressions that
* comprise the equality set.
*/
class EqualitySet : public NAList<ItemExpr*>
{
public:
/**
* Instantiates an initially empty equality set.
* @param heap Heap to use with the underlying list.
*/
EqualitySet(CollHeap* heap)
: NAList<ItemExpr*>(heap),
heap_(heap),
joinPredId_(NULL_VALUE_ID),
type_(NULL)
{
delete type_;
}
virtual ~EqualitySet()
{}
/**
* Returns the id of the \c JoinPred associated with this EqualitySet.
* @return The \c JoinPred id, or 0 if there is none.
*/
UInt32 getJoinPredId() const
{
return joinPredId_;
}
/**
* Sets the id of the \c JoinPred associated with this EqualitySet. This is used
* to reference the \c JoinPred in range or residual predicates that are members
* of the equality set, but outside the JoinPred.
* @param id The \c JoinPred id.
*/
void setJoinPredId(UInt32 id)
{
joinPredId_ = id;
}
/**
* Returns the type of the equality set. For numeric types, this is the most
* restrictive type common to all members of the equality set. For example,
* if there are two members of the equality set with types smallint unsigned
* and numeric(4,2), the type of the equality set as a whole would be
* numeric(4,2) unsigned.
*
* @return The type of the equality set.
*/
const NAType* getType()
{
if (!type_)
determineType();
return type_;
}
private:
/**
* Sets the type for the equality set according to the rules outlined in
* getType().
*/
void determineType();
UInt32 joinPredId_;
NAType* type_;
CollHeap* heap_;
}; // EqualitySet
/**
* Class that performs MV Analysis of a query expression.
* It uses the QueryAnalysis object (performed on the
* query expression) for its processing.
*/
class QRDescGenerator : public NABasicObject
{
friend class OptRangeSpec;
public:
QRDescGenerator(NABoolean bFormatted, CollHeap* heap)
: mvqrHeap_(heap),
bFormatted_(bFormatted),
bSortJoinPredicateCols_(TRUE),
bGenColumnRefs_(TRUE),
generatedJBBid_(GENERATED_JBBID_START),
putAllJBBsInQD_(CmpCommon::getDefault(MVQR_ALL_JBBS_IN_QD) == DF_ON),
descriptorType_(ET_INVALID),
relExpr_(NULL),
currentJBB_(NULL),
rangeColHash_(hashValueId, 77, TRUE, heap),
rangeExprHash_(hashString, 77, TRUE, heap),
vegsUsedHash_(hashValueId, 77, TRUE, heap),
exprsUsedHash_(hashString, 77, TRUE, heap),
colTblIdHash_(hashString, 77, TRUE, heap),
isDumpMvMode_(FALSE),
allEqualitySets_(heap)
{
maxExprSize_ = CmpCommon::getDefaultLong(MVQR_MAX_EXPR_SIZE);
maxExprDepth_ = CmpCommon::getDefaultLong(MVQR_MAX_EXPR_DEPTH);
}
virtual ~QRDescGenerator();
static NABoolean typeSupported(const NAType* type);
/**
* Checks to see if at least one of the MVs in the list is enabled for
* query rewrite.
*
* @param tableDesc Table descriptor containing the list of MVs.
* @return \c TRUE iff at least one MV in the list is rewrite-enabled.
*/
static NABoolean hasRewriteEnabledMVs(TableDesc* tableDesc);
/**
* Determines whether or not the passed JBB should be included in the query
* descriptor. The criteria are that two or more of the tables in the JBB
* must have MVs defined on them, or one table with MVs defined on it and a
* Group By node. When constructing an MV descriptor, all JBBs are included
* without regard to these criteria.
*
* @param jbb The JBB to screen.
* @return \c TRUE iff the JBB should be included in the descriptor and be
* eligible for rewrite.
*/
NABoolean qrNeededForJBB(JBB* jbb);
/**
* Determines whether or not an isolated Scan node should be included in the
* query descriptor as a pseudo-JBB. The table referenced by the Scan must be
* used in at least 1 MV, and the Scan must have a Group By node immediately
* above it. When constructing an MV descriptor, all JBBs are included without
* regard to these criteria. The need for this function is temporary, until
* single-node JBBs are provided by the Analyzer. Currently, a single Scan
* node is not treated as a JBB.
*
* @param parent The parent of the Scan node. This must be a Group By if a
* JBB element is to be added to the query descriptor for the
* Scan node.
* @param scanExpr The Scan node to evaluate.
* @return \c TRUE iff the Scan node is to be included in the descriptor as a
* JBB element, and thus eligible for rewrite.
*/
NABoolean qrNeededForTable(RelExpr* parent, RelExpr* scanExpr);
/**
* Used to specify the MV Table Name. Needs to be called if
* an MV Descriptor is to be generated.
*
* @param MVTableName
*/
void setMVTableName(NAString& MVTableName)
{
mMVTableName_ = MVTableName;
}
const NAString& getMVTableName() const
{
return mMVTableName_;
}
/**
* Whether the columns in a join predicate should be sorted
* (by column name).
*/
void setSortJoinPredicateCols(NABoolean bWhat=TRUE)
{
bSortJoinPredicateCols_ = bWhat;
}
NABoolean getSortJoinPredicateCols() const
{
return bSortJoinPredicateCols_;
}
/**
* Whether column refs should be generated (for the same column id)
*/
void setGenColumnRefs(NABoolean bWhat = FALSE)
{
bGenColumnRefs_ = bWhat;
}
NABoolean getGenColumnRefs() const
{
return bGenColumnRefs_;
}
/**
* Generates a unique id value for a "pseudo-JBB". The only such case is
* currently the sole table in a query or subquery where there is no join.
* The Analyzer will soon create JBBs for these singletons, and our special
* treatment will no longer be necessary.
*
* @return A generated id for a JBB.
*/
UInt32 genJBBid()
{
return generatedJBBid_--;
}
/**
* Returns the equality set that the passed \c ValueId is part of, or
* \c NULL if it is not contained in an equality set.
*
* @param vidPtr Pointer to the ValueId.
* @return Pointer to the equality set found, if any.
*/
EqualitySet* getEqualitySet(QRValueId* vidPtr)
{
return vegsUsedHash_.getFirstValue(vidPtr);
}
/**
* Returns the equality set containing the passed expression, or \c NULL if
* no such equality set exists. The expression is represented by its
* normalized text.
*
* @param strPtr Pointer to the text of the expression.
* @return Pointer to the equality set found, if any.
*/
EqualitySet* getEqualitySet(NAString* strPtr)
{
return exprsUsedHash_.getFirstValue(strPtr);
}
/**
* Populate the passed descriptor with the JBBs from the underlying query or
* materialized view.
*
* @param descPtr Pointer to the query or MV descriptor.
* @param qa The QueryAnalysis for the query to get a descriptor for.
* @return \c TRUE if one or more JBBs were found, \c FALSE otherwise (in
* which case the descriptor will not be generated.
*/
NABoolean processJBBs(QRDescriptorPtr descPtr,
QueryAnalysis* qa);
/**
* Logs the list of columns for which the corresponding bit is set in the
* passed bitmap.
*
* @param table The table owning the columns covered by the bitmap.
* @param bitmap The bitmap.
* @param predType Indicator of whether the bitmap shows the columns having
* a range predicate, or those having a residual predicate.
* This is incorporated into the message displayed in the log.
*/
void logColumnBitmap(QRTablePtr table,
const XMLBitmap& bitmap,
ElementType predType);
/**
* Derives and returns a query descriptor from a QueryAnalysis object.
*
* @param qa The QueryAnalysis for the query to get a descriptor for.
* @param expr Root of the query tree. This is used to look for singleton
* scan nodes that are not part of a join, and create JBBs
* for them.
* @return The query's descriptor, or NULL if the query has no JBBs.
*/
QRQueryDescriptorPtr createQueryDescriptor(QueryAnalysis* qa, RelExpr* expr);
/**
* Creates a materialized view descriptor from a QueryAnalysis object.
*
* @param qa The QueryAnalysis for the query used in the MV.
* @param expr Root of the query tree. This is used to look for singleton
* scan nodes that are not part of a join, and create JBBs
* for them.
* @return The MV descriptor.
*/
QRMVDescriptorPtr createMvDescriptor(QueryAnalysis* qa, RelExpr* expr);
/**
* Tells whether this is an MV descriptor or a query descriptor.
* @return Element type enumeration value corresponding to the descriptor type.
*/
ElementType getDescriptorType() const
{
return descriptorType_;
}
/**
* Serializes a descriptor object to XML form.
* @param desc The descriptor.
* @return The XML text for the descriptor.
*/
XMLString* createXmlText(QRElementPtr desc);
/**
* Sets the bit corresponding to the passed column value id in either the
* table's range or residual predicate bit map.
*
* @param colVid Value id of the column to set the bit for.
* @param elemType Indicates whether the range or residual bitmap should
* be used.
*/
void setPredBitmap(QRValueId colVid, ElementType elemType);
/**
* Saves information on a range specification for later use. A RangeInfo
* object, which associates a range specification with its owning range
* predicate list, is looked for in one of the range hash tables. If found,
* the range specification is merged with the one in that %RangeInfo. If not,
* a new %RangeInfo is created with the passed range spec and added to the
* appropriate hash table.
*
* @param range The range specification to save. If its content is merged into
* an existing one for the same column or expression, it is deleted.
* @param jbbElem Ptr to the JBB element owning the range predicate list the
* range belongs to.
*/
void storeRangeInfo(OptRangeSpec* range, QRJBBPtr jbbElem);
const QRElementHash& getColTblIdHash() const
{
return colTblIdHash_;
}
QRElementPtr getElementForValueID(ValueId& id) const;
const NAList<EqualitySet*>& getAllEqualitySets() const
{
return allEqualitySets_;
}
/**
* Adds information from data structures of another QRDescGenerator into this
* one. Rangespec processing in the Normalizer uses a separate generator before
* we get to query rewrite, and some columns have already been assigned ids,
* entered in the hash table, etc. Those must be incorporated into the descriptor
* generator we use in mvqr processing. Only certain data structures are affected:
* the used columns lists for regular and extra-hub tables, and the hash table of
* column and table ids. I tried creating the generator where it could be passed
* to both places so a single one could be used, but there were cases where this
* could not be done.
*
* @param other The descriptor generator providing the data to merge into this
* one, typically from Normalizer.
*/
void mergeDescGenerator(const QRDescGenerator* other);
/**
* Creates the equality sets implied by any vegpreds or equality predicates
* in \c preds. Hash tables are also created that map value ids of columns
* or expressions to the equality set they participate in. These structures
* allow the Normalizer to use the correct vegref ValueId instead of a
* base column vid when creating rangespec operators (Bug 2707). This function
* is only called by the Normalizer; for MVQR, the private function
* formEqualitySets() is called directly during its processing of predicates.
*
* @param preds The set of predicate ValueIds to create equality sets from.
* This is passed by value so the copy ctor will be invoked and
* protect the argument from the destructive effects of
* formEqualitySets(), which removes any vegpreds or equality
* preds from the list.
*/
void createEqualitySets(ValueIdSet preds)
{
NAList<EqualitySet*> equalitySets(mvqrHeap_);
formEqualitySets(preds, equalitySets);
}
NABoolean isDumpMvMode()
{
return isDumpMvMode_;
}
void setDumpMvMode()
{
isDumpMvMode_ = TRUE;
}
/**
* Tells whether the passed value id is that of a joinpred.
* @param vid The value id to look up.
* @return True iff the vid is a joinpred id.
*/
NABoolean isJoinPredId(ValueId vid)
{
return colToJoinPredMap_.getTopValues().contains(vid);
}
private:
/**
* Adds a JoinPred element to a JBB element of a descriptor. The elements
* passed in the array are examined to see if they belong to the hub or
* extrahub, and placed in the appropriate JoinPred.
*
* @param jbbElem The JBB element to add the JoinPred to.
* @param qrElemArray Sorted array of elements comprising the JoinPred.
* @param idArray Array of ids corresponding to the elements.
* @param eqCount Number of elements in the JoinPred.
* @param [out] hubJoinPredId The id of the JoinPred element for the hub.
*/
void addJoinPred(QRJBBPtr jbbElem, QRElementPtr* qrElemArray,
Int32* idArray, Int32 eqCount, UInt32& hubJoinPredId);
/**
* Returns the node id of the passed item expression, or \c NULL_CA_ID if no
* single node contains the entire expression.
*
* @param itemExpr Item expression to check.
* @return The CA node id for the expression, or \c NULL_CA_ID if it is a
* multi-node expression.
*/
CANodeId getExprNode(ItemExpr* itemExpr);
/**
* Goes through the members of an equality set, identifying the JoinPred
* items, and creating range or residual predicates for the remaining members
* that reference the JoinPred.
*
* @param jbbElem JBB element the equality set is part of.
* @param eqSet The equality set.
*/
void processEqualitySet(QRJBBPtr jbbElem, EqualitySet& eqSet);
VEGPredicate* getVegPredicate(UInt32 hubJoinPredId);
/**
* Adds a range predicate expressing equality of #rangeItemExpr to the
* constant #constItem. This is used when there is a constant included in an
* equality set, as well as another member that is not a join pred operand.
*
* @param rangeItemExpr The non-joinpred member of the equality set that is
* to be equated to the constant.
* @param type Type associated with the equality set.
* @param jbbElem JBB element the equality set is part of.
* @param constItem The constant the range item is equated to.
* @see #processEqualitySet
*/
void addEqualityRangePred(ItemExpr* rangeItemExpr,
const NAType* type,
QRJBBPtr jbbElem,
ConstValue* constItem);
/**
* Adds a range predicate expressing equality of a JoinPred to a constant.
* This is used when there is a constant included in an equality set, and two
* or more of the other equality set members form an equijoin predicate.
*
* @param hubJoinPredId Id of the hub JoinPred.
* @param type Type associated with the equality set.
* @param jbbElem JBB element the equality set is part of.
* @param constItem The constant the range item is equated to.
* @see #processEqualitySet
*/
void addEqualityRangePred(UInt32 hubJoinPredId,
const NAType* type,
QRJBBPtr jbbElem,
ConstValue* constItem);
/**
* Adds a residual predicate to a JBB element for an equality condition.
* This function is called to create a predicate for an equality relationship
* between between JoinPred and a non-JoinPred member of the same equality
* set, or one of a chain of equality conditions linking all members of an
* equality set if the set does not contain a JoinPred (which happens when
* only a single table is involved).
*
* @param jbbElem JBB element the residual predicate will belong to.
* @param op1 Left-hand side of the equality predicate.
* @param op2 Right-hand side of the equality predicate, or NULL if a join
* pred is referenced.
* @param hubJoinPredId Id of the join pred that op1 shares equality with,
* if such a join pred exists.
* @see #processEqualitySet
*/
void addEqualityResidPred(QRJBBPtr jbbElem,
ItemExpr* op1,
ItemExpr* op2,
ValueId hubJoinPredId = NULL_VALUE_ID);
/**
* Adds the source equality set to the destination, and removes the source.
* This is necessary when two equality sets exist and an equality condition
* is encountered between a member of one and a member of the other. This also
* requires changing the hash tables that have equality sets as the values,
* for any entry with the source as the value.
*
* @param source Equality set to add to the other one.
* @param destination Equality set to add to.
* @param equalitySets The list of all equality sets, needed so the source
* equality set can be removed.
*/
void combineEqSets(EqualitySet* source,
EqualitySet* destination,
NAList<EqualitySet*>& equalitySets);
/**
* Adds the members of #vegVals into the equality set #eqSet, creating that
* equality set if it is \c NULL. The appropriate hash tables are also
* updated.
*
* @param vegPred VEG predicate members are derived from. \c NULL if called
* for an equality pred instead of a vegpred.
* @param vegVid ValueId of a VEG being added.
* @param vegVals Set of ValueIds to add. These are often the base columns of
* the Veg referred to by #vegVid, but are passed as a
* \ValueIdSet, because some may have been removed for various
* reasons.
* @param eqSet Equality set to add to. This may be null, in which case a new
* one is allocated.
* @param equalitySets The list of all equality sets. If a new equality set
* must be allocated, add it to this list.
*/
void putVegMembersInEqualitySet(
ItemExpr* vegPred,
const ValueId& vegVid,
const ValueIdSet& vegVals,
EqualitySet*& eqSet,
NAList<EqualitySet*>& equalitySets);
/**
* Adds the members of a VEGPredicate to an equality set. Some of the members
* may already belong to different equality sets. For instance, if the preds
* a=b+1 and c=d+1 have been processed, the sets {a, b+1} and {c, d+1} will
* be present (expressions are not part of VEGs). When the VEGPredicate
* consisting of a and b is processed, the two existing equality sets will
* be merged. If only a=b+1 has been seen, then the VEGPredicate members
* (other than a) will be added to {a, b+1}. If no member of the veg pred is
* already a member of an existing equality set, a new one is created.
*
* @param vegPred The VegPredicate whose members will be added to an equality
* set.
* @param equalitySets List of equality sets, in case a new one is created and
* must be added to it.
*/
void addVegPredToEqualitySets(
VEGPredicate* vegPred,
NAList<EqualitySet*>& equalitySets);
/**
* Adds the operands of an equality predicate to an equality set. If the
* operands are members of two different equality sets, the sets are combined.
* If only one is a member, the other is added. If neither is a member, a new
* equality set is created and they are added to it.
*
* @param pred The equality predicate (item expression tree rooted by an
* equals operator.
* @param [out] equalitySets The list of equality sets, in case a new one needs
* to be created and added to it.
*/
void addEqPredToEqualitySets(
ItemExpr* pred,
NAList<EqualitySet*>& equalitySets);
/**
* Create equality sets from the VEGPredicates and other equality conditions
* in the query. Although a VEG is conceptually the same thing as the equality
* set we use, they do not correspond exactly, and our processing here may
* combine two or more VEGs into a single equality set, as well as adding
* expressions that are equivalent to the members of a VEG.
*
* @param [out] preds List of predicates, from which the VEGPredicates and
* equality conditions will be removed and analyzed to
* produce the equality sets.
* @param [out] equalitySets The list of equality sets produced by the function.
*/
void formEqualitySets(ValueIdSet& preds,
NAList<EqualitySet*>& equalitySets);
/**
* Obtains the set of predicates from the query that reference children of
* #jbbElem, and creates join, range, and residual predicates from them for
* the descriptor.
*
* @param nodeSet Set of CA nodes corresponding the the JBBCs of \c jbbElem.
* @param gbNode Group By node for the JBB (null if there isn't one), needed to
* find predicates on GB node that aren't pushed down (count(*)).
* @param jbbElem The JBB being processed.
*/
void processReferencingPreds(CANodeIdSet* nodeSet,
RelExpr* gbNode,
QRJBBPtr jbbElem);
/**
* Deletes the equality sets in the passed list, and clears the hash tables
* that reference EqualitySet as a value. The dynamically allocated keys and
* values are also deleted.
*
* @param equalitySets List of equality sets that have served their purpose.
*/
void discardEqualitySets(NAList<EqualitySet*>& equalitySets);
/**
* Traverses the query tree looking for table scan nodes that are not part of
* a join, so that a JBB element can be created for them. The Analyzer does
* not currently treat these isolated nodes as JBBs, so we have to find them.
*
* @param desc The query descriptor we are creating.
* @param expr RelExpr node that is the root of the query tree.
*/
void getSingleTableJBBs(QRDescriptorPtr desc, RelExpr* expr);
/**
* Gets information about a column, including the node ID of the table that
* owns it.
*
* @param vid ValueId of a veg reference or base column.
* @param [out] nodeID Id of the owning node, or \c NULL_CA_ID if #vid is not
* the id of a veg ref or base column.
* @param [out] cvid ValueId of the column. This will be the same as #vid if
* vid is for a base column.
* @param [out] vegrefVid ValueId of the vegref the column belongs to, or
* \c NULL_VALUE_ID if none. This will be the same as
* #vid if vid is for a vegref.
* @param [out] baseColName Name of the base column.
* @param [out] isExtraHub \c TRUE if the node is an extra-hub node.
* @param [out] colIndex The ordinal number of the column in the base table.
* @return \c TRUE if a node id was determined, \c FALSE otherwise.
*/
NABoolean getTableId(ValueId vid,
CANodeId& nodeID,
ValueId& cvid,
ValueId& vegrefVid,
NAString& baseColName,
NABoolean& isExtraHub,
Int32& colIndex);
/**
* Returns the node id for the table that owns the referenced column.
*
* @param vid ValueId of a veg reference or base column.
* @return The node id of the owning table, or \c NULL_CA_ID if #vid is not
* the id of a veg ref or base column.
*/
CANodeId getNodeId(ValueId vid);
/**
* Creates an oject representing a column element in the descriptor.
*
* @param vid ValueId of the veg ref or base column.
* @param joinPredId If nonzero, the column element should be a reference to
* the existing JoinPred element with this id.
* @param markAsUsed If TRUE, add the column's value id to the list of those
* used in the descriptor, so subsequent uses will cause a
* reference to the original to be used.
* @return Pointer to the create column element.
*/
QRColumnPtr genQRColumn(ValueId vid,
UInt32 joinPredId = 0,
NABoolean markAsUsed = TRUE);
/**
* Creates a hierarchy of descriptor objects corresponding to the passed
* item expression.
*
* @param itemExpr Root of the item expression tree to create descriptor
* objects for.
* @return Root of the hierarchy of created descriptor objects.
*/
QRExplicitExprPtr getExprTree(ItemExpr* itemExpr);
/**
* Creates a descriptor object corresponding to the passed item expression.
* This method is used for both output expressions and residual predicates.
*
* @param pExpr The item expression from which to derive the descriptor object.
* @param isResidual Is this a residual predicate or an output expression?
* @param joinPredId If nonzero, the expression element will be a reference to
* the existing JoinPred element with this id.
* @return The created expression descriptor object.
*/
QRExprPtr genQRExpr(ItemExpr* pExpr,
NABoolean isResidual,
UInt32 joinPredId = 0);
/**
* Is this expression an InstantiateNull function?
*
* @param itemExpr The InstantiateNull expression
* @return TRUE is the passed itemExpr is an InstantiateNull function.
*/
NABoolean isInstNull(ItemExpr* itemExpr);
/**
* Skip the VEGReference and/or InstantiateNull function to get to the column itself.
*
* @param itemExpr The InstantiateNull expression
* @return A QRColumn element for the column pointed to by the InstantiateNull
* function.
*/
QRColumnPtr skipInstNull(ItemExpr* itemExpr);
/**
* Replaces all occurrences of a given column name in a string with a numbered
* placeholder.
*
* @param pItemText The expression text to do the replacement in.
* @param colvid ValueId of the column to replace.
* @param dColIndex Numeric suffix to append to the base marker text for each
* occurrence of the column in the text.
* @return \c TRUE if at least one instance of the column was replaced,
* otherwise \c FALSE.
*/
NABoolean normalizeColumnInExpression(NAString& pItemText,
ValueId colvid,
short dColIndex);
/**
* Creates a JBB descriptor object from an Analyzer JBB object, and fills in
* the descriptor object with information derived from the Analyzer object.
*
* @param jbb The Analyzer JBB.
* @return The descriptor version of the JBB.
*/
QRJBBPtr createJbb(JBB* jbb);
/**
* Sets bits in the residual predicate bitmap for any column that is part of
* a VEG in the list of veg refs.
*
* @param vegrefsInExpr List of veg refs to go through.
*/
void markColumnsAsResidual(ValueIdSet& vegrefsInExpr);
/**
* Creates a residual predicate descriptor object for the predicate with the
* given ValueId.
*
* @param predVid ValueId of the predicate.
* @param jbbElement JBB element to which the residual predicate belongs.
*/
void processResidualPredicate(ValueId predVid, QRJBBPtr jbbElement);
/**
* Creates a group by descriptor object corresponding to the passed
* \c GBAnalysis object.
*
* @param gbAnalysis The Analyzer's analysis object for the group by.
* @param jbbElement The JBB descriptor object the group by is for.
*/
void processGroupBy(RelExpr* groupByNode,
CANodeId gbID,
QRJBBPtr jbbElement);
/**
* Creates the output list for a descriptor from the characteristic outputs
* of the top node of an Analyzer JBB.
*
* @param normOutput Characteristic outputs of the JBB
* @param jbbElement Descriptor object for the JBB this is the output of.
*/
void processOutputList(const ValueIdSet& normOutput,
QRJBBPtr jbbElement);
/**
* Creates the table descriptor objects and possibly group by descriptor
* object that are the contents of a JBB in the descriptor.
*
* @param jbbcNodeIds Node ids for the JBBCs of the JBB.
* @param jbbElement The JBB descriptor object.
* @param jbbOutputs The ValueIdSet of the JBB outputs.
*/
void processJBBCList(CANodeIdSet* jbbcNodeIds,
QRJBBPtr jbbElement,
ValueIdSet &jbbOutputs,
CANodeId& groupJbbcNodeId);
/**
* Process the primary key of the table, and add it into the table element.
* @param tableAnalysis
* @param tableElement
* @param jbbOutputs
*/
void processKeys(TableAnalysis* tableAnalysis,
QRTablePtr tableElement,
ValueIdSet &jbbOutputs);
/**
* Creates a version descriptor object. Each of the top-level descriptor
* objects (query, MV, result) has a version associated with it.
*
* @return The version object.
*/
QRVersionPtr createVersionElement();
/**
* Adds stored range predicates to their correct lists. To this point they
* have been stored in a hash table so they can be found and updated if
* another predicate causes the range to be modified, as in <code>a between
* 10 and 20 and a <> 15</code>, which is represented by two separate
* predicates.
*/
void addRangePredicates();
QRElementPtr getElementForValueID(char firstChar, UInt32 id) const;
NABoolean isMvMode()
{
return descriptorType_ == ET_MVDescriptor;
}
NABoolean isQueryMode()
{
return descriptorType_ == ET_QueryDescriptor;
}
NABoolean isRangeSupported(QRRangePredPtr rangePred);
private:
/** Starting value for generated IDs for pseudo-JBBs. */
static const UInt32 GENERATED_JBBID_START;
// To keep track of column IDs - the set gets populated
// and utilized when bGenColumnRefs_ is TRUE
ValueIdSet mColumnsUsed_;
ValueIdSet mExtraHubColumnsUsed_;
CollHeap* mvqrHeap_;
NAString mMVTableName_;
NABoolean bSortJoinPredicateCols_;
NABoolean bGenColumnRefs_;
NABoolean bFormatted_;
UInt32 generatedJBBid_;
NABoolean putAllJBBsInQD_; // read from CQD MVQR_ALL_JBBS_IN_QD
ElementType descriptorType_; // Query or MV descriptor being generated?
RelExpr* relExpr_; // root node of query
JBB* currentJBB_; // currently generating desc for this JBB
/** Hash table mapping ValueIds of columns to their associated range info. */
NAHashDictionary<QRValueId, RangeInfo> rangeColHash_;
/** Hash table mapping text of expressions to their associated range info. */
NAHashDictionary<const NAString, RangeInfo> rangeExprHash_;
/** Hash table mapping ValueIds of columns to their associated equality set. */
NAHashDictionary<QRValueId, EqualitySet> vegsUsedHash_;
/** Hash table mapping text of expressions to their associated equality set. */
NAHashDictionary<const NAString, EqualitySet> exprsUsedHash_;
/** Hash table mapping ids to their QRColumn or QRTable object. */
QRElementHash colTblIdHash_;
/** Map column value ids to the join pred they are in. In MV and query
* descriptors, a ref to a column uses a 'J' element id with the join pred's
* value id number. Col ids are the bottom values in the map.
*/
ValueIdMap colToJoinPredMap_;
NAList<EqualitySet*> allEqualitySets_;
NABoolean isDumpMvMode_;
Lng32 maxExprSize_;
Lng32 maxExprDepth_;
}; // QRDescGenerator
#endif /* QUERYDESCRIPTOR_H */