/**********************************************************************
// @@@ 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 @@@
**********************************************************************/
/* -*-C++-*-
******************************************************************************
*
* File:         RelSequence.cpp
* Description:  All the methods of RelSequence() and PhysSequence().
*
* Created:      6/27/97
* Language:     C++
*
*
******************************************************************************
*/
#include "AllItemExpr.h"
#include "ItemSample.h"
#include "AllRelExpr.h"
#include "RelSequence.h"
#include "SchemaDB.h"
#include "GroupAttr.h"
#include "BindWA.h"
#include "NormWA.h"
#include "Cost.h"
#include "CostMethod.h"
#include "opt.h"
#include "Globals.h"

// -----------------------------------------------------------------------
// This file contains most of the methods for the class RelSequence
// This is a departure from the way other RelExpr's are organized.
//

// The RelSequence constructor.
// Inputs:
//
//  child: The child node of this node. presumably a Scan node.
//
RelSequence::RelSequence(RelExpr *child,
                         ItemExpr *requiredOrder,
                         CollHeap *oHeap)
  : RelExpr(REL_SEQUENCE, child, NULL, oHeap),
    requiredOrderTree_(requiredOrder),
    partitionBy_(NULL),
    cancelExprTree_(NULL),
    hasOlapFunctions_(FALSE),
    hasTDFunctions_(FALSE),
    cachedNumHistoryRows_(0),
    cachedHistoryRowLength_(0),
    cachedUnboundedFollowing_(FALSE),
    cachedMinFollowingRows_(0),
    historyInfoCached_(FALSE)
{
  setNonCacheable();
}

RelSequence::RelSequence(RelExpr *child,
                         ItemExpr *partitionBy,
                         ItemExpr *orderBy,
                         CollHeap *oHeap)
  : RelExpr(REL_SEQUENCE, child, NULL, oHeap),
    requiredOrderTree_(orderBy),
    partitionBy_(partitionBy),
    cancelExprTree_(NULL),
    hasOlapFunctions_(FALSE),
    hasTDFunctions_(FALSE),
    cachedNumHistoryRows_(0),
    cachedHistoryRowLength_(0),
    cachedUnboundedFollowing_(FALSE),
    cachedMinFollowingRows_(0),
    historyInfoCached_(FALSE)


{
  setNonCacheable();
}


// RelSequence::~RelSequence() -----------------------------------------------
// The destructor
//
RelSequence::~RelSequence()
{
}

ItemExpr *
RelSequence::removeRequiredOrderTree()
{
  ItemExpr *requiredOrderTree = requiredOrderTree_;

  requiredOrderTree_ = NULL;

  return requiredOrderTree;
}

//++MV
void RelSequence::addRequiredOrderTree(ItemExpr *orderExpr)
{
  ExprValueId c = requiredOrderTree_;

  ItemExprTreeAsList(&c, ITM_ITEM_LIST).insert(orderExpr);
  requiredOrderTree_ = c.getPtr();
}
//--MV 

// RelSequence::topHash() --------------------------------------------------
// Compute a hash value for a chain of derived RelExpr nodes.
// Used by the Cascade engine as a quick way to determine if
// two nodes are identical.
// Can produce false positives (nodes appear to be identical),
// but should not produce false negatives (nodes are definitely different)
//
// Inputs: none (other than 'this')
//
// Outputs: A HashValue of this node and all nodes in the
// derivation chain below (towards the base class) this node.
//
HashValue RelSequence::topHash()
{
  // Compute a hash value of the derivation chain below this node.
  //
  HashValue result = RelExpr::topHash();

  result ^= requiredOrder();
  result ^= partition();
  result ^= sequenceFunctions();
  result ^= sequencedColumns();
  result ^= cancelExpr();

  return result;
}

// RelSequence::duplicateMatch()
// A more thorough method to compare two RelExpr nodes.
// Used by the Cascades engine when the topHash() of two
// nodes returns the same hash values.
//
// Inputs: other - a reference to another node of the same type.
//
// Outputs: NABoolean - TRUE if this node is 'identical' to the
//          'other' node. FALSE otherwise.
//
// In order to match, this node must match all the way down the
// derivation chain to the RelExpr class.
//
// For the RelSequence node, the only relevant data members which
// need to be compared are partition_, requiredOrder_ and sequenceFunctions_
//
NABoolean
RelSequence::duplicateMatch(const RelExpr & other) const
{
  // Compare this node with 'other' down the derivation chain.
  //
  if (!RelExpr::duplicateMatch(other))
    return FALSE;

  // Cast the RelExpr to a RelSequence node. (This must be a RelSequence node)
  //
  const RelSequence &o = (RelSequence &) other;

  // If the required order keys are not the same 
  // then the nodes are not identical
  //
  if (!(requiredOrder() == o.requiredOrder()))
    return FALSE;

  if (!(partition() == o.partition()))
    return FALSE;

  // If the sequence functions are not the same 
  // then the nodes are not identical
  //
  if (!(sequenceFunctions() == o.sequenceFunctions()))
    return FALSE;

  if (!(sequencedColumns() == o.sequencedColumns()))
    return FALSE;

  if (!(cancelExpr() == o.cancelExpr()))
    return FALSE;

  return TRUE;
} // RelSequence::duplicateMatch

// RelSequence::copyTopNode ----------------------------------------------
// Copy a chain of derived nodes (Calls RelExpr::copyTopNode).
// Needs to copy all relevant fields.
// Used by the Cascades engine.
//
// Inputs: derivedNode - If Non-NULL this should point to a node
//         which is derived from this node.  If NULL, then this
//         node is the top of the derivation chain and a node must
//         be constructed.
//
// Outputs: RelExpr * - A Copy of this node.
//
// If the 'derivedNode is non-NULL, then this method is being called
// from a copyTopNode method on a class derived from this one. If it
// is NULL, then this is the top of the derivation chain and an RelSequence
// node must be constructed.
// 
// In either case, the relevant data members must be copied to 'derivedNode'
// and 'derivedNode' is passed to the copyTopNode method of the class
// below this one in the derivation chain (RelExpr::copyTopNode() in this
// case).
// 
RelExpr *
RelSequence::copyTopNode(RelExpr *derivedNode, CollHeap *outHeap)
{
  RelSequence *result;

  if (derivedNode == NULL)
    // This is the top of the derivation chain
    // Create an empty RelSequence node.
    //
    result = new (outHeap) RelSequence();
  else
    // A node has already been constructed as a derived class.
    //
    result = (RelSequence *) derivedNode;

  // Copy the relavant fields.

  result->requiredOrder() = requiredOrder();
  result->partition() = partition();
  result->sequenceFunctions() = sequenceFunctions();
  result->sequencedColumns() = sequencedColumns();
  result->cancelExpr() = cancelExpr();

  result->checkPartitionChangeExpr_  = checkPartitionChangeExpr_;
  result->hasOlapFunctions_ = hasOlapFunctions_;
  result->hasTDFunctions_= hasTDFunctions_;
  result->movePartIdsExpr_ = movePartIdsExpr_;

  //need to review the commented code below
  //result->requiredOrderTree_ = requiredOrderTree_->copyTree(outHeap)->castToItemExpr();
  if (partitionBy_)
    result->partitionBy_ = partitionBy_->copyTree(outHeap)->castToItemExpr();
  //result->cancelExprTree_ = cancelExprTree_->copyTree(outHeap)->castToItemExpr();
  // Copy any data members from the classes lower in the derivation chain.
  //
  return RelExpr::copyTopNode(result, outHeap);
} // RelSequence::copyTopNode


