| /* -*-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]); |
| |
| } |
| |