blob: 07c1ae49cc2438d1c747d41f542b11b35b66fda2 [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 @@@
// **********************************************************************
/***********************************************************************
*
* File: QmsWorkloadAnalysis.h
* Description: Implementation of the WorkloadAnalysis and ProposedMV
* classes for finding proposed MVs that can be used to
* rewrite queries of existing MVs.
* The lingo is a bit confusing, because each query in the
* workload is represented here by an MVDetails object,
* and the result of the analysis is a ProposedMV.
*
* Created: 05/17/11
***********************************************************************/
#ifndef _WORKLOADANALYSIS_H_
#define _WORKLOADANALYSIS_H_
#include "NABasicObject.h"
#include "NAString.h"
#include "Collections.h"
#include "QRSharedPtr.h"
#include "QRDescriptor.h"
class WorkloadAnalysis;
class ProposedMV;
#ifdef _MEMSHAREDPTR
typedef QRIntrusiveSharedPtr<ProposedMV> ProposedMVPtr;
typedef QRIntrusiveSharedPtr<WorkloadAnalysis> WorkloadAnalysisPtr;
#else
typedef ProposedMV* ProposedMVPtr;
typedef WorkloadAnalysis* WorkloadAnalysisPtr;
#endif
typedef NAPtrList<ProposedMVPtr> ProposedMVPtrList;
typedef SharedPtrValueHash<const NAString, QRElement> ElementHash;
typedef SharedPtrValueHashIterator<const NAString, QRElement> ElementHashIterator;
typedef NAHashDictionary<const NAString, const NAString> QueryNameHash;
#include "QmsMVDetails.h"
#include "QmsMVCandidate.h"
/**
* The ProposedMV class is initialized with a list of MVDetails objects
* for queries that share the same join graph and GroupBy list.
* It is then used to analyze any differences between those queries,
* and find the minimal set of predicates that are common to all.
* Finally, it generates the SQL text for the CREATE MV command.
***********************************************************************
*/
class ProposedMV : public NAIntrusiveSharedPtrObject
{
public:
ProposedMV(ADD_MEMCHECK_ARGS_DECL(CollHeap* heap))
: NAIntrusiveSharedPtrObject(ADD_MEMCHECK_ARGS_PASS(heap)),
name_(heap),
mapList_(heap),
isInitialized_(FALSE),
groupingColumns_(hashKey, INIT_HASH_SIZE_SMALL, TRUE, heap), // Pass NAString::hashKey
selectList_(hashKey, INIT_HASH_SIZE_SMALL, TRUE, heap), // Pass NAString::hashKey
selectArray_(heap),
rangePredList_(heap),
residualPredList_(heap),
mvPairList_(heap),
canSkipRangePreds_(FALSE),
canSkipResidualPreds_(FALSE),
addedOutputs_(heap),
addedLojTables_(heap),
hasGroupBy_(FALSE),
stuffToDelete_(heap),
heap_(heap)
{
}
virtual ~ProposedMV();
/**
* Add a single MVDEtails object to the list.
* @param mv The MV to add
*/
void addMV(MVDetailsPtr mv, QRJoinSubGraphMapPtr map);
/**
* Add a list of MVDEtails objects.
* @param mvs The list of MVs to add.
*/
void addMVs(const SubGraphMapList& maps);
/**
* Set the name of the proposed MV, based on its number.
* @param num The proposed MV number.
*/
void setName(Int32 num);
/**
* Get the name of the proposed MV.
* @return Get the name of the proposed MV.
*/
const NAString& getName()
{
return name_;
}
SubGraphMapList& getMapList()
{
return mapList_;
}
/**
* Create the list of MVPair objects.
* Each MVPair is composed of the first query, and one of the others.
* So that the first query is compared to all the rest.
*/
void initializeMVPairList();
/**
* Add to the select list all the columns needed by all the MVs.
*/
void findInclusiveSelectList();
/**
* Analyze the range and residual predicates of the MVs to find the
* subset of common predicates.
*/
void findReducedPredicateSet();
/**
* Generate the SQL for the proposed MV.
* @param text The NAString to add the SQL text into.
* @param addComments By default this method adds information on supported
* queries in comment lines. Set this parameter to FALSE
* to return only the SQL command.
*/
void reportResults(NAString& text, NABoolean addComments = TRUE);
Int32 getJoinSize();
protected:
// Methods for analyzing common predicates.
void initFrom(QRJoinSubGraphMapPtr map);
void checkBitmapsFirst();
void handleRangePredicates();
void handleResidualPredicates();
void handleLeftOuterJoins();
void handleRemovedRangePredicate(QRRangePredPtr pred);
void handleRemovedResidualPredicate(QRExprPtr pred);
void addElementToSelectList(const QRElementPtr col);
void addMvSideColumnToSelectList(const QRColumnPtr mvCol, MVPairPtr thisPair);
// Methods for generating the CREATE MV SQL.
void toSQL(NAString& text);
void unparseSelectClause(NAString& text);
void unparseFromClause(NAString& text);
void unparseWhereAndHavingClauses(NAString& text, NAString& havingClause);
void unparseGroupByClause(NAString& text);
void unparseRangePreds(NAString& whereClause, NAString& havingClause);
void unparseResidualPreds(NAString& whereClause, NAString& havingClause);
NAString getFromClauseForTable(JoinGraphTablePtr table);
NAString getOnClauseFor(QRJoinSubGraphPtr subGraph, JoinGraphTablePtr nextTable);
NAString getColumnCorrelationName(QRColumnPtr column);
NAString unparseColumnOrExpr(const QRElementPtr elem);
const NAString* getHashKeyForElement(const QRElementPtr elem);
void addPredicateText(NAString& text, const NAString& pred);
NABoolean isAddedLojTable(const NAString& id);
NABoolean isSingleQuery()
{
return mapList_.entries() == 1;
}
private:
CollHeap* heap_;
NAString name_;
SubGraphMapList mapList_;
NABoolean isInitialized_;
// The select list and GroupBy list are both initialized from the first MV,
// and then addidional columns may be added (no duplicates allowed).
// The select array keeps the entries ordered by ordinal number, to avoid sorting.
ElementHash selectList_;
NAArray<QROutputPtr> selectArray_;
ElementHash groupingColumns_;
// The range and residual predicates lists are both initialized from the
// first MV, and then non-common predicates are removed.
NAPtrList<QRRangePredPtr> rangePredList_;
NAPtrList<QRExprPtr> residualPredList_;
// The MVPair objects are used to match range and residual predicates.
// Each pair is composed of the first MVDetails, and one of the others.
MVPairList mvPairList_;
NAPtrList<QROutputPtr> addedOutputs_;
StringPtrSet addedLojTables_;
NABoolean canSkipRangePreds_;
NABoolean canSkipResidualPreds_;
NABoolean hasGroupBy_;
// Fake elements that are constructed for matching purposes
// and need to be deleted before destruction.
NAPtrList<QRElementPtr> stuffToDelete_;
}; // class ProposedMV
/**
* The WorkloadAnalysis class is a container of ProposedMV objects.
***********************************************************************
*/
class WorkloadAnalysis : public NAIntrusiveSharedPtrObject
{
public:
WorkloadAnalysis(ADD_MEMCHECK_ARGS_DECL(CollHeap* heap))
: NAIntrusiveSharedPtrObject(ADD_MEMCHECK_ARGS_PASS(heap)),
proposedMVsList_(heap),
inventoryHash_(hashKey, INIT_HASH_SIZE_LARGE, TRUE, heap),
nextMV_(1),
heap_(heap)
{
}
virtual ~WorkloadAnalysis();
/**
* Add a new ProposedMV object to the list.
* @param pmv
* @return TRUE if added correctly, FALSE if found to be a duplicate.
*/
NABoolean addProposedMV(ProposedMVPtr pmv);
/**
* Perform the common predicate analysis.
*/
void findReducedPredicateSet();
/**
* Generate the output text with the SQL text of the proposed MVs.
* @param ofs The output stream
*/
void reportResults(ofstream& ofs, Int32 minQueriesPerMV);
Int32 getMaxJoinSize();
private:
CollHeap* heap_;
ProposedMVPtrList proposedMVsList_;
QueryNameHash inventoryHash_;
Int32 nextMV_;
}; // class WorkloadAnalysis
#endif // _WORKLOADANALYSIS_H_