// RelSequence::addLocalExpr() -----------------------------------------------
// Insert into a list of expressions all the expressions of this node and
// all nodes below this node in the derivation chain. Insert into a list of
// names, all the names of the expressions of this node and all nodes below
// this node in the derivation chain. This method is used by the GUI tool
// and by the Explain Function to have a common method to get all the
// expressions associated with a node.
//
// Inputs/Outputs: xlist - a list of expressions.
//                 llist - a list of names of expressions.
//
// The xlist contains a list of all the expressions associated with this
// node. The llist contains the names of these expressions. (This lists
// must be kept in the same order).
// RelSequence::addLocalExpr potentially adds the requiredOrder_ expression
// ("required_order") and the sequenceFunctions_ ("sequence_functions")
//
// It then calls RelExpr::addLocalExpr() which will add any RelExpr
// expressions to the list.
//
void RelSequence::addLocalExpr(LIST(ExprNode *) &xlist,
                               LIST(NAString) &llist) const
{

  if (requiredOrderTree_) {
    xlist.insert(requiredOrderTree_);
    llist.insert("required_order");
  } else if (requiredOrder().entries() > 0) {
    xlist.insert(requiredOrder().rebuildExprTree(ITM_ITEM_LIST));
    llist.insert("required_order");
  }

  if (partitionBy_) {
    xlist.insert(partitionBy_);
    llist.insert("partition_by");
  } else if (partition().entries() > 0) {
    xlist.insert(partition().rebuildExprTree(ITM_ITEM_LIST));
    llist.insert("partition_by");
  }


  if (sequenceFunctions().entries() > 0) {
    xlist.insert(sequenceFunctions().rebuildExprTree(ITM_ITEM_LIST));
    llist.insert("read_functions");
  }

  if (returnSeqFunctions().entries() > 0) {
    xlist.insert(returnSeqFunctions().rebuildExprTree(ITM_ITEM_LIST));
    llist.insert("return_functions");
  }
  if (sequencedColumns().entries() > 0) {
    xlist.insert(sequencedColumns().rebuildExprTree(ITM_ITEM_LIST));
    llist.insert("sequenced_columns");
  }
  if (movePartIdsExpr().entries() > 0) {
    xlist.insert(movePartIdsExpr().rebuildExprTree(ITM_ITEM_LIST));
    llist.insert("move_partition");
  }

  if (cancelExpr().entries() > 0) {
    xlist.insert(cancelExpr().rebuildExprTree(ITM_ITEM_LIST));
    llist.insert("cancel_expression");
  }

  
  if (checkPartitionChangeExpr_.entries() > 0) 
  {
    xlist.insert(checkPartitionChangeExpr_.rebuildExprTree(ITM_ITEM_LIST));
    llist.insert("olap_partition_change");
  }

  RelExpr::addLocalExpr(xlist,llist);
} // RelSequence::addLocalExpr

// RelSequence::getPotentialOutputValues() ---------------------------------
// Construct a Set of the potential outputs of this node.
//
// Inputs: none (other than 'this')
//
// Outputs: outputValues - a ValueIdSet representing the potential outputs
//          of this node.
//
// The potential outputs for the RelSequence node are the sequenced columns
// generated by the RelSequence node. 
//
void
RelSequence::getPotentialOutputValues(ValueIdSet & outputValues) const
{
  // Make sure the ValueIdSet is empty.
  //
  outputValues.clear();

  outputValues += sequencedColumns();

  // Add the values generated by the RelSequence node.
  //
  outputValues += sequenceFunctions();

  // Add the cancel expression.
  //
  outputValues.insertList(cancelExpr());

} // RelSequence::getPotentialOutputValues()


// The destructor
//
PhysSequence::~PhysSequence()
{
}

// PhysSequence::copyTopNode ----------------------------------------------
// Copy a chain of derived nodes (Calls RelSequence::copyTopNode).
// Needs to copy all relevant fields.
// Used by the Cascades engine.
//
// Inputs: derivedNode - If Non-NULL this should point to a node
//         which is derived from this node.  If NULL, then this
//         node is the top of the derivation chain and a node must
//         be constructed.
//
// Outputs: RelExpr * - A Copy of this node.
//
// If the 'derivedNode is non-NULL, then this method is being called
// from a copyTopNode method on a class derived from this one. If it
// is NULL, then this is the top of the derivation chain and a RelSequence
// node must be constructed.
// 
// In either case, the relevant data members must be copied to 'derivedNode'
// and 'derivedNode' is passed to the copyTopNode method of the class
// below this one in the derivation chain (RelSequence::copyTopNode() in this
// case).
// 
RelExpr *
PhysSequence::copyTopNode(RelExpr *derivedNode, CollHeap *outHeap)
{
  PhysSequence *result;

  if (derivedNode == NULL)
    // This is the top of the derivation chain
    // Generate an empty PhysSequence node.
    //
    result = new (outHeap) PhysSequence();
  else
    // A node has already been constructed as a derived class.
    //
    result = (PhysSequence *) derivedNode;

  // PhysSequence has no data members.

  // Copy any data members from the classes lower in the derivation chain.
  //
  return RelSequence::copyTopNode(result, outHeap);
} // PhysSequence::copyTopNode

