blob: 74cda8abed1cbfc01eca1fb44fcd8423a91cd9a5 [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 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