text: /**********************************************************************
  // @@@ 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 RELSEQUENCE_H
  #define RELSEQUENCE_H
  /* -*-C++-*-
  ******************************************************************************
  *
  * File:         RelSequence.h
  * Description:  Class definitions for the classes RelSequence
  *               and PhysSequence
  * Created:      6/17/97
  * Language:     C++
  *
  *
  *
  *
  ******************************************************************************
  */
  
  #include "RelExpr.h"
  
  // forward references
  
  class Generator;
  class MapTable;
  class Attributes;
  
  // Class RelSequence
  // --------------------------------------------------------
  
  // The RelSequence RelExpr is the logical RelExpr used to implement the
  // "sequence by clause" and is introduced by the parser.  The physical
  // version of this node is the RelExpr class PhysSequence.  The data
  // members of this class are:
  //
  // ItemExpr *requiredOrderTree_ : An ItemExpr list of columns
  // representing the reqired sort order for this node.  A required sort
  // order is specified withg th sort by clause.
  //
  // ValueIdList requiredOrder_ : The bound version of
  // requiredOrderTree_.
  //
  // ValueIdSet sequenceFunctions_ : A set of all the sequence
  // functions associated with this RelSequence node.  They are gathered
  // and assigned to the RelSequence node during binding.
  //
  class RelSequence : public RelExpr
  {
  public:
  
    // The constructor
    //
  // warning elimination  (removed "inline")
    RelSequence(RelExpr *child = NULL,
                ItemExpr *requiredOrder = NULL,
                CollHeap *oHeap = CmpCommon::statementHeap());
  
    RelSequence(RelExpr *child,
                ItemExpr *partitionBy,
                ItemExpr *orderBy,
                CollHeap *oHeap = CmpCommon::statementHeap());
  
    // The destructor
    //
    virtual ~RelSequence();
  
    // RelSequence has one child.
    //
    virtual Int32 getArity() const {return 1;};
  
    //++MV
    void addRequiredOrderTree(ItemExpr *orderExpr);
  
    // a virtual function for performing name binding within the query tree
    //
    RelExpr * bindNode(BindWA *bindWAPtr);
  
    // Each operator supports a (virtual) method for transforming its
    // scalar expressions to a canonical form
    //
    virtual void transformNode(NormWA & normWARef,
  			     ExprGroupId & locationOfPointerToMe);
  
    // a method used during subquery transformation for pulling up predicates
    // towards the root of the transformed subquery tree
    //
    // RelSequence cannot pull up any preds. so redefine this method.
    //
    virtual void pullUpPreds();
  
    // a method used 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.
    //
    virtual void recomputeOuterReferences();
  
    // Each operator supports a (virtual) method for rewriting its
    // value expressions.
    //
    virtual void rewriteNode(NormWA & normWARef);
  
    // Each operator supports a (virtual) method for performing
    // predicate pushdown and computing a "minimal" set of
    // characteristic input and characteristic output values.
    //
    // The default implementation is adequate for RelSequence
    // virtual RelExpr * normalizeNode(NormWA & normWARef);
  
    // Method to push down predicates from a RelSequence node into the
    // children
    //
    virtual
    void pushdownCoveredExpr(const ValueIdSet & outputExprOnOperator,
                             const ValueIdSet & newExternalInputs,
                             ValueIdSet& predOnOperator,
  			   const ValueIdSet * nonPredExprOnOperator = NULL,
                             Lng32 childId = (-MAX_REL_ARITY) );
  
    // Return a the set of potential output values of this node.
    // For RelSequence, this is the output of the child, plus all
    // the values generated by RelSequence
    //
    virtual void getPotentialOutputValues(ValueIdSet &vs) const;
  
    // add all the expressions that are local to this
    // node to an existing list of expressions (used by GUI tool and Explain)
    //
    virtual void addLocalExpr(LIST(ExprNode *) &xlist,
  			    LIST(NAString) &llist) const;
  
    // 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, but should not produce false
    // negatives.
    //
    virtual HashValue topHash();
  
    // A more thorough method to compare two RelExpr nodes.
    // Used by the Cascades engine.
    //
    virtual NABoolean duplicateMatch(const RelExpr & other) const;
  
    // Copy a chain of derived nodes (Calls RelExpr::copyTopNode).
    // Needs to copy all relevant fields.
    // Used by the Cascades engine.
    //
    virtual RelExpr *copyTopNode(RelExpr *derivedNode = NULL,
  			       CollHeap *outHeap = NULL);
  
    // synthesize logical properties
    //
    virtual void synthLogProp(NormWA * normWAPtr = NULL);
    virtual void synthEstLogProp(const EstLogPropSharedPtr& inputEstLogProp);
  
    virtual Context* createContextForAChild(Context* myContext,
                                            PlanWorkSpace* pws,
                                            Lng32& childIndex);
  
    // get a printable string that identifies the operator
    //
    virtual const NAString getText() const {return "Sequence";};
  
    inline void setCancelExprTree(ItemExpr *expr)
    { cancelExprTree_ = expr; }
  
    ValueIdList mapSortKey(const ValueIdList &sortKey) const;
  
    // Accessor methods
    inline const ValueIdList & requiredOrder() const { return requiredOrder_; }
  
    inline const ValueIdList & partition() const { return partition_; }
  
    inline const ValueIdSet & sequenceFunctions() const
    { return sequenceFunctions_; }
  
    inline const ValueIdSet & returnSeqFunctions() const
    { 
      return returnSeqFunctions_; 
    }
    inline const ValueIdSet & movePartIdsExpr() const
    { 
      return movePartIdsExpr_; 
    }
    inline const ValueIdSet & sequencedColumns() const
    { return sequencedColumns_; }
  
    inline void addSequencedColumn(ValueId col)
    { sequencedColumns_ += col; }
  
    inline const ValueIdList & cancelExpr() const
    { return cancelExpr_; }
  
    // 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 addUnResolvedSeqFunctions(ValueIdSet &unresolvedSeqFuncs,
                                   BindWA *bindWA);
  
     inline void setRequiredOrder(const ValueIdList &reqOrder)
     { requiredOrder_ = reqOrder; }
  
     inline void setPartition(const ValueIdList &partition)
     { partition_ = partition; }
  
     ValueIdList getPartitionChange() { return partitionChange_ ;}
  
     ItemExpr * getPartitionBy() { return partitionBy_;}
  
     void setPartitionBy(ItemExpr * part) {partitionBy_ = part;}
  
     inline void setSequenceFunctions(const ValueIdSet &seqFuncs)
     { sequenceFunctions_ = seqFuncs; }
  
    inline void setSequencedColumns(const ValueIdSet &seqCols)
    { sequencedColumns_ = seqCols; }
  
    inline void setCancelExpr(const ValueIdList &expr)
    { cancelExpr_ = expr; }
  
    inline void setHasOlapFunctions(const NABoolean v)
    { hasOlapFunctions_ = v; }
    inline const NABoolean getHasOlapFunctions() const
    { return hasOlapFunctions_; }
  
    inline void setHasTDFunctions(const NABoolean v)
    { hasTDFunctions_ = v; }
    inline const NABoolean getHasTDFunctions() const
    { return hasTDFunctions_; }
  
    ItemExpr * getRequiredOrderTree() {return requiredOrderTree_;}
  
    Lng32 getCachedNumHistoryRows()
    {
      return cachedNumHistoryRows_;
    }
    void setCachedNumHistoryRows( Lng32 v)
    {
      cachedNumHistoryRows_ = v;
    }
  
    NABoolean getCachedUnboundedFollowing()
    {
      return cachedUnboundedFollowing_;
    }
    void setCachedUnboundedFollowing( NABoolean v)
    {
      cachedUnboundedFollowing_ = v;
    }
  
    Lng32 getCachedMinFollowingRows()
    {
      return cachedMinFollowingRows_;
    }
    void setCachedMinFollowingRows( Lng32 v)
    {
      cachedMinFollowingRows_ = v;
    }
  
    Lng32 getCachedHistoryRowLength()
    {
      return cachedHistoryRowLength_;
    }
    void setCachedHistoryRowLength( Lng32 v)
    {
      cachedHistoryRowLength_ = v;
    }
  
    NABoolean getHistoryInfoCached()
    {
      return historyInfoCached_;
    }
    void setHistoryInfoCached( NABoolean v)
    {
      historyInfoCached_ = v;
    }
    
  protected:
  
    inline ValueIdList & requiredOrder() { return requiredOrder_; }
  
    inline ValueIdList & partition() { return partition_; }
  
    inline ValueIdSet & sequenceFunctions() { return sequenceFunctions_; }
  
    inline ValueIdSet & readSeqFunctions() { return sequenceFunctions_; }
    inline ValueIdSet & returnSeqFunctions() { return returnSeqFunctions_; }
    inline ValueIdSet & sequencedColumns() { return sequencedColumns_; }
  
    inline ValueIdList & cancelExpr() { return cancelExpr_; }
  
    void addCancelExpr(CollHeap *wHeap);
    
    inline ValueIdSet & checkPartitionChangeExpr() { return checkPartitionChangeExpr_; }
    inline ValueIdSet & movePartIdsExpr() { return movePartIdsExpr_; }
  
  private:
    // Return a pointer to the required order tree after
    // setting it to NULL.
    //
    ItemExpr *removeRequiredOrderTree();
  
    // An ItemExpr list of columns representing the reqired sort order
    // for this node.
    //
    ItemExpr *requiredOrderTree_;
  
    // The ItemExpr list of columns representing the partition by clause.
    //
    ItemExpr *partitionBy_;
  
    // -- MV
    // During execution, when the cancelExpr evaluates to TRUE, the Sequence
    // node cancels the parent request.
    ItemExpr *cancelExprTree_;
  
    // The bound version of requiredOrderTree_.
    //
    ValueIdList requiredOrder_;
  
      // The bound version of partitionByTree_
    //
    ValueIdList partition_;
  
    ValueIdList partitionChange_;
    // A set of all the sequence functions associated with this
    // RelSequence node.  They are gathered and assigned to the
    // RelSequence node during binding.
    //
    ValueIdSet sequenceFunctions_;
  
    ValueIdSet returnSeqFunctions_;
    ValueIdSet sequencedColumns_;
  
    // -- MV
    ValueIdList cancelExpr_;
  
    // flag that defines whether this RelSequence was created for TD functions
    // or not
    NABoolean hasTDFunctions_;
    NABoolean hasOlapFunctions_;
  
    ValueIdSet checkPartitionChangeExpr_;
    ValueIdSet movePartIdsExpr_;
  
    //cached parameters
    NABoolean historyInfoCached_;
    Lng32 cachedNumHistoryRows_;
    NABoolean cachedUnboundedFollowing_;
    Lng32 cachedMinFollowingRows_;
    Lng32 cachedHistoryRowLength_;
  
  }; // class RelSequence
  
  // Class PhysSequence ----------------------------------------------------
  // The PhysSequence node replaces the logical RelSequence node through the
  // application of the PhysSequenceRule. This transformation is
  // designed to present a purely physical verison of this operator
  // that is both a logical and physical node. The PhysSequence node
  // does not add any data members. It adds a few virtual methods.
  // -----------------------------------------------------------------------
  #pragma nowarn(1506)   // warning elimination
  class PhysSequence : public RelSequence
  {
  public:
  
    // The constructor
    //
  #pragma nowarn(734)   // warning elimination
    PhysSequence(RelExpr *child = NULL,
  #pragma warn(734)   // warning elimination
                        CollHeap *oHeap = CmpCommon::statementHeap())
      : RelSequence(child, NULL, oHeap)
    {
      numHistoryRows_ = getDefault(DEF_MAX_HISTORY_ROWS);
      minFixedHistoryRows_ = 0;
      unboundedFollowing_ = FALSE;
      minFollowingRows_ = 0;
    };
  
    // The destructor.
    //
    virtual ~PhysSequence();
  
    // methods to do code generation of the physical node.
    //
    virtual RelExpr * preCodeGen(Generator * generator,
  			       const ValueIdSet & externalInputs,
  			       ValueIdSet &pulledNewInputs);
    virtual short codeGen(Generator*);
  
    // generate CONTROL QUERY SHAPE fragment for this node.
    //
    virtual short generateShape(CollHeap * space, char * buf, NAString * shapeStr = NULL);
  
    // Copy a chain of derived nodes (Calls RelSequence::copyTopNode).
    // Needs to copy all relevant fields (in this case no fields
    // need to be copied)
    // Used by the Cascades engine.
    //
    virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL,
  				CollHeap *outHeap = NULL);
  
    // cost functions
    //
    virtual PhysicalProperty *synthPhysicalProperty(const Context *context,
                                                    const Lng32 planNumber,
                                                    PlanWorkSpace  *pws);
    virtual CostMethod* costMethod() const;
  
    // The method gets redefined since Sequnece may be a BMO depending
    // on its inputs.
    virtual NABoolean isBigMemoryOperator(const Context* context,
                                          const Lng32 planNumber);
  
    virtual CostScalar getEstimatedRunTimeMemoryUsage(NABoolean perCPU);
    virtual double getEstimatedRunTimeMemoryUsage(ComTdb * tdb);
  
  
    // Redefine these virtual methods to declare this node as a
    // physical node.
    //
    virtual NABoolean isLogical() const {return FALSE;};
    virtual NABoolean isPhysical() const {return TRUE;};
  
    ExplainTuple *addSpecificExplainInfo(ExplainTupleMaster *explainTuple,
  					      ComTdb * tdb,
  					      Generator *generator);
  
    // Helper function that traverses the set of root sequence functions
    // supplied by the compiler and constructs the set of all of the
    // attributes that must be materialized in the history row.
    //
    void getHistoryAttributes(const ValueIdSet &sequenceFunctions,
                              const ValueIdSet &outputFromChild,
                              ValueIdSet &historyAttributes,
                              NABoolean addConvNodes = FALSE,
                              CollHeap *wHeap = NULL,
                              ValueIdMap *origAttributes = NULL) const;
  
    // Helper function to compute the attribute for the history buffer
    // based on the items projected from the child and the computed
    // history items.  Also, adds the attribute information the the map
    // table.
    //
    void computeHistoryAttributes(Generator *generator,
                                  MapTable *localMapTable,
                                  Attributes **attrs,
                                  const ValueIdSet &historyIds) const;
  
    // Helper function that traverses the set of root sequence functions
    // supplied by the compiler and dynamically determines the size
    // of the history buffer.
    //
    void computeHistoryRows(const ValueIdSet &sequenceFunctions,
                            Lng32 &computedHistoryRows,
                            Lng32 &unableToCalculate,
                            //long &minFixedHistoryRows,
                            NABoolean &unboundedFollowing, //&unlimitedHistoryRows,
                            Lng32 &minFollowingRows,
                            const ValueIdSet &outputFromChild);
  
  
    // Return a READ-ONLY reference to the number of history rows to be
    // allocated in the history buffer.
    //
    inline const Lng32 & numHistoryRows() const { return numHistoryRows_; }
  
    // Set the number of history rows to be allowed in the history buffer.
    void setNumHistoryRows(Lng32 numHistoryRows);
  
    void setUnboundedFollowing(NABoolean v);
    NABoolean getUnboundedFollowing() const ;
  
    void setMinFollowingRows(Lng32 v);
  
    // set the min following rows to max(v, minFollowingRows_);
    void computeAndSetMinFollowingRows(Lng32 v);
  
    Lng32 getMinFollowingRows() const ;
  
    Lng32 getEstHistoryRowLength() const
    {
      return estHistoryRowLength_;
    }
  
    void setEstHistoryRowLength(Lng32 v)
    {
      estHistoryRowLength_ = v;
    }
  
    void updateEstHistoryRowLength(ValueIdSet &histIds,
  				ValueId newValId,
                                  Lng32 &estimatedLength)
    {
      if (!histIds.contains(newValId))
      {
        estimatedLength += newValId.getType().getTotalSize();
        histIds += newValId;
      }
    }
  
    void seperateReadAndReturnItems(CollHeap *wHeap);
  
    void computeReadNReturnItems(ValueId seqVid,
                                 ValueId vid,
                                 const ValueIdSet &outputFromChild,
                                 CollHeap *wHeap);
    
    void transformOlapFunctions(CollHeap *wHeap);
  
    void computeHistoryParams( Lng32 histRecLength,
                               Lng32 &maxRowsInOLAPBuffer,
                               Lng32 &minNumberOfOLAPBuffers,
                               Lng32 &numberOfWinOLAPBuffers,
                               Lng32 &maxNumberOfOLAPBuffers,
                               Lng32 &olapBufferSize);
  
    void retrieveCachedHistoryInfo(RelSequence * cacheRelSeq) ;
  
  
    void estimateHistoryRowLength(const ValueIdSet &sequenceFunctions,
                                  const ValueIdSet &outputFromChild,
                                  ValueIdSet &histIds,
                                  Lng32 &estimatedLength);
  
    void addCheckPartitionChangeExpr( Generator *generator,
                                      NABoolean addConvNodes = FALSE,
                                      ValueIdMap *origAttributes = NULL);
  private:
  
    // The number of history rows to allocate for the history buffer.
    // Is initialized to the value of the default REF_MAX_HISTORY_ROWS.
    // Later it may be reduced if it can be determined that fewer rows
    // can safely be used.
    //
    Lng32 numHistoryRows_;
  
    // minimum number of rows that need to fit in the history buffer
    // unbounded to Bounded and bounded to bounded cases
    // if there is an unbounded following we still need to detremine the size for above cases
    Lng32 minFixedHistoryRows_;
  
    // do need to have unlimited size-- unbounded following cases
    NABoolean unboundedFollowing_; //unlimitedHistoryRows_;
  
  
    Lng32 minFollowingRows_;
  
    //estimated history row length
    Lng32 estHistoryRowLength_;
  
  }; // class PhysSequence
  #pragma warn(1506)  // warning elimination
  
  #endif
  