// RelSequence::transformNode() -------------------------------------------
// Unconditional query transformations such as the transformation of
// a subquery to a semijoin are implemented by the virtual function
// transformNode(). The aim of such transformations is to bring the
// query tree to a canonical form. transformNode() also ensures
// that the "required" (or characteristic) input values are "minimal"
// and the "required" (or characteristic) outputs values are
// "maximal" for each operator.
//
// transformNode() is an overloaded name, which is used for a set
// of methods that implement the transformation phase of query
// normalization.
//
// We use the term query tree for a tree of relational operators,
// each of which can contain none or more scalar expression trees.
// The transformations performed by transformNode() brings scalar
// expressions into a canonical form. The effect of most such
// transformations is local to the scalar expression tree.
// However, the transformation of a subquery requires a semijoin
// to be performed between the relational operator that contains
// the subquery and the query tree for the subquery. The effect
// of such a subquery transformation is therefore visible not
// only in the scalar expression tree but also in the relational
// expression tree.
//
// Parameters:
//
// NormWA & normWARef
//    IN : a pointer to the normalizer work area
//
// ExprGroupId & locationOfPointerToMe
//    IN : a reference to the location that contains a pointer to
//         the RelExpr that is currently being processed.
//
void RelSequence::transformNode(NormWA &normWARef,
                                ExprGroupId &locationOfPointerToMe)
{
  CMPASSERT( this == locationOfPointerToMe );

  // If this node has already been transformed, we are done.
  //
  if (nodeIsTransformed())
    return;
  
  // Make sure that it is only transformed once.
  //
  markAsTransformed();

  // transformNode takes up a bound tree and turns into a transformed
  // tree. For a RelExpr that means the following.
  //    + expressions are transformed. If the expressions contain
  //        subqueries then new RelExpr are created for them and
  //        they are usually added above (as an ancestor) of the node
  //        that contained them.
  //    + predicates are pulled up from the children and their
  //        required inputs are modified
  //    + the required inputs of the node the node itself are changed
  //        from being a sufficient set to being a sufficient minimal
  //        set.
  //
  // Transform the child.
  // Pull up their transformed predicates
  // recompute their required inputs.
  //
  child(0)->transformNode(normWARef, child(0)); 

  if(requiredOrder().
     transformNode(normWARef,
                   child(0),
                   getGroupAttr()->getCharacteristicInputs())) {

    // The requiredOrder list apparently had some subqueries that had
    // not been processed before (is this possible?). Normalize the
    // new tree that has become our child.
    //
    child(0)->transformNode(normWARef, child(0));
  }
  
  if(partition().
     transformNode(normWARef,
                   child(0),
                   getGroupAttr()->getCharacteristicInputs())) {

    // The partition list apparently had some subqueries that had
    // not been processed before (is this possible?). Normalize the
    // new tree that has become our child.
    //
    child(0)->transformNode(normWARef, child(0));
  }
  
  if (CmpCommon::getDefault(COMP_BOOL_201) == DF_ON){
    normWARef.resetSeqFunctionsCache();
  }


  if(sequenceFunctions().
     transformNode(normWARef,
                   child(0),
                   getGroupAttr()->getCharacteristicInputs())) {

    // The sequenceFunctions apparently had some subqueries that had not
    // been processed before (is this possible?). Normalize the new
    // tree that has become our child.
    //
    child(0)->transformNode(normWARef, child(0));
  }
/*
  Note: This code resulted in an internal error when TD RANK code was added. 
  if (CmpCommon::getDefault(COMP_BOOL_200) == DF_ON){
    
    normWARef.resetAllSeqFunctions();
    for(ValueId seqId = sequenceFunctions().init(); sequenceFunctions().next(seqId); 
        sequenceFunctions().advance(seqId) ){
      ItemExpr * ie;
      ie = seqId.getItemExpr();
      normWARef.optimizeSeqFunctions( ie, NULL, 0 );
    }
    
  }*/



  if(sequencedColumns().
     transformNode(normWARef,
                   child(0),
                   getGroupAttr()->getCharacteristicInputs())) {

    // The sequencedColumns apparently had some subqueries that had not
    // been processed before (is this possible?). Normalize the new
    // tree that has become our child.
    //
    child(0)->transformNode(normWARef, child(0));
  }

  if(cancelExpr().
     transformNode(normWARef,
                   child(0),
                   getGroupAttr()->getCharacteristicInputs())) {

    // The cancelExpr apparently had some subqueries that had not
    // been processed before (is this possible?). Normalize the new
    // tree that has become our child.
    //
    child(0)->transformNode(normWARef, child(0));
  }

  // Pull up the predicates and recompute the required inputs
  // of whoever my children are now.
  //
  pullUpPreds();

  // transform the selection predicates
  //
  transformSelectPred(normWARef, locationOfPointerToMe);

} // RelSequence::transformNode()

// RelSequence::rewriteNode() ---------------------------------------------
// rewriteNode() is the virtual function that computes
// the transitive closure for "=" predicates and rewrites value
// expressions.
//
// Parameters:
//
// NormWA & normWARef
//    IN : a pointer to the normalizer work area
//
void RelSequence::rewriteNode(NormWA & normWARef)
{
  RelExpr::rewriteNode(normWARef);

  if(requiredOrder().normalizeNode(normWARef)) {
  }

  if(partition().normalizeNode(normWARef)) {
  }

  if(sequenceFunctions().normalizeNode(normWARef)) {
  }

  if(sequencedColumns().normalizeNode(normWARef)) {
  }

  if(cancelExpr().normalizeNode(normWARef)) {
  }

} // RelSequence::rewriteNode()

// RelSequence::pullUpPreds() --------------------------------------------
// is redefined to disallow the pullup of most predicates from the
// operator's child.  RelSequence can not pull up any predicates from
// its child since this will change the semantics of the sequence
// functions.  The exception is that predicates which consist entirely
// of outer references (are covered by the inputs) can (and must) be
// pulled up.  The reason that these predicates can be pulled up is
// that these types of predicates will either be TRUE for all rows and
// therefore have no affect on the result, or will be FALSE for all
// rows and the sequence will not produce any rows (so when the pred
// is pulled up, the request will not even get to sequence). The
// reason that these predicates must be pulled up is because if these
// preds become VEGPreds, they will not be handled properly if they
// cannot be pulled up and pushed to their source (see Genesis case:
// 10-070111-6157)
//
void
RelSequence::pullUpPreds()
{
  // ---------------------------------------------------------------------
  // Pull up predicates from the child.
  // move them to my selection predicates
  // ---------------------------------------------------------------------

  // Only predicates that reference only input values can be pulled
  // up.
  ValueIdSet availableInputs = getGroupAttr()->getCharacteristicInputs();

  ValueIdSet predicatesToPullUp;
  ValueIdSet notUsed;
  ValueIdSet predicatesThatStay;

  GroupAttributes emptyGA;

  // Find the set of predicates on the child which are covered by the inputs
  // These predicates can be pulled up above the Sequence operator
  //
  emptyGA.coverTest(child(0)->selectionPred(),
                    availableInputs,
                    predicatesToPullUp,
                    notUsed,
                    &predicatesThatStay);

  // If there are some predicates that can be pulled, then remove them
  // from the child and add them to my selection predicates
  //
  if (NOT predicatesToPullUp.isEmpty())
    {
      selectionPred() += predicatesToPullUp;
      child(0)->selectionPred() -= predicatesToPullUp;
    }



  // ---------------------------------------------------------------------
  // WARNING: One rule that this procedure must follow is
  // that recomputeOuterReferences() must be called on the children even
  // if no predicates are pulled up from them. This is to correct
  // the outer references that are added to a right child of a
  // semi or outer join when processing subqueries in the ON clause.
  // ---------------------------------------------------------------------
  child(0)->recomputeOuterReferences();


} // RelSequence::pullUpPreds()


// RelSequence::recomputeOuterReferences() --------------------------------
// This method is used by the normalizer for recomputing the
// outer references (external dataflow input values) that are
// still referenced by each operator in the subquery tree
// after the predicate pull up is complete.
//
// Side Effects: sets the characteristicInputs of the groupAttr.
//
void RelSequence::recomputeOuterReferences()
{
  // This is virtual method on RelExpr.  When this is called it is
  // assumed that the children have already been transformed.  The
  // required inputs of the child are therefore already minimal and
  // sufficient.  It is also assumed that the RelExpr itself has been
  // bound.  That implies that the group attributes have already been
  // allocated and the required inputs is a sufficient (but not
  // necessarilly minimum) set of external values needed to evaluate
  // all expressions in this subtree.
  // 
  // Delete all those input values that are no longer referenced on
  // this operator because the predicates that reference them have 
  // been pulled up.
  //
  ValueIdSet outerRefs = getGroupAttr()->getCharacteristicInputs(); 

  // The set of valueIds need by this node.
  //
  ValueIdSet allMyExpr(getSelectionPred());

  allMyExpr.insertList(requiredOrder());
  allMyExpr.insertList(partition());

  allMyExpr += sequenceFunctions();

  allMyExpr += sequencedColumns();

  allMyExpr.insertList(cancelExpr());
  
  // Remove from outerRefs those valueIds that are not needed
  // by all my expressions
  //
  allMyExpr.weedOutUnreferenced(outerRefs);

  // Add to outerRefs those that my children need.
  //
  outerRefs += child(0).getPtr()->getGroupAttr()->getCharacteristicInputs();

  // set my Character Inputs to this new minimal set.
  //
  getGroupAttr()->setCharacteristicInputs(outerRefs);
} // RelSequence::recomputeOuterReferences()  


