| /********************************************************************** |
| // @@@ 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 REFRESHBUILDER_H |
| #define REFRESHBUILDER_H |
| |
| /* -*-C++-*- |
| ****************************************************************************** |
| * |
| * File: MvRefreshBuilder.h |
| * Description: Definition of class Refresh for MV INTERNAL REFRESH command. |
| * |
| * Created: 12/27/2000 |
| * Language: C++ |
| * Status: $State: Exp $ |
| * |
| * |
| ****************************************************************************** |
| */ |
| |
| |
| #include "ComMvDefs.h" |
| #include "RelMisc.h" |
| #include "Refresh.h" |
| #include "ChangesTable.h" |
| |
| // classes defined in this file |
| class MvRefreshBuilder; |
| class MvRecomputeBuilder; |
| class MavBuilder; |
| class MinMaxMavBuilder; |
| class MultiDeltaMavBuilder; |
| class MvMultiTxnMavBuilder; |
| class PipelinedMavBuilder; |
| class MultiDeltaRefreshMatrix; |
| class MultiDeltaRefreshMatrixRow; |
| class MavRelRootBuilder; |
| struct MinMaxColExtraInfo; |
| |
| // Forward references |
| class LogsInfo; |
| class DeltaDefinitionPtrList; |
| class IntegerList; |
| class CorrName; |
| class QualifiedName; |
| class Refresh; |
| class MVColumnInfo; |
| class MvIudLog; |
| class MVJoinGraph; |
| class Union; |
| class RelSequence; |
| |
| //---------------------------------------------------------------------------- |
| // The MvRefreshBuilder class hierarchy is responsible for the actual |
| // inlining work of building the refresh RelExpr trees. |
| // For ON REQUEST MVs, if the refresh is not pipelined, only one object is |
| // built and used. In case of pipelined refresh, several objects are built, |
| // each for a single level of MV refresh. |
| // The MvRefreshBuilder class itself is abstract. |
| // Here is the class hierarchy: |
| // MvRefreshBuilder : |
| // MvRecomputeBuilder |
| // MjvBuilder (defined in MjvBuilder.h/cpp) |
| // MjvImmInsertBuilder |
| // MjvImmDeleteBuilder |
| // MjvImmDirectUpdateBuilder |
| // MavBuilder |
| // MultiDeltaMavBuilder |
| // MvMultiTxnMavBuilder |
| // MinMaxMavBuilder |
| // PipelinedMavBuilder |
| //---------------------------------------------------------------------------- |
| class MvRefreshBuilder : public NABasicObject |
| { |
| public: |
| |
| MvRefreshBuilder(const CorrName& mvName, |
| MVInfoForDML *mvInfo, |
| Refresh *refreshNode, |
| BindWA *bindWA); |
| |
| private: |
| // Copy Ctor and = operator are not implemented. |
| MvRefreshBuilder(const MvRefreshBuilder& other); |
| MvRefreshBuilder& operator=(const MvRefreshBuilder& other); |
| |
| public: |
| enum { MAX_EPOCH_FOR_UNION_BACKBONE = 50 }; |
| |
| public: |
| virtual ~MvRefreshBuilder(); |
| |
| // Accessors to private data members |
| const CorrName& getMvCorrName() const { return mvCorrName_; } |
| Refresh *getRefreshNode() const { return refreshNode_; } |
| MVInfoForDML *getMvInfo() const { return mvInfo_; } |
| Lng32 getPhase() const { return phase_; } |
| const DeltaDefinitionPtrList *getDeltaDefList() const |
| { return deltaDefList_;} |
| void setDeltaDefList(const DeltaDefinitionPtrList *deltaDef) |
| { deltaDefList_ = deltaDef;} |
| |
| // Build the refresh RelExpr tree. This pure virtual method is respossible |
| // for building the main refresh tree. This is done differently for every |
| // refresh type. |
| virtual RelExpr *buildRefreshTree() = 0; |
| |
| // Transform the Scan on the base table from the MV SELECT tree, to scan |
| // the logs instead. This is the basic implementation that handles the IUD |
| // log and the range log. It is overridden by MvMultiTxnMavBuilder for |
| // that special case. |
| virtual RelExpr *buildLogsScanningBlock(const QualifiedName& baseTable); |
| |
| virtual NABoolean needAlternateCIorder() const; |
| |
| virtual Union *buildUnionBetweenRangeAndIudBlocks(RelExpr *scanIUDLogBlock, |
| RelExpr *scanRangeLogBlock) const; |
| |
| protected: |
| |
| virtual RelRoot *buildRootWithUniformSelectList(RelExpr *topNode, |
| ItemExpr *opExpr, |
| const CorrName *nameOverride, |
| NABoolean forRange) const; |
| |
| LogsInfo &getLogsInfo() const |
| { |
| CMPASSERT(logsInfo_); |
| return *logsInfo_; |
| } |
| |
| // Prepare for Multi-Delta refresh (both MAV and MJV) |
| MultiDeltaRefreshMatrix *prepareProductMatrix(NABoolean supportPhases, |
| NABoolean checkOnlyInserts); |
| |
| // Prepare a single join product according to the product matrix row. |
| RelRoot *prepareProductFromMatrix( |
| const MultiDeltaRefreshMatrix& productMatrix, |
| RelRoot *rawJoinProduct, |
| Int32 rowNumber, |
| NABoolean isLast); |
| |
| // Any reason not to implement multi-delta optimization? |
| // (implemented differently by MAV and MJV) |
| virtual NABoolean avoidMultiDeltaOptimization() { return FALSE; }; |
| |
| // Methods called internally for reading the IUD log |
| // ---------------------------------------------------- |
| |
| virtual RelExpr *buildReadIudLogBlock(); |
| |
| virtual Int32 getNumOfScansInUnionBackbone() const; |
| |
| void fixScanCardinality(RelExpr *node, |
| double cardinalityFactor, |
| Cardinality cardinality) const; |
| |
| // Construct the appropriate expression for the Op@ virtual column. |
| // The value of this column is 1 for inserted rows, and -1 for deleted rows. |
| ItemExpr *constructOpExpression() const; |
| |
| // buildReadIudLogBlock callee |
| virtual ItemExpr *buildSelectionPredicateForScanOnIudLog() const; |
| |
| virtual ItemExpr *buildSelectionListForScanOnIudLog() const; |
| |
| virtual ItemExpr *buildBaseTableColumnList(Lng32 specialFlags=0) const; |
| |
| // Have a uniform select list over the IUD log |
| virtual RelRoot *buildRootOverIUDLog(RelExpr *topNode) const; |
| |
| // Methods called internally for reading the range log |
| // ---------------------------------------------------- |
| |
| virtual RelExpr *buildReadBaseTable() const; |
| |
| // Construct a join between the base table and the range log |
| virtual RelExpr *buildReadRangesBlock() const; |
| |
| virtual ItemExpr *buildEndRangeVector() const; |
| |
| virtual ItemExpr *buildBeginRangeVector() const; |
| |
| // Construct a join between the base table and the range log |
| virtual RelExpr *buildReadRangeLogBlock() const; |
| |
| // buildReadRangeLogBlock() callee |
| virtual RelRoot *buildRootOverRangeBlock(RelExpr *topNode) const; |
| // buildReadRangeLogBlock() callee |
| virtual RelExpr *buildJoinBaseTableWithRangeLog(RelExpr *scanRangeLog, |
| RelExpr *scanBaseTable) const; |
| |
| // Used by buildUnionWithRangeLog(), Overridden by MvMultiTxnMavBuilder |
| virtual ItemExpr *buildSelectionPredicateForScanOnRangeLog() const; |
| |
| // Construct the join predicate between the base table and the range log. |
| // Overridden by MvMultiTxnMavBuilder for additional predicates. |
| virtual ItemExpr *buildRangeLogJoinPredicate() const; |
| |
| virtual ItemExpr *buildRangeLogJoinPredicateWithCols( |
| ItemExpr *rangeType, |
| ItemExpr *baseCI, |
| ItemExpr *beginRangeCI, |
| ItemExpr *endRangeCI) const; |
| |
| |
| virtual NABoolean useUnionBakeboneToMergeEpochs() const; |
| |
| virtual RelExpr *buildUnionBakeboneToMergeEpochs(RelExpr *topNode) const; |
| |
| virtual Int32 isGroupByAprefixOfTableCKeyColumns() const { return FALSE; } |
| |
| virtual ItemExpr *buildAlternateCIorder(ItemExpr *ciColumns, const CorrName &tableNameCorr) const; |
| |
| // Was INTERNAL REFRESH invoked with DE LEVEL 3? |
| NABoolean wasFullDE() const; |
| |
| // The statement heap (taken from bindWA). |
| CollHeap *heap_; |
| |
| BindWA *bindWA_; |
| |
| private: |
| |
| // Data members. |
| // ---------------------------------------------------- |
| // The name of the MV being refreshed. |
| CorrName mvCorrName_; |
| // The Delta Definitions of the logs used. |
| const DeltaDefinitionPtrList *deltaDefList_; |
| // Which phase of multi-delta refresh is this invocation? |
| Lng32 phase_; |
| MVInfoForDML *mvInfo_; |
| Refresh *refreshNode_; |
| LogsInfo *logsInfo_; |
| |
| }; // class MvRefreshBuilder |
| |
| //---------------------------------------------------------------------------- |
| // The simplest Refresh tree: RECOMPUTE. |
| //---------------------------------------------------------------------------- |
| class MvRecomputeBuilder : public MvRefreshBuilder |
| { |
| public: |
| MvRecomputeBuilder(const CorrName& mvName, |
| MVInfoForDML *mvInfo, |
| NABoolean noDeleteOnRecompute, |
| BindWA *bindWA) |
| : MvRefreshBuilder(mvName, mvInfo, NULL, bindWA), |
| noDeleteOnRecompute_(noDeleteOnRecompute) |
| {} |
| |
| virtual ~MvRecomputeBuilder() {} |
| |
| private: |
| // Copy Ctor and = operator are not implemented. |
| MvRecomputeBuilder(const MvRecomputeBuilder& other); |
| MvRecomputeBuilder& operator=(const MvRecomputeBuilder& other); |
| |
| public: |
| virtual RelExpr *buildRefreshTree(); |
| |
| private: |
| |
| |
| RelExpr *buildInsertToMvSubTree() const; |
| RelExpr *buildDeleteFromMvSubTree() const; |
| |
| private: |
| NABoolean noDeleteOnRecompute_; |
| |
| }; // class MvRecomputeBuilder |
| |
| //---------------------------------------------------------------------------- |
| // Builds the refresh tree of a single-delta MAV. |
| // This MAV reads the logs of its base tables for the refresh operation. |
| //---------------------------------------------------------------------------- |
| class MavBuilder : public MvRefreshBuilder |
| { |
| public: |
| MavBuilder(const CorrName& mvName, |
| MVInfoForDML *mvInfo, |
| Refresh *refreshNode, |
| NABoolean isProjectingMvDelta, |
| BindWA *bindWA); |
| |
| private: |
| // Copy Ctor and = operator are not implemented. |
| MavBuilder(const MavBuilder& other); |
| MavBuilder& operator=(const MavBuilder& other); |
| |
| public: |
| enum GroupOpNumbers { GOP_INSERT = 1, |
| GOP_DELETE, |
| GOP_UPDATE, |
| GOP_MINMAX_RECOMPUTE_FROM_UPDATE, |
| GOP_MINMAX_RECOMPUTE_FROM_INSERT }; |
| |
| virtual ~MavBuilder() {} |
| |
| // The implementation-specific part of building the MAV refresh tree. |
| // This method is overridden by every sub-class. |
| virtual RelExpr *buildRefreshTree(); |
| |
| static const char *getVirtualOpColumnName() { return virtualOpColumnName_; } |
| static const char *getVirtualGopColumnName() { return virtualGopColumnName_; } |
| static const char *getVirtualIsLastColName() { return virtualIsLastColumnName_; } |
| |
| // These are correlation names to "tables". |
| static const char *getSysDeltaName() { return sysDeltaName_; } |
| static const char *getSysCalcName() { return sysCalcName_; } |
| static const char *getSysMavName() { return sysMavName_; } |
| static const char *getStartCtxName() { return startCtxName_; } |
| static const char *getEndCtxName() { return endCtxName_; } |
| static const char *getMinMaxMavName() { return minMaxMavName_; } |
| |
| // These are name suffixes of extra aggregate columns added for each |
| // Min/Max column. |
| static const char *getExtraColSuffixForIns() { return extraColSuffixForIns_; } |
| static const char *getExtraColSuffixForDel() { return extraColSuffixForDel_; } |
| |
| protected: |
| |
| // Internal methods used by buildRefreshTree(). |
| |
| // The actual building of the refresh tree, that is the same for all |
| // MAV sub-classes. |
| RelExpr *buildTheMavRefreshTree(RelExpr *mvSelectTree, |
| DeltaDefinition *deltaDef); |
| |
| // build the left side of the refresh tree - the DCB. |
| RelExpr *buildDeltaCalculationBlock(RelExpr *mvSelectTree); |
| |
| // Construct a selection predicate on the MAV group by columns. |
| ItemExpr *buildGroupByColumnsPredicate(const NAString& table1Name, |
| const NAString& table2Name = "", |
| const NABoolean ignoreAlias = FALSE) const; |
| |
| // build the right side of the refresh tree - the DPB. |
| RelExpr *buildDeltaProcessingBlock(DeltaDefinition *deltaDef); |
| |
| // Build the Delta Processing Block Insert sub-tree. |
| RelExpr *buildDPBInsert(DeltaDefinition *deltaDef, RelExpr *topNode) const; |
| RelExpr *buildDPBInsertNodes(const NAString& sourceTable) const; |
| |
| // Build the Delta Processing Block Delete sub-tree. |
| RelExpr *buildDPBDelete(RelExpr *topNode); |
| |
| // Build the Delta Processing Block Update sub-tree. |
| // The Update expressions are of the form: |
| // (a is a MAV aggregate column, b is a MAV groupby column) |
| // SET expressions: a = tableForSet.a |
| // WHERE expressions: b = tableForWhere.b |
| RelExpr *buildDPBUpdate(const NAString& tableForSet, |
| const NAString& tableForWhere) const; |
| |
| // Build a stack of 5 RelRoot nodes to calculate the SYS_CALC columns. |
| RelExpr *buildLotsOfRootsForCalcCalculation(RelExpr *topNode, RelExpr *mvSelectTree); |
| |
| NABoolean isProjectingMvDelta() const { return isProjectingMvDelta_; } |
| |
| virtual NABoolean useUnionBakeboneToMergeEpochs() const; |
| |
| virtual Int32 isGroupByAprefixOfTableCKeyColumns() const; |
| |
| // Accessors for static data members |
| const char *getGopTableName() const { return gopTableName_; } |
| const char *getGopCol1Name() const { return gopCol1Name_; } |
| const char *getGopCol2Name() const { return gopCol2Name_; } |
| |
| private: |
| |
| // All the methods below are used for the generic support of MIN/MAX. |
| |
| // Delta Processing Block |
| RelExpr *buildDPBMinMaxIfCondition(const RelExpr *updateNode) const; |
| |
| RelExpr *createSignal() const; |
| |
| // Builds a Signal for this class. |
| // Overridden by MinMaxOptimizedMavBuilder. |
| virtual RelExpr *buildMinMaxRecomputationBlock() const; |
| |
| private: |
| // TRUE if this is not the top most refresh builder. |
| NABoolean isProjectingMvDelta_; |
| |
| // TRUE when there is no need to check if the Min/Max value was deleted. |
| NABoolean canSkipMinMax_; |
| |
| // This attribute has lazy evaluation, thus we use int instead of boolean. |
| // -1 is unintialized, 0 is false,1 is true |
| Int32 isGroupByAprefixOfTableCKeyColumns_; |
| |
| // This is needed for accessing the NATable of the base tables for |
| // MIN/MAX optimizations. |
| BindWA *pBindWA; |
| |
| // "Virtual" columns are columns that are manualy added to the RETDesc. |
| static const char virtualOpColumnName_[]; |
| static const char virtualGopColumnName_[]; |
| static const char virtualIsLastColumnName_[]; |
| |
| // These are correlation names to "tables". |
| static const char sysDeltaName_[]; |
| static const char sysCalcName_[]; |
| static const char sysMavName_[]; |
| static const char startCtxName_[]; |
| static const char endCtxName_[]; |
| static const char minMaxMavName_[]; |
| |
| // These names are used in pipelined refresh, for the TupleList join. |
| static const char gopTableName_[]; |
| static const char gopCol1Name_[]; |
| static const char gopCol2Name_[]; |
| |
| // These are name suffixes of extra aggregate columns added for each |
| // Min/Max column. |
| static const char extraColSuffixForIns_[]; |
| static const char extraColSuffixForDel_[]; |
| }; // class MavBuilder |
| |
| |
| //---------------------------------------------------------------------------- |
| class MinMaxOptimizedMavBuilder : public MavBuilder |
| { |
| |
| public: |
| MinMaxOptimizedMavBuilder(const CorrName& mvName, |
| MVInfoForDML *mvInfo, |
| Refresh *refreshNode, |
| NABoolean isProjectingMvDelta, |
| BindWA *bindWA) |
| : MavBuilder(mvName, mvInfo, refreshNode, isProjectingMvDelta, bindWA) |
| {} |
| |
| virtual ~MinMaxOptimizedMavBuilder() {} |
| |
| private: |
| // Copy Ctor and = operator are not implemented. |
| MinMaxOptimizedMavBuilder(const MinMaxOptimizedMavBuilder& other); |
| MinMaxOptimizedMavBuilder& operator=(const MinMaxOptimizedMavBuilder& other); |
| |
| protected: |
| virtual RelExpr *buildMinMaxRecomputationBlock() const; |
| |
| void fixGroupingColumns(RelRoot* pRoot) const; |
| |
| void removeGroupingColsFromSelectList(RelRoot* pRoot) const; |
| }; // MinMaxOptimizedMavBuilder |
| |
| |
| //---------------------------------------------------------------------------- |
| class MultiDeltaMavBuilder : public MavBuilder |
| { |
| public: |
| MultiDeltaMavBuilder(const CorrName& mvName, |
| MVInfoForDML *mvInfo, |
| Refresh *refreshNode, |
| NABoolean isProjectingMvDelta, |
| BindWA *bindWA) |
| : MavBuilder(mvName, mvInfo, refreshNode, isProjectingMvDelta, bindWA), |
| isDuplicatesOptimized_(FALSE) |
| {} |
| |
| private: |
| // Copy Ctor and = operator are not implemented. |
| MultiDeltaMavBuilder(const MultiDeltaMavBuilder& other); |
| MultiDeltaMavBuilder& operator=(const MultiDeltaMavBuilder& other); |
| |
| public: |
| |
| virtual ~MultiDeltaMavBuilder() {} |
| |
| virtual RelExpr *buildRefreshTree(); |
| |
| protected: |
| // Any reason not to implement multi-delta optimization? |
| // (implemented differently by MAV and MJV) |
| virtual NABoolean avoidMultiDeltaOptimization(); |
| |
| virtual NABoolean isTableExpressionPresent(RelExpr *currentNode); |
| |
| private: |
| void bindJoinProduct(RelRoot *product, NABoolean isSignPlus); |
| |
| RelExpr *buildRawDeltaCalculationTree( |
| const MultiDeltaRefreshMatrix& productMatrix); |
| |
| void prepareRetdescForUnion(RETDesc *retDesc, NABoolean isSignPlus); |
| |
| NABoolean collectOpExpressions(RETDesc *retDesc, |
| const ColumnDesc *columnDesc, |
| ItemExpr *&newOpExpr); |
| |
| RelExpr *getMvSelectTree() { return mvSelectTree_; } |
| |
| private: |
| NABoolean isDuplicatesOptimized_; |
| RelExpr *mvSelectTree_; |
| }; // class MultiDeltaMavBuilder |
| |
| //---------------------------------------------------------------------------- |
| class MvMultiTxnMavBuilder : public MavBuilder |
| { |
| public: |
| MvMultiTxnMavBuilder(const CorrName& mvName, |
| MVInfoForDML *mvInfo, |
| Refresh *refreshNode, |
| NABoolean isProjectingMvDelta, |
| BindWA *bindWA) |
| : MavBuilder(mvName, mvInfo, refreshNode, isProjectingMvDelta, bindWA), |
| pMultiTxnClause_(refreshNode->getNRowsClause()) |
| {} |
| |
| private: |
| // Copy Ctor and = operator are not implemented. |
| MvMultiTxnMavBuilder(const MvMultiTxnMavBuilder& other); |
| MvMultiTxnMavBuilder& operator=(const MvMultiTxnMavBuilder& other); |
| |
| public: |
| |
| virtual ~MvMultiTxnMavBuilder() {} |
| |
| virtual RelExpr *buildRefreshTree(); |
| |
| RelExpr *buildLogsScanningBlock(const QualifiedName& baseTable); |
| |
| protected: |
| |
| virtual RelExpr *buildReadPreviousContext(); |
| |
| RelExpr *buildErrorOnNoContext(RelExpr *topNode); |
| RelExpr *buildPhase1SelectList(RelExpr *topNode, const NATable *baseNaTable); |
| |
| virtual RelExpr *buildReadIudLogBlock() ; |
| |
| // buildReadIudLogBlock callee |
| virtual ItemExpr *buildSelectionPredicateForScanOnIudLog() const; |
| |
| virtual NABoolean needAlternateCIorder() const; |
| |
| virtual Union *buildUnionBetweenRangeAndIudBlocks(RelExpr *scanIUDLogBlock, |
| RelExpr *scanRangeLogBlock) const; |
| |
| virtual ItemExpr *buildSelectionPredicateForScanOnRangeLog() const; |
| |
| virtual ItemExpr *buildCatchupSelectionPredicateForScanOnRangeLog() const; |
| |
| virtual ItemExpr *buildPhase1SelectionPredicateForScanOnRangeLog() const; |
| |
| virtual ItemExpr *buildSelectionListForScanOnIudLog() const; |
| |
| virtual ItemExpr *buildRangeLogJoinPredicate() const; |
| |
| virtual ItemExpr *addContextPredicatesOnIUDLog() const; |
| |
| virtual NAString *getSequenceByPrefixColName() const |
| { |
| return NULL; |
| } |
| |
| virtual NABoolean useUnionBakeboneToMergeEpochs() const; |
| |
| virtual RelSequence *buildSequenceOnScan(RelExpr *topNode, ItemExpr *isLastExpr) const; |
| |
| virtual RelRoot *buildRootOverSequence(RelExpr *topNode, ItemExpr *isLastExpr) const; |
| |
| virtual ItemExpr *buildSequenceIsLastExpr() const; |
| |
| virtual RelExpr *buildInsertContextNode(); |
| |
| virtual RelExpr *buildInsertContextTree(RelExpr *leftTopNode); |
| |
| const NRowsClause *pMultiTxnClause_; |
| |
| }; // class MvMultiTxnMavBuilder |
| |
| //---------------------------------------------------------------------------- |
| //---------------------------------------------------------------------------- |
| //---------------------------------------------------------------------------- |
| //---------------------------------------------------------------------------- |
| // Exclude from coverage testing - used only with range loggiing |
| class MultiTxnDEMavBuilder : public MvMultiTxnMavBuilder |
| { |
| public: |
| MultiTxnDEMavBuilder(const CorrName& mvName, |
| MVInfoForDML *mvInfo, |
| Refresh *refreshNode, |
| NABoolean isProjectingMvDelta, |
| BindWA *bindWA) |
| : MvMultiTxnMavBuilder(mvName, mvInfo, refreshNode, isProjectingMvDelta, bindWA) |
| {} |
| |
| private: |
| // Copy Ctor and = operator are not implemented. |
| MultiTxnDEMavBuilder(const MultiTxnDEMavBuilder& other); |
| MultiTxnDEMavBuilder& operator=(const MultiTxnDEMavBuilder& other); |
| |
| public: |
| |
| virtual ~MultiTxnDEMavBuilder() {} |
| |
| protected: |
| virtual const char *getVirtualRangeSpecialCol() const { return virtualRangeSpecialCol_; } |
| |
| virtual NAString *getSequenceByPrefixColName() const |
| { |
| return new(heap_) NAString(sequenceByPrefixColName_); |
| } |
| |
| virtual NAString *getLastNotNullPrefixColName() const |
| { |
| return new(heap_) NAString(lastNotNullPrefixColName_); |
| } |
| |
| // The Range of values that @SPECIAL can recieve |
| enum { |
| VIRTUAL_BEGIN_RANGE, |
| TABLE_ROWS, |
| IUD_LOG_ROWS |
| }; |
| |
| // Have a uniform select list over the IUD log |
| virtual RelRoot *buildRootOverIUDLog(RelExpr *topNode) const; |
| |
| // Have a uniform select list over the Range log |
| virtual RelRoot *buildRootOverRangeBlock(RelExpr *topNode) const; |
| |
| ItemExpr *buildComputedTableSyskey(ItemExpr *colExpr) const; |
| |
| void buildSortKeyColumnsForRangeBlock(ItemExprList &sortKeyCols) const; |
| |
| void addSyskeyToSortKeyColumnsForRangeBlock(ItemExprList &sortKeyCols) const; |
| |
| RelRoot *buildRootWithFilterForEmptyRanges(RelExpr *topNode) const; |
| |
| virtual RelSequence *buildSequenceOnScan(RelExpr *topNode, ItemExpr *isLastExpr) const; |
| |
| virtual RelRoot *buildRootOverSequence(RelExpr *topNode, ItemExpr *isLastExpr) const; |
| |
| RelRoot *buildFinalRootOverSequence(RelExpr *topNode) const; |
| |
| ItemExpr *buildSelectionOverSequence() const; |
| |
| ItemExpr *buildIsCoveredByRange() const; |
| |
| ItemExpr *buildIsPhysicallyCoveredByRangeBoundries() const; |
| |
| // buildReadRangeLogBlock() callee |
| virtual RelExpr *buildJoinBaseTableWithRangeLog(RelExpr *scanRangeLog, |
| RelExpr *scanBaseTable) const; |
| |
| virtual RelExpr *buildReadRangeLogBlock() const; |
| |
| private: |
| static const char virtualRangeSpecialCol_[]; |
| static const char sequenceByPrefixColName_[]; |
| static const char lastNotNullPrefixColName_[]; |
| |
| }; // MultiTxnDEMavBuilder |
| |
| //---------------------------------------------------------------------------- |
| // Builds the refresh tree of a single-delta pipelined MAV. |
| // This MAV gets its input pipelined by the refresh tree of the used MV. |
| class PipelinedMavBuilder : public MavBuilder |
| { |
| public: |
| PipelinedMavBuilder(const CorrName& mvName, |
| MVInfoForDML *mvInfo, |
| Refresh *refreshNode, |
| NABoolean isProjectingMvDelta, |
| const QualifiedName *pipeliningSource, |
| BindWA *bindWA); |
| |
| private: |
| // Copy Ctor and = operator are not implemented. |
| PipelinedMavBuilder(const PipelinedMavBuilder& other); |
| PipelinedMavBuilder& operator=(const PipelinedMavBuilder& other); |
| |
| public: |
| virtual ~PipelinedMavBuilder() {} |
| |
| // called by Refresh::bindnode() for building the next level refresh tree |
| // and connecting it as a "view" that is projecting the data. |
| RelExpr *buildAndConnectPipeliningRefresh(RelExpr *pipeliningTree); |
| |
| protected: |
| QualifiedName *getPipeliningSource() |
| { return getDeltaDefList()->at(0)->getTableName(); } |
| |
| // Methods called by buildAndConnectPipeliningRefresh(). |
| // ---------------------------------------------------- |
| RelExpr *buildJoinWithTupleList(RelExpr *topNode); |
| RelRoot *buildRenameToLog(RelExpr *topNode); |
| |
| }; // class PipelinedMavBuilder |
| |
| //---------------------------------------------------------------------------- |
| //---------------------------------------------------------------------------- |
| //---------------------------------------------------------------------------- |
| class LogsInfo : public NABasicObject |
| { |
| public: |
| |
| LogsInfo(DeltaDefinition &deltaDef, |
| MVInfoForDML *mvInfo, |
| BindWA *bindWA); |
| |
| virtual ~LogsInfo(); |
| |
| private: |
| // Copy Ctor and = operator are not implemented. |
| LogsInfo(const LogsInfo& other); |
| LogsInfo& operator=(const LogsInfo& other); |
| |
| public: |
| |
| DeltaDefinition &getDeltaDefinition() { return deltaDef_; } |
| |
| MvIudLog &getMvIudlog() { return *currentMvIudlog_; } |
| |
| IntegerList *getBaseTableDirectionVector() { return baseTableDirectionVector_; } |
| |
| BindWA *getBindWA() { return bindWA_; } |
| |
| const NATable *getBaseNaTable() { return currentMvIudlog_->getSubjectNaTable(); } |
| |
| const NATable *getIudLogNaTable() { return currentMvIudlog_->getNaTable(); } |
| |
| const NATable *getRangeNaLogTable() |
| { |
| CMPASSERT(rangeNaTable_); |
| return rangeNaTable_; |
| } |
| |
| const CorrName &getBaseTableName() { return currentMvIudlog_->getSubjectTableName(); } |
| |
| const CorrName &getIudLogTableName() { return *currentMvIudlog_->getTableName(); } |
| |
| const CorrName &getRangeLogTableName() |
| { |
| CMPASSERT(rangeTableName_); |
| return *rangeTableName_; |
| } |
| |
| private: |
| // Given the base table name, construct the range log name from it. |
| CorrName *calcRangeLogName(const CorrName &theTable, CollHeap *heap) const; |
| |
| |
| DeltaDefinition &deltaDef_; |
| MvIudLog *currentMvIudlog_; |
| IntegerList *baseTableDirectionVector_; |
| MVInfoForDML *mvInfo_; |
| BindWA *bindWA_; |
| |
| NATable *rangeNaTable_; |
| CorrName *rangeTableName_; |
| }; |
| |
| //---------------------------------------------------------------------------- |
| //---------------------------------------------------------------------------- |
| //---------------------------------------------------------------------------- |
| class MultiDeltaRefreshMatrixRow : public NABasicObject |
| { |
| private: |
| enum rowSign { SIGN_MINUS = 0, SIGN_PLUS=1 }; |
| enum scanType { SCAN_TABLE = 0, SCAN_DELTA=1 }; |
| |
| public: |
| // Ctor for creating an all-but-last SCAN_TABLE row. |
| MultiDeltaRefreshMatrixRow(Int32 length, Int32 maxLength, CollHeap *heap); |
| |
| // Copy Ctor. |
| MultiDeltaRefreshMatrixRow(const MultiDeltaRefreshMatrixRow& other); |
| |
| // Dtor |
| virtual ~MultiDeltaRefreshMatrixRow() {} |
| |
| // Mutators |
| void initArray(); |
| void flipSignAndLastTable(); |
| void addColumn(scanType type = SCAN_TABLE); |
| |
| // Accessors |
| NABoolean isSignPlus() const |
| { return sign_==SIGN_PLUS; } |
| |
| NABoolean isScanOnDelta(CollIndex i) const |
| { return tableScanTypes_[i]==SCAN_DELTA; } |
| |
| #ifndef NDEBUG |
| void display() const; |
| void print(FILE* ofd = stdout, |
| const char* indent = DEFAULT_INDENT, |
| const char* title = "MultiDeltaRefreshMatrixRow") const; |
| #endif |
| |
| private: |
| rowSign sign_; // The sign of this matrix row. |
| Int32 currentLength_; // How many tables so far. |
| Int32 maxLength_; // The array size. |
| ARRAY(scanType) tableScanTypes_; // The matrix row itself. |
| CollHeap *heap_; // Used by the copy Ctor. |
| }; // class MultiDeltaRefreshMatrixRow |
| |
| //---------------------------------------------------------------------------- |
| class MultiDeltaRefreshMatrix : public NABasicObject |
| { |
| public: |
| MultiDeltaRefreshMatrix(Int32 maxNumOfRows, |
| MVJoinGraph *joinGraph, |
| CollHeap *heap); |
| |
| virtual ~MultiDeltaRefreshMatrix(); |
| |
| // Mutators |
| void addTable(NABoolean readDelta); |
| void setThisPhase(Int32 phase); |
| void calculatePhases(); |
| |
| // Accessors |
| const MultiDeltaRefreshMatrixRow *getRow(Int32 i) const; |
| |
| Int32 getNumOfRows() const { return numOfRows_; } |
| Int32 getRowLength() const { return currentRowLength_; } |
| NABoolean isLastPhase() const { return isLastPhase_; } |
| Lng32 getTableIndexFor(Int32 index) const { return tableIndexMapping_[index];} |
| Int32 getFirstRowForThisPhase() const { return firstRowForThisPhase_; } |
| Int32 getNumOfRowsForThisPhase() const { return numOfRowsForThisPhase_; } |
| void setPhasesSupported(NABoolean supported) { isPhasesSupported_ = supported; } |
| NABoolean isPhasesSupported() const { return isPhasesSupported_; } |
| NABoolean isTooManyDeltasError() const { return TooManyDeltasError_; } |
| NABoolean isDuplicatesOptimized() const { return isDuplicatesOptimized_; } |
| void disableDuplicateOptimization() { isDuplicatesOptimized_ = FALSE; } |
| |
| #ifndef NDEBUG |
| void display() const; |
| void print(FILE* ofd = stdout, |
| const char* indent = DEFAULT_INDENT, |
| const char* title = "MultiDeltaRefreshMatrix") const; |
| #endif |
| |
| private: |
| Int32 numOfRows_; // How many rows so far. |
| Int32 currentRowLength_; // How many tables so far. |
| Int32 maxRowLength_; // No. of tables in join product |
| CollHeap *heap_; // The binder (statement) heap. |
| // The actual matrix is an array of matrix rows. |
| ARRAY(MultiDeltaRefreshMatrixRow *) theMatrix_; |
| // The mapping from the tableIndex to the array of used objects in MVInfo. |
| // This mapping is created by the join graph algorithm. |
| ARRAY(Lng32) tableIndexMapping_; |
| |
| // data members for division to phases. |
| NABoolean isPhasesSupported_; // Do we need to support divition to phases? |
| Int32 thisPhase_; // PHASE parameter to refresh. |
| NABoolean isLastPhase_; // Are more phases needed? |
| Int32 firstRowForThisPhase_; // Where does this phase start? |
| Int32 numOfRowsForThisPhase_; // Ho many rows in this phase? |
| NABoolean TooManyDeltasError_; // Abort rather than risk an optimizer crash. |
| NABoolean isDuplicatesOptimized_; // Do not build full matrix, since duplicates |
| // are eliminated elsewhere. |
| |
| // Heuristic parameters taken from the Defaults table: |
| // Maximum number of tables in a join for doing everything in one phase. |
| Int32 maxJoinSizeForSinglePhase_; // Default is 3 |
| // Minimum join size for doing a single matrix row per phase. |
| Int32 minJoinSizeForSingleProductPerPhase_; // Default is 8 |
| // When the join size is between the two parameters above - how many |
| // matrix rows to do per phase. |
| Int32 phaseSizeForMidRange_; // Default is 6 |
| // If there are too many deltas, the optimizer may explode. |
| Int32 maxDeltasThreshold_; // Default is 31 rows (Six deltas) |
| |
| }; // class MultiDeltaRefreshMatrix |
| |
| |
| #endif |