blob: 4e9701aff794cf7cc675260cd84a4f7d7766c6d8 [file] [log] [blame]
/* -*-C++-*-
*************************************************************************
*
* File: NormWA.C
* Description: The workarea used by the normalizer
* Created: 4/27/94
* Language: C++
*
*
// @@@ 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 @@@
*
*
*************************************************************************
*/
// -----------------------------------------------------------------------
#include "Sqlcomp.h"
#include "NormWA.h"
#include "CmpContext.h"
#ifdef INCLUDE_SELECTED_HEADERS
#endif // INCLUDE_SELECTED_HEADERS
void NormWA::setComplexScalarExprFlag()
{
complexScalarExprCount_++;
setWalkingAnExprTreeFlag();
} // NormWA::setComplexScalarExprFlag()
void NormWA::restoreComplexScalarExprFlag()
{
complexScalarExprCount_--;
restoreWalkingAnExprTreeFlag();
} // NormWA::restoreComplexScalarExprFlag()
void NormWA::setNullFlag()
{
nullCount_++;
setWalkingAnExprTreeFlag();
} // NormWA::setNullFlag()
void NormWA::restoreNullFlag()
{
nullCount_--;
restoreWalkingAnExprTreeFlag();
} // NormWA::restoreNullFlag()
void NormWA::setNotFlag()
{
notCount_++;
setWalkingAnExprTreeFlag();
} // NormWA::setNotFlag()
void NormWA::restoreNotFlag()
{
notCount_--;
restoreWalkingAnExprTreeFlag();
} // NormWA::restoreNotFlag()
void NormWA::setOrFlag()
{
orCount_++;
setWalkingAnExprTreeFlag();
} // NormWA::setOrFlag()
void NormWA::restoreOrFlag()
{
orCount_--;
restoreWalkingAnExprTreeFlag();
} // NormWA::restoreOrFlag()
CollHeap* NormWA::wHeap()
{
return (currentCmpContext_) ? (currentCmpContext_->statementHeap()) : 0;
}
void NormWA::locateVEGRegionAndMarkToBeMergedRecursively(const ValueId & vid)
{
VEGRegion* toBeMergedRegion = locateVEGRegionAndMarkToBeMerged(vid);
if (toBeMergedRegion)
{
ValueIdSet nullInstValues;
toBeMergedRegion->gatherInstantiateNullMembers(nullInstValues);
for (ValueId exprId = nullInstValues.init();
nullInstValues.next(exprId);
nullInstValues.advance(exprId))
{
locateVEGRegionAndMarkToBeMergedRecursively(exprId);
}
}
}
NABoolean NormWA::findEquivalentInSeqFunctionsCache(ItemExpr * newItem,
ValueId &cacheEquivTransSeqId ){
//ValueId equivId = newSeqId;
CollIndex equivIndex = -1;
//ItemExpr *newItem = newSeqId.getItemExpr();
ItmSequenceFunction *newSeq = NULL;
if(newItem->isASequenceFunction()) {
newSeq = (ItmSequenceFunction *)newItem;
}
if(newSeq) {
for(CollIndex i = 0 ; i < origSeqFunction_.entries(); i++)
{
ItemExpr *seq = origSeqFunction_[i];
if(newSeq->isEquivalentForBinding(seq)){
equivIndex = i;
break;
}
}
}
if (equivIndex == -1) {
return FALSE;
}
return retrieveFromSeqFunctionsCache(equivIndex, cacheEquivTransSeqId);
}
ValueId NormWA::getEquivalentItmSequenceFunction(ValueId newSeqId)
{
ValueId equivId = newSeqId;
ItemExpr *newItem = newSeqId.getItemExpr();
ItmSequenceFunction *newSeq = NULL;
if(newItem->isASequenceFunction()) {
newSeq = (ItmSequenceFunction *)newItem;
}
if(newSeq) {
for(ValueId seqId = allSeqFunctions_.init(); allSeqFunctions_.next(seqId);
allSeqFunctions_.advance(seqId) ){
ItemExpr *seq = seqId.getItemExpr();
if(newSeq->isEquivalentForBinding(seq)){
equivId = seqId;
if(newSeq->origOpType() != seq->origOpType()) {
seq->setOrigOpType(seq->getOperatorType());
}
break;
}
}
}
allSeqFunctions_ += equivId;
//
return equivId;
}
void NormWA::optimizeSeqFunctions( ItemExpr * ie, ItemExpr * pie, Int32 idx)
{
if (ie){
for(Int32 i = 0; i < ie->getArity(); i++ ){
optimizeSeqFunctions( ie->child(i), ie , i);
}
if (ie->isASequenceFunction()) {
ValueId equivid;
equivid = getEquivalentItmSequenceFunction(ie->getValueId());
if (equivid != ie->getValueId()) {
pie->child(idx)= equivid;
}
//ie = getEquivalentItmSequenceFunction(ie->getValueId()).getItemExpr();
}
}
else {
return;
}
}
const RelExpr * NormWA::getCurrentOwnerExpr()
{
if (getVEGTable() && getVEGTable()->getCurrentVEGRegion())
return getVEGTable()->getCurrentVEGRegion()->getOwnerExpr()->castToRelExpr() ;
else
return NULL ;
}
// Methods of the SqoWA
// This function restores a changed RelExpr back to its original form
// based on what we originally changed.
NABoolean SqoChangedRelExprs::undoChanges(NormWA & normWARef, Lng32 subqId)
{
NABoolean performedUndo = FALSE;
if (subqId_ == subqId)
{
switch (whatChanged_)
{
case SQO_REASSIGNED_VREGION:
normWARef.reassignVEGRegion(changedRelExpr_, changedChildId_,
originalRelExpr_, origChildId_);
performedUndo = TRUE;
break;
}
}
return performedUndo;
}
// This function restores a changed Vid back to its original form
// based on what we originally changed.
NABoolean SqoChangedItemExprs::undoChanges(NormWA & normWARef, Lng32 subqId)
{
NABoolean performedUndo = FALSE;
if (subqId_ == subqId)
{
switch (whatChanged_)
{
case SQO_REPLACED:
changedVid_.replaceItemExpr(oldItemExpr_);
performedUndo = TRUE;
break;
case SQO_NEWCHILD:
changedVid_.getItemExpr()->child(changedChild_) = oldItemExpr_;
performedUndo = TRUE;
break;
case SQO_NEWOPTYPE:
changedVid_.getItemExpr()->setOperatorType(oldOperatorType_);
performedUndo = TRUE;
break;
}
}
return performedUndo;
}
void SqoWA::undoChanges(NormWA & normWARef )
{
// We need a list of indexes to ItemExprs that we have restored
LIST(SqoChangedItemExprs * ) undoneItemExprs(STMTHEAP);
// We need a list indexes to of RelExprs that we have restored
LIST(SqoChangedRelExprs * ) undoneRelExprs(STMTHEAP);
for (UInt32 itemIdx=0; itemIdx < changedItemExprs_.entries(); itemIdx++)
{
if (changedItemExprs_[itemIdx]->undoChanges(normWARef, subqId_))
undoneItemExprs.insert(changedItemExprs_[itemIdx]);
}
for (UInt32 relIdx=0; relIdx < changedRelExprs_.entries(); relIdx++)
{
if (changedRelExprs_[relIdx]->undoChanges(normWARef, subqId_))
undoneRelExprs.insert(changedRelExprs_[relIdx]);
}
// Remove the things we undid.
for (UInt32 idx=0; idx < undoneItemExprs.entries(); idx++)
changedItemExprs_.remove(undoneItemExprs[idx]);
for (UInt32 idx=0; idx < undoneRelExprs.entries(); idx++)
changedRelExprs_.remove(undoneRelExprs[idx]);
}