// RelSequence::synthEstLogProp() ------------------------------------------
// synthesize estimated logical properties given a specific set of
// input log. properties.
//
// Parameters:
//
// EstLogPropSharedPtr inputEstLogProp
//    IN : A set of input logical properties used to estimate the logical
//         properities of this node.
//
void RelSequence::synthEstLogProp(const EstLogPropSharedPtr& inputEstLogProp)
{
  if (getGroupAttr()->isPropSynthesized(inputEstLogProp) == TRUE) 
    return;

  // Get the estimated logical properties of the child. To be used
  // to estimate the logical properties of this node.
  //
  EstLogPropSharedPtr childEstProp  = child(0).outputLogProp(inputEstLogProp);

  EstLogPropSharedPtr myEstProps =
    synthEstLogPropForUnaryLeafOp(inputEstLogProp,
                                  childEstProp->getColStats(),
                                  childEstProp->getResultCardinality());

  // Set the logical properties of this node.
  //
  getGroupAttr()->addInputOutputLogProp(inputEstLogProp, myEstProps);
  
} // RelSequence::synthEstLogProp


// RelSequence::synthLogProp ----------------------------------------------
// synthesize logical properties
//
void
RelSequence::synthLogProp(NormWA * normWAPtr)
{
  // check to see whether properties are already synthesized.
  //
  if (getGroupAttr()->existsLogExprForSynthesis()) 
    return;

  // Synthesize log. properties for me and my children.
  //
  RelExpr::synthLogProp(normWAPtr);

  ValueIdSet nonRIConstraints;
  for (ValueId x= child(0).getGroupAttr()->getConstraints().init();
       child(0).getGroupAttr()->getConstraints().next(x);
       child(0).getGroupAttr()->getConstraints().advance(x) )
    {
      if ((x.getItemExpr()->getOperatorType() != ITM_COMP_REF_OPT_CONSTRAINT) &&
	  (x.getItemExpr()->getOperatorType() != ITM_REF_OPT_CONSTRAINT))
	  nonRIConstraints += x;
    }
  getGroupAttr()->addConstraints(nonRIConstraints);
  getGroupAttr()->addSuitableRefOptConstraints
  (child(0).getGroupAttr()->getConstraints());

} // RelSequence::synthLogProp()


// RelSequence::costMethod()
// Obtain a pointer to a CostMethod object providing access
// to the cost estimation functions for nodes of this type.
CostMethod*
PhysSequence::costMethod() const
{
  static THREAD_P CostMethodRelSequence *m = NULL;
  if (m == NULL)
    m = new (GetCliGlobals()->exCollHeap())  CostMethodRelSequence();
  return m;

} // PhysSequence::costMethod()


ValueIdList
RelSequence::mapSortKey(const ValueIdList &sortKey) const
{

  ValueIdMap seqColsMap;

  for(ValueId sequenceCol = sequencedColumns().init();
      sequencedColumns().next(sequenceCol);
      sequencedColumns().advance(sequenceCol)) {

    CMPASSERT(sequenceCol.getItemExpr()->getOperatorType() == ITM_NOTCOVERED);

      seqColsMap.addMapEntry(sequenceCol, 
                             sequenceCol.getItemExpr()->child(0)->getValueId());
    }
  
  ValueIdList newSortKey;
  
  seqColsMap.mapValueIdListUp(newSortKey, sortKey);
  
  return newSortKey;
}

PhysicalProperty *
PhysSequence::synthPhysicalProperty(const Context *context,
                                    const Lng32   pn,
                                    PlanWorkSpace *pws)
{

  // Call the default implementation
  // (RelExpr::synthPhysicalProperty()) to synthesize the properties
  // on the number of cpus.
  // 
  PhysicalProperty* sppTemp = RelExpr::synthPhysicalProperty(context,pn,pws);

  const PhysicalProperty * const sppOfChild =
    context->getPhysicalPropertyOfSolutionForChild(0);

  // ---------------------------------------------------------------------
  // Replace the sort key in my spp.
  // ---------------------------------------------------------------------
  PhysicalProperty* sequencePP =
    new (CmpCommon::statementHeap())
    PhysicalProperty(*sppOfChild,
                     mapSortKey(sppOfChild->getSortKey()),
                     sppOfChild->getSortOrderType(),
                     sppOfChild->getDp2SortOrderPartFunc());

  sequencePP->setCurrentCountOfCPUs(sppTemp->getCurrentCountOfCPUs());
  delete sppTemp;

  return sequencePP;
} //  RelSequence::synthPhysicalProperty() 


void
RelSequence::pushdownCoveredExpr(const ValueIdSet & outputExpr,
                                 const ValueIdSet & newExternalInputs,
                                 ValueIdSet & predicatesOnParent,
				 const ValueIdSet * setOfValuesReqdByParent,
                                 Lng32 childIndex
		                 )
{

  ValueIdSet exprOnParent;
  if(setOfValuesReqdByParent)
    exprOnParent = *setOfValuesReqdByParent;
  exprOnParent += sequenceFunctions();
  exprOnParent.insertList(requiredOrder());
  exprOnParent.insertList(partition());
  ValueIdSet outputSet(outputExpr);

  // Prune from the sequencedColumns() ValueIdSet, those expressions
  // that are not needed above (in setOfValuesReqdByParent) or by
  // the selectionPred.
  //
  ValueId refVal;
  for(ValueId seqCol = sequencedColumns().init(); 
      sequencedColumns().next(seqCol);
      sequencedColumns().advance(seqCol)) {

    if(!exprOnParent.referencesTheGivenValue(seqCol, refVal) &&
       !selectionPred().referencesTheGivenValue(seqCol, refVal) &&
       !outputSet.referencesTheGivenValue(seqCol, refVal)) {
      sequencedColumns() -= seqCol;
    }
  }
  
  exprOnParent += sequencedColumns();

  RelExpr::pushdownCoveredExpr(outputSet,
                               newExternalInputs,
                               predicatesOnParent,
			       &exprOnParent,
                               childIndex
                               );

  // predicatesOnParent has not been changed.
  //

} // RelSequence::pushdownCoveredExpr

Context* RelSequence::createContextForAChild(Context* myContext,
                                             PlanWorkSpace* pws,
                                             Lng32& childIndex)
{
  // ---------------------------------------------------------------------
  // If one Context has been generated for each child, return NULL 
  // to signal completion.
  // ---------------------------------------------------------------------
  if (pws->getCountOfChildContexts() == getArity())
    return NULL;

  childIndex = 0;

  Lng32 planNumber = 0;
  const ReqdPhysicalProperty* rppForMe = myContext->getReqdPhysicalProperty();
  PartitioningRequirement* partReqForMe = 
    rppForMe->getPartitioningRequirement();

  // If a partitioning requirement exists and it requires broadcast
  // replication, then return NULL now. Only an exchange operator
  // can satisfy a broadcast replication partitioning requirement.
  if ((partReqForMe != NULL) AND
      partReqForMe->isRequirementReplicateViaBroadcast())
    return NULL;

  RequirementGenerator rg(child(0),rppForMe);

  // ---------------------------------------------------------------------
  // Add the order requirements needed for this RelSequence node
  // ---------------------------------------------------------------------

  // Remove any sort order requirement from parent.
  //
  rg.removeSortKey();
  rg.removeArrangement();
  rg.removeSortOrderTypeReq();

  ValueIdList sortKey;

  // Note for Bob W.
  // Look into whether requiredOrder() can be used the same way for OLAP
  // and TD Rank so this special case can be eliminated.  
  if( !getHasTDFunctions() )
  {
    sortKey.insert(partition());
  }  

  sortKey.insert(requiredOrder());

  // Shouldn't/Can't add a sort order type requirement
  // if we are in DP2
  if (rppForMe->executeInDP2())
    rg.addSortKey(sortKey,NO_SOT);
  else
    rg.addSortKey(sortKey,ESP_SOT);

  // Cannot execute in DP2
  //
  rg.addLocationRequirement(EXECUTE_IN_MASTER_OR_ESP);

  Lng32 childNumPartsRequirement = ANY_NUMBER_OF_PARTITIONS;
  float childNumPartsAllowedDeviation = 0.0;
  NABoolean numOfESPsForced = FALSE;

  if(okToAttemptESPParallelism(myContext,
                               pws,
                               childNumPartsRequirement,
                               childNumPartsAllowedDeviation,
                               numOfESPsForced) AND
     (partition().entries() > 0)) {

    rg.addPartitioningKey(partition());

    if (NOT numOfESPsForced)
      rg.makeNumOfPartsFeasible(childNumPartsRequirement,
                                &childNumPartsAllowedDeviation);
    rg.addNumOfPartitions(childNumPartsRequirement,
                          childNumPartsAllowedDeviation);
  } else {
    
    // Cannot execute in parallel
    //
    rg.addNumOfPartitions(1);
  }


  // ---------------------------------------------------------------------
  // Done adding all the requirements together, now see whether it worked
  // and give up if it is not possible to satisfy them
  // ---------------------------------------------------------------------
  if (NOT rg.checkFeasibility())
    return NULL;

  // ---------------------------------------------------------------------
  // Compute the cost limit to be applied to the child.
  // ---------------------------------------------------------------------
  CostLimit* costLimit = computeCostLimit(myContext, pws);
  
  // ---------------------------------------------------------------------
  // Get a Context for optimizing the child.
  // Search for an existing Context in the CascadesGroup to which the
  // child belongs that requires the same properties as those in 
  // rppForChild. Reuse it, if found. Otherwise, create a new Context
  // that contains rppForChild as the required physical properties..
  // ---------------------------------------------------------------------
  Context* result = shareContext(
         childIndex,
	 rg.produceRequirement(),
         myContext->getInputPhysicalProperty(),
	 costLimit, 
	 myContext,
	 myContext->getInputLogProp());

  // ---------------------------------------------------------------------
  // Store the Context for the child in the PlanWorkSpace.
  // ---------------------------------------------------------------------
  pws->storeChildContext(childIndex, planNumber, result);

  return result;
  
} // RelSequence::createContextForAChild()

// Helper routine for reporting errors with sequence functions. Called
// by RelRoot::bindNode().
//
static NABoolean checkUnresolvedSequenceFunctions(BindWA *bindWA)
{
  ValueIdSet &seqs = 
    bindWA->getCurrentScope()->getUnresolvedSequenceFunctions();

  if (seqs.isEmpty()) 
    return FALSE;			// no error

  NAString unparsed(CmpCommon::statementHeap());
  for (ValueId vid = seqs.init(); seqs.next(vid); seqs.advance(vid)) {

    ItemExpr *ie = vid.getItemExpr();

    unparsed += ", ";
    ie->unparse(unparsed, DEFAULT_PHASE, USER_FORMAT_DELUXE);
  }
  unparsed.remove(0,2);					// remove initial ", "

  // 4109 Sequence functions placed incorrectly.
  *CmpCommon::diags() << DgSqlCode(-4109) << DgString0(unparsed);
  bindWA->setErrStatus();
  return TRUE;
} // checkUnresolvedSequenceFunctions()

// RelSequence::bindNode - Bind the RelSequence node.
//
RelExpr *RelSequence::bindNode(BindWA *bindWA)
{
  
  // If this node has already been bound, we are done.
  //
  if (nodeIsBound())
    return this;

  CMPASSERT(!bindWA->getCurrentScope()->getSequenceNode());

  bindWA->getCurrentScope()->getSequenceNode()= this;

  // Add sequence functions found in parent node(s)
  //
  sequenceFunctions() += 
    bindWA->getCurrentScope()->getUnresolvedSequenceFunctions();

  bindWA->getCurrentScope()->getUnresolvedSequenceFunctions().clear();
  bindWA->getCurrentScope()->getAllSequenceFunctions().clear();
  
  // Bind the child nodes.
  //
  bindChildren(bindWA);
  if (bindWA->errStatus())
    return this;

  ItemExpr * partitionChange =NULL;
  ValueIdList change;
  if(partitionBy_) {
    partitionChange = partitionBy_->copyTree(bindWA->getCurrentScope()->collHeap());    
    bindWA->getCurrentScope()->context()->inOrderBy() = TRUE;
    partitionBy_->convertToValueIdList(partition(),
                                       bindWA,
                                       ITM_ITEM_LIST);
    bindWA->getCurrentScope()->context()->inOrderBy() = FALSE;
    if(bindWA->errStatus())
      return this;

    partitionBy_ = NULL;
  }

  ItemExpr *requiredOrderTree = removeRequiredOrderTree();
  
  if(requiredOrderTree) {
    bindWA->getCurrentScope()->context()->inOrderBy() = TRUE;
    requiredOrderTree->convertToValueIdList(requiredOrder(),
                                            bindWA,
                                            ITM_ITEM_LIST);
    bindWA->getCurrentScope()->context()->inOrderBy() = FALSE;

/*
    //
    // Next, we enforce the restriction that no CZECH collation
    // is involved in any of the SEQUENCE BY columns/expressions.
    //
    for (CollIndex i = 0; i < requiredOrder().entries(); i++)
    {
        ValueId ValId        = requiredOrder()[i];
        NABuiltInTypeEnum TQ = ValId.getType().getTypeQualifier();

        if ( TQ == NA_CHARACTER_TYPE)
        {
            const CharType& ColumnCT = (const CharType&)ValId.getType();
            if ( ColumnCT.getCollation() == CharInfo::CZECH_COLLATION )
            {
                *CmpCommon::diags() << DgSqlCode(-4380)
                    << DgString0(ColumnCT.getCollationName());
                bindWA->setErrStatus();
            }
        }
    }
*/

    if(bindWA->errStatus())
      return this;
  }
  
  
  

  // if unresolved sequence functions have been found in the children
  // of the Sequence node or in the requiredOrderTree, that would mean
  // that we are referencing sequence functions before the sequence
  // operation is performed If this is the case, the following method
  // will issue the error.
  //
  if (checkUnresolvedSequenceFunctions(bindWA))
    return this;

  // Construct the RETDesc for this node.
  //
  RETDesc *resultTable = new(bindWA->wHeap()) RETDesc(bindWA);
  
  // Add the columns from the child to the RETDesc.
  // 
  const RETDesc &childTable = *child(0)->getRETDesc();

  if(childTable.isGrouped())
    resultTable->setGroupedFlag();
  
  const ColumnDescList *sysColList = childTable.getSystemColumnList();
  const ColumnDescList *colList = childTable.getColumnList();
  
  CollIndex i = 0;
  for(i = 0; i < sysColList->entries(); i++) 
  {
    ValueId columnValueId = sysColList->at(i)->getValueId();
    ItemExpr *newColumn = new (bindWA->wHeap()) 
      NotCovered (columnValueId.getItemExpr());
    newColumn->synthTypeAndValueId();
    
    resultTable->addColumn(bindWA,
      sysColList->at(i)->getColRefNameObj(),
      newColumn->getValueId(),
      SYSTEM_COLUMN,
      sysColList->at(i)->getHeading());

    if(sysColList->at(i)->isGrouped()) {
      ColumnNameMap *cnm =
        resultTable->findColumn(sysColList->at(i)->getColRefNameObj());
      cnm->getColumnDesc()->setGroupedFlag();
    }

    sequencedColumns() += newColumn->getValueId();
  }
  ValueIdMap ncToOldMap;
  for(i = 0; i < colList->entries(); i++) 
  {
    ValueId columnValueId = colList->at(i)->getValueId();
    ItemExpr *newColumn = new (bindWA->wHeap()) 
      NotCovered (columnValueId.getItemExpr());
    newColumn->synthTypeAndValueId();
    newColumn->setOrigOpType(columnValueId.getItemExpr()->origOpType());
    
    resultTable->addColumn(bindWA,
      colList->at(i)->getColRefNameObj(),
      newColumn->getValueId(),
      USER_COLUMN,
      colList->at(i)->getHeading());
    ncToOldMap.addMapEntry(newColumn->getValueId(),columnValueId);
    if(colList->at(i)->isGrouped()) {
      ColumnNameMap *cnm =
        resultTable->findColumn(colList->at(i)->getColRefNameObj());
      cnm->getColumnDesc()->setGroupedFlag();
    }

    sequencedColumns() += newColumn->getValueId();
  }
  
  // Set the return descriptor
  //
  setRETDesc(resultTable);
  bindWA->getCurrentScope()->setRETDesc(resultTable);

  //bindWA->getCurrentScope()->getSequenceNode() = this;
  if (!bindWA->getCurrentScope()->context()->inUpsertXform())
    {
      if(partitionChange) {
        partitionChange->convertToValueIdList(partitionChange_, bindWA, ITM_ITEM_LIST);
      }
    
    if(bindWA->errStatus())
      return this;
  
    partitionChange = NULL;

   /// bindWA->getCurrentScope()->setTDPartitionChange(change);
  }
  // -- MV
  // Bind the cancel expression.
  //
  if (cancelExprTree_)
  {
    cancelExprTree_->convertToValueIdList(cancelExpr(), bindWA, ITM_ITEM_LIST);
    cancelExprTree_ = NULL;
    if (bindWA->errStatus()) {
      delete resultTable;
      return NULL;
    }
  }

  //
  // bind the qualify predicates and attach the resulting value id set
  // to the node (as a selection predicate on the sequence node)
  //
  ItemExpr *qualifyPred = removeSelPredTree();
  if (qualifyPred) {
	  bindWA->getCurrentScope()->context()->inQualifyClause() = TRUE;
	  qualifyPred->convertToValueIdSet(selectionPred(), bindWA, ITM_AND);
	  bindWA->getCurrentScope()->context()->inQualifyClause() = FALSE;
	  if (bindWA->errStatus()) return this;
  }


  bindWA->getCurrentScope()->getSequenceNode() = NULL;

  //
  // Bind the base class.
  //
  RelExpr *boundExpr = bindSelf(bindWA);
  if (bindWA->errStatus())
    return boundExpr;

  // Register this node in current scope.  Later (in
  // RelRoot::bindNode()), the unresolved sequence functions will be
  // attached to this registered node.
  //
  //CMPASSERT(!bindWA->getCurrentScope()->getSequenceNode());

  bindWA->getCurrentScope()->getSequenceNode() = boundExpr;
  // save the ncToOldmap in the current scope. It will be used in Insert::bindnode for a special case.
  bindWA->getCurrentScope()->setNCToOldMap( ncToOldMap);
  return boundExpr;

} // RelSequence::bindNode()

NABoolean PhysSequence::isBigMemoryOperator(const Context* context,  
                                            const Lng32 planNumber)
{
  const double memoryLimitPerCPU = CURRSTMT_OPTDEFAULTS->getMemoryLimitPerCPU();

  // The Sequence operator allocates the history buffer in memory.
  //

  const ReqdPhysicalProperty* rppForMe = context->getReqdPhysicalProperty();
  // Start off assuming that the sort will use all available CPUs.
  Lng32 cpuCount = rppForMe->getCountOfAvailableCPUs();
  PartitioningRequirement* partReq = rppForMe->getPartitioningRequirement();
  const PhysicalProperty* spp = context->getPlan()->getPhysicalProperty();
  Lng32 numOfStreams;  

  // If the physical properties are available, then this means we 
  // are on the way back up the tree. Get the actual level of 
  // parallelism from the spp to determine if the number of cpus we 
  // are using are less than the maximum number available.
  if (spp != NULL)
  {
    PartitioningFunction* partFunc = spp->getPartitioningFunction();
    numOfStreams = partFunc->getCountOfPartitions();
    if (numOfStreams < cpuCount)
      cpuCount = numOfStreams;
  }
  else
  if ((partReq != NULL) AND
      (partReq->getCountOfPartitions() != ANY_NUMBER_OF_PARTITIONS))
  {
    // If there is a partitioning requirement, then this may limit
    // the number of CPUs that can be used.
    numOfStreams = partReq->getCountOfPartitions();
    if (numOfStreams < cpuCount)
      cpuCount = numOfStreams;
  }

  EstLogPropSharedPtr inLogProp = context->getInputLogProp();

  const double probeCount =
    MIN_ONE(inLogProp->getResultCardinality().value());

  CMPASSERT ( numHistoryRows() > 0 &&
	      getEstHistoryRowLength() > 0);

  const double historyBufferRowCount = MIN_ONE(numHistoryRows());

  const double rowsPerCpu = MIN_ONE(historyBufferRowCount / cpuCount);
  const double rowsPerCpuPerProbe = MIN_ONE(rowsPerCpu / probeCount);

  const Lng32 bufferWidth = estHistoryRowLength_;
  const double bufferSizePerCpu = (rowsPerCpuPerProbe / 1024. * bufferWidth);

  return (bufferSizePerCpu >= memoryLimitPerCPU);

} // PhysSequence::isBigMemoryOperator


// addUnResolvedSeqFunctions - Add unresolved sequence functions to
// the RelSequence operator found when binding the select list.  Also,
// if OLAP, bind the partition by and order by clauses and add to
// RelSequence.
//
void RelSequence::addUnResolvedSeqFunctions(ValueIdSet &unresolvedSeqFuncs,
                                            BindWA *bindWA)
{ 
  // Add the unresolved sequence functions to this RelSequence
  //
  sequenceFunctions_ += unresolvedSeqFuncs; 

  if(sequenceFunctions_.entries()) {

    if (CmpCommon::getDefault(OLAP_CAN_INVERSE_ORDER) == DF_ON)
    {
      NABoolean mustInv = FALSE;
      NABoolean canInv = TRUE;

      Lng32 precedingMax = 0;
      Lng32 followingMax = 0;

      for(ValueId sfId = sequenceFunctions_.init();
          sequenceFunctions_.next(sfId); sequenceFunctions_.advance(sfId)) 
        {
          ItmSequenceFunction * sf = (ItmSequenceFunction *)(sfId.getItemExpr());
          if(!sf->isOLAP()) 
          {
            canInv = FALSE;
            continue;
          }
          ItmSeqOlapFunction *olapF = (ItmSeqOlapFunction *)sf;
          precedingMax = MAXOF(precedingMax, -(olapF->getframeStart()));
          followingMax = MAXOF(followingMax, olapF->getframeEnd());
          
          if(!olapF->canInverseOLAPOrder()) {
            canInv = FALSE;
            continue;
          }
          if(olapF->mustInverseOLAPOrder()) {
            mustInv = TRUE;
          }
        }

      NABoolean shouldInv = (canInv && (followingMax > precedingMax));

      if((mustInv && canInv) || shouldInv) {
        for(ValueId sfId = sequenceFunctions_.init();
            sequenceFunctions_.next(sfId); sequenceFunctions_.advance(sfId)) 
          {
            ItmSeqOlapFunction * olapF = (ItmSeqOlapFunction *)(sfId.getItemExpr());
            olapF->inverseOLAPOrder(bindWA->wHeap());
          }
      } else if(mustInv && !canInv) {
        *CmpCommon::diags() << DgSqlCode(-4349);
        bindWA->setErrStatus();
        return;
      }
    }


    // Get the first sequence function
    //
    ValueId sFunc = sequenceFunctions_.init();
    sequenceFunctions_.next(sFunc);

    ItemExpr *ie = sFunc.getItemExpr();
    CMPASSERT(ie->isASequenceFunction());
    ItmSequenceFunction *seqFunc = (ItmSequenceFunction *)ie;

    // If it is OLAP, the bind the partition by and order by clauses.
    // and attach them to this RelSequence operator.
    //
    if( getHasOlapFunctions() || getHasTDFunctions() ) {

      // only for OLAP.
      // for TD, the partition by is already bound
      if( getHasOlapFunctions() )
      {
        CMPASSERT(partition().entries() == 0);
      }
      CMPASSERT(requiredOrder().entries() == 0);

      ItemExpr * prevSF = NULL;
      for(ValueId sfId = sequenceFunctions_.init();
        sequenceFunctions_.next(sfId); sequenceFunctions_.advance(sfId)) 
      {
        ItemExpr * ie = sfId.getItemExpr();
        CMPASSERT(ie->isASequenceFunction());
        ItmSequenceFunction *sf = (ItmSequenceFunction *)ie;               
        
        if ( 
            (getHasTDFunctions() && !sf->isTDFunction())
             ||
             (getHasOlapFunctions() && !sf->isOLAP())
            )
        {   //Using rank function and sequence functions together 
            //  in the same query scope is not supported.
            *CmpCommon::diags() << DgSqlCode(-4367);
            bindWA->setErrStatus();
            return;
        }
        if ((!getHasOlapFunctions()) && prevSF)
          if (!sf->hasBaseEquivalence(prevSF))
          { //All rank functions need to have the same expression as argument
            *CmpCommon::diags() << DgSqlCode(-4361);
            bindWA->setErrStatus();
            return;
          }
        prevSF = sf;
      }

      // Bind the order by and partition by using the child's
      // RETDesc.
      //
      BindScope *currScope = bindWA->getCurrentScope();

      RETDesc *myRETDesc = getRETDesc();
      RETDesc *currentRETDesc = currScope->getRETDesc();

      setRETDesc(child(0)->getRETDesc());
      currScope->setRETDesc(child(0)->getRETDesc());

      if (getHasOlapFunctions()) {

        ItemExpr *partitionBy = seqFunc->getOlapPartitionBy();

        if(partitionBy) {
          bindWA->getCurrentScope()->context()->inOlapPartitionBy() = TRUE;
          partitionBy->convertToValueIdList(partition(),
                                            bindWA,
                                            ITM_ITEM_LIST);
          bindWA->getCurrentScope()->context()->inOlapPartitionBy() = FALSE;
          if(bindWA->errStatus())
            return;
        }
      }

      ItemExpr *orderBy = seqFunc->getOlapOrderBy();
      if(orderBy) {        
        
        if( seqFunc->isTDFunction() ) { 
          // TBD: Try to do requiredOrder()=partition() somewhere else to
          // make it consistent with OLAP
          requiredOrder()=partition();
          orderBy = orderBy->changeDefaultOrderToDesc();
        }           
        // if for OLAP and there's a double inverse, remove them.
        else if( seqFunc->isOLAP()  ) {
          NABoolean inv = FALSE;
          orderBy = orderBy->removeInverseFromExprTree(inv,TRUE);          
        }


        bindWA->getCurrentScope()->context()->inOrderBy() = TRUE;
        bindWA->getCurrentScope()->context()->inOlapOrderBy() = TRUE;
        orderBy->convertToValueIdList(requiredOrder(),
                                      bindWA,
                                      ITM_ITEM_LIST);
        bindWA->getCurrentScope()->context()->inOrderBy() = FALSE;
        bindWA->getCurrentScope()->context()->inOlapOrderBy() = FALSE;
        if(bindWA->errStatus())
          return;        
        
        // NULLs are in a different order for TD
        if( seqFunc->isTDFunction() ) {

          ValueIdList newOrder;
          ValueId valId;
          for (CollIndex i=0; i<requiredOrder().entries(); i++)
          {
            valId = requiredOrder()[i];
            NAType * type = valId.getType().newCopy();

            if (type->supportsSQLnull())
            {              
              ItemExpr * ie =NULL; 

              if (valId.getItemExpr()->getOperatorType() == ITM_INVERSE)
              {
                 ie = valId.getItemExpr()->removeInverseOrder();
              }
              else
              {
                ie = valId.getItemExpr();
              }
              ItemExpr * constZero = new (bindWA->wHeap()) ConstValue(0);
              ItemExpr * constOne = new (bindWA->wHeap()) ConstValue(1);
              ItemExpr *isnull = new HEAP UnLogic (ITM_IS_NULL, ie);
              ItemExpr *ifthenelse = new (bindWA->wHeap()) IfThenElse(isnull, constZero, constOne);              
              ItemExpr * newExpr =  new (bindWA->wHeap()) Case(NULL, ifthenelse);
              newExpr = new (bindWA->wHeap()) 
                          Cast(newExpr, 
                               ((ConstValue *) constZero)->getType()->newCopy());

              if (valId.getItemExpr()->getOperatorType() == ITM_INVERSE)
              {
                 newExpr = new  (bindWA->wHeap()) InverseOrder( newExpr);
              }
              newExpr->synthTypeAndValueId(TRUE);
              newOrder.insert(newExpr->getValueId());
              newOrder.insert(valId);
            }
            else
            {
              newOrder.insert(valId);
            }            
          }  
          requiredOrder()= newOrder;          
        }
      }

      // Return the RETDescs to their proper values.
      //
      setRETDesc(myRETDesc);
      currScope->setRETDesc(currentRETDesc);
    }    
  }
}

void PhysSequence::setNumHistoryRows(Lng32 numHistoryRows)
{
  numHistoryRows_ = numHistoryRows;
};

void PhysSequence::setUnboundedFollowing(NABoolean v)
{
  unboundedFollowing_ = v;
};

NABoolean PhysSequence::getUnboundedFollowing() const
{
  return unboundedFollowing_;
};
void PhysSequence::setMinFollowingRows(Lng32 v)
{
  minFollowingRows_ = v;
};

void PhysSequence::computeAndSetMinFollowingRows(Lng32 v)
{
  if ( v > minFollowingRows_ )
     minFollowingRows_ = v;
};

Lng32 PhysSequence::getMinFollowingRows() const
{
  return minFollowingRows_;
};


void PhysSequence::estimateHistoryRowLength(const ValueIdSet &sequenceFunctions,
					    const ValueIdSet &outputFromChild,
					    ValueIdSet &histIds,
					    Lng32 &estimatedLength)
{
  ValueIdSet children;

  for(ValueId valId = sequenceFunctions.init();
      sequenceFunctions.next(valId);
      sequenceFunctions.advance(valId)) 
  {
    if(valId.getItemExpr()->isASequenceFunction()) 
    {
      ItemExpr *itmExpr = valId.getItemExpr();

      switch(itmExpr->getOperatorType())
      {
        case ITM_OLAP_LEAD:
        case ITM_OLAP_LAG:
        case ITM_OFFSET:
        case ITM_ROWS_SINCE:
        case ITM_THIS:
        case ITM_NOT_THIS:
          updateEstHistoryRowLength(histIds,
                                    itmExpr->child(0)->getValueId(),
                                    estimatedLength);
	  //estimatedLength +=  itmExpr->child(0)->getValueId().getType().getTotalSize();
          break;
        case ITM_RUNNING_SUM:
        case ITM_RUNNING_COUNT:
        case ITM_RUNNING_MIN:
        case ITM_RUNNING_MAX:
        case ITM_LAST_NOT_NULL:
          updateEstHistoryRowLength(histIds,
                                    itmExpr->getValueId(),
                                    estimatedLength);
          break;
        case ITM_OLAP_SUM:
        case ITM_OLAP_COUNT:
        case ITM_OLAP_RANK:
        case ITM_OLAP_DRANK:
	  {
	    ItemExpr * tmpExpr = 
	      ((ItmSeqOlapFunction *)itmExpr)->transformOlapFunction(
						  CmpCommon::statementHeap());
	    tmpExpr->synthTypeAndValueId(TRUE);
	    CMPASSERT (valId != tmpExpr->getValueId());
	    children += tmpExpr->getValueId();
	  }
          break;
        case ITM_OLAP_MIN:
        case ITM_OLAP_MAX:
	  {
	    if (((ItmSeqOlapFunction *)itmExpr)->getframeStart() < 0 && 
	        ((ItmSeqOlapFunction *)itmExpr)->getframeEnd() >0)
	    {
	      ItemExpr * tmpExpr = 
		((ItmSeqOlapFunction *)itmExpr)->transformOlapFunction(
						    CmpCommon::statementHeap());
	      tmpExpr->synthTypeAndValueId(TRUE);
	      CMPASSERT (valId != tmpExpr->getValueId());
	      children += tmpExpr->getValueId();
	    }
	    else
	    {
              updateEstHistoryRowLength(histIds,
                                    itmExpr->getValueId(),
                                    estimatedLength);

              updateEstHistoryRowLength(histIds,
                                    itmExpr->child(0)->getValueId(),
                                    estimatedLength);
	      //estimatedLength += itmExpr->getValueId().getType().getTotalSize(); //
	      //estimatedLength += itmExpr->child(0)->getValueId().getType().getTotalSize(); //
	    }
	  }
	  break;
        case ITM_MOVING_MIN:
        case ITM_MOVING_MAX:
	  {
            updateEstHistoryRowLength(histIds,
                                    itmExpr->getValueId(),
                                    estimatedLength);

            updateEstHistoryRowLength(histIds,
                                    itmExpr->child(0)->getValueId(),
                                    estimatedLength);
	  //estimatedLength += itmExpr->getValueId().getType().getTotalSize(); //
	  //estimatedLength += itmExpr->child(0)->getValueId().getType().getTotalSize(); //
	  }
          break;
        case ITM_RUNNING_CHANGE:
          if (itmExpr->child(0)->getOperatorType() == ITM_ITEM_LIST)
          {
            ExprValueId treePtr = itmExpr->child(0);
            ItemExprTreeAsList changeValues(&treePtr,
                                            ITM_ITEM_LIST,
                                            RIGHT_LINEAR_TREE);
            CollIndex nc = changeValues.entries();
            for (CollIndex i = nc; i > 0; i--)
            {
              updateEstHistoryRowLength(histIds,
                                     changeValues[i-1]->getValueId(),
                                     estimatedLength);
            }
          }
          else
          {
            updateEstHistoryRowLength(histIds,
                                    itmExpr->child(0)->getValueId(),
                                    estimatedLength);
	      // estimatedLength +=  itmExpr->child(0)->getValueId().getType().getTotalSize();
          }
          updateEstHistoryRowLength(histIds,
                                    itmExpr->getValueId(),
                                    estimatedLength);
          //estimatedLength +=  itmExpr->getValueId().getType().getTotalSize();
          break;

        default:
          CMPASSERT(0);
      }
    }
    // Gather all the children, and if not empty, recurse down to the
    // next level of the tree.
    //
    for(Lng32 i = 0; i < valId.getItemExpr()->getArity(); i++) 
    {
      if (!outputFromChild.contains(valId.getItemExpr()->child(i)->getValueId()))
      {
        children += valId.getItemExpr()->child(i)->getValueId();
      }
    }
  }
  
  if (!children.isEmpty())
  {
    estimateHistoryRowLength(children,
			     outputFromChild,
                             histIds,
			     estimatedLength);
  }

}

void PhysSequence::retrieveCachedHistoryInfo(RelSequence * cacheRelSeq) 
{
  ValueIdSet outputFromChild = child(0).getGroupAttr()->getCharacteristicOutputs();
  

  if (!cacheRelSeq->getHistoryInfoCached())
  {
    Lng32 unableToCalculate = 0;
    Lng32 estimatedRowLength = 0;
    Lng32 numHistoryRows = 0;
    NABoolean unboundedFollowing = 0;
    Lng32 minFollowing = 0;
    ValueIdSet histIds;
    
    estimateHistoryRowLength( sequenceFunctions(),
			      outputFromChild,
                              histIds,
			      estimatedRowLength);
    if (sequencedColumns().entries()>0)
    {
      estimatedRowLength += sequencedColumns().getRowLength();
    }

    if (partition().entries()>0)
    {
      estimatedRowLength += partition().getRowLength();
    }

    estimatedRowLength += sequenceFunctions().getRowLength();

    cacheRelSeq->setCachedHistoryRowLength(estimatedRowLength);

    computeHistoryRows(sequenceFunctions(), 
		       numHistoryRows, 
		       unableToCalculate, 
		       unboundedFollowing, 
		       minFollowing,
		       outputFromChild);

    if(unableToCalculate || numHistoryRows ==0)
    {
      numHistoryRows = getDefault(DEF_MAX_HISTORY_ROWS);
    }

    cacheRelSeq->setCachedNumHistoryRows( numHistoryRows);
    cacheRelSeq->setCachedUnboundedFollowing(unboundedFollowing);
    cacheRelSeq->setCachedMinFollowingRows(minFollowing);
    cacheRelSeq->setHistoryInfoCached(TRUE);
  }
   CMPASSERT(cacheRelSeq->getCachedHistoryRowLength() != 0 &&
             cacheRelSeq->getCachedNumHistoryRows() != 0 &&
             cacheRelSeq->getHistoryInfoCached());

  estHistoryRowLength_ = cacheRelSeq->getCachedHistoryRowLength();
  numHistoryRows_ = cacheRelSeq->getCachedNumHistoryRows();
  unboundedFollowing_ = cacheRelSeq->getCachedUnboundedFollowing();
  minFollowingRows_ = cacheRelSeq->getCachedMinFollowingRows();

}






