/**********************************************************************
// @@@ 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 PHYPROP_HDR
#define PHYPROP_HDR
/* -*-C++-*-
**************************************************************************
*
* File:         PhyProp.h
* Description:  Physical Properties and Cost
* Created:      4/10/94
* Language:     C++
*
*
*
*
**************************************************************************
*/

// -----------------------------------------------------------------------
#include "SchemaDB.h"
#include "PartFunc.h"
#include "RelEnforcer.h"
#include "PartReq.h"
#include "RelEnforcer.h"
#include "opt.h"

#include "LookupTable.h"

// -----------------------------------------------------------------------
//  The following classes are defined in this file.
// -----------------------------------------------------------------------
class PhysicalProperty;
class ReqdPhysicalProperty;
class InputPhysicalProperty;
class CurrentFragmentBigMemoryProperty;

// -----------------------------------------------------------------------
// forward references
// -----------------------------------------------------------------------
class GroupAttributes;
class CorrName;
class DP2CostDataThatDependsOnSPP;
class PushDownProperty;
class PushDownRequirement;
namespace tmudr {
  class UDRPlanInfo;
}

// -----------------------------------------------------------------------
// global defines
// -----------------------------------------------------------------------

// see class ReqdPhysicalProperty

#define DEFAULT_LOCATION     EXECUTE_IN_ESP
#define DEFAULT_SINGLETON    1
//#define DEFAULT_DATA_SOURCE  SOURCE_PERSISTENT_TABLE /* not used */


// -----------------------------------------------------------------------
// Physical Properties
// ===================
//
//    Physical properties are those that can be derived from physical
//    expressions.  Thus, these are properties that have a dependency
//    on the physical strategy/algorithm chosen to implement the 
//    query.  
// -----------------------------------------------------------------------

class PhysicalProperty : public NABasicObject
{

public:

  // ---------------------------------------------------------------------
  //  Constructors and destructor
  // ---------------------------------------------------------------------
  PhysicalProperty() 
    : sortOrderType_(NO_SOT),
      dp2SortOrderPartFunc_(NULL),
      actualPartFunc_(NULL), 
      location_(DEFAULT_LOCATION),  
      sourceOfData_(SOURCE_PERSISTENT_TABLE),
      indexDesc_(NULL),
      partSearchKey_(NULL),
      currentCountOfCPUs_(1),
      dp2CostInfo_(NULL),
      udrPlanInfo_(NULL),
      pushDownProperty_(NULL),
      memoryNeedsinCurrentFragment_(NULL),
      explodedOcbJoin_(FALSE),
      accessOnePartition_(FALSE),
      insertedDataIsSorted_(FALSE)
  {}
  
  PhysicalProperty(const ValueIdList &sortKey, 
                   SortOrderTypeEnum sortOrderType,
                   PartitioningFunction* dp2SortOrderPartFunc = NULL,
		   PartitioningFunction * actualPartFunc = NULL,
		   const PlanExecutionEnum plenum = DEFAULT_LOCATION, 
                   const DataSourceEnum dsenum = SOURCE_PERSISTENT_TABLE,
                   const IndexDesc * indexDesc = NULL,
		   const SearchKey * partSearchKey = NULL,
                   const PushDownProperty* pdp = NULL,
				   NABoolean explOcbJoin = FALSE
		   )
    : sortKey_(sortKey),
      sortOrderType_(sortOrderType),
      dp2SortOrderPartFunc_(dp2SortOrderPartFunc),
      actualPartFunc_(actualPartFunc), 
      location_(plenum),  
      sourceOfData_(dsenum),
      indexDesc_(indexDesc),
      partSearchKey_(partSearchKey),
      currentCountOfCPUs_(1),
      dp2CostInfo_(NULL),
      udrPlanInfo_(NULL),
      pushDownProperty_(pdp),
      memoryNeedsinCurrentFragment_(NULL),
      explodedOcbJoin_(explOcbJoin),
      accessOnePartition_(FALSE),
      insertedDataIsSorted_(FALSE)
  {}

  PhysicalProperty(PartitioningFunction * actualPartFunc,
		   const PlanExecutionEnum plenum = DEFAULT_LOCATION, 
		   const DataSourceEnum dsenum = SOURCE_PERSISTENT_TABLE
		   )
    : sortOrderType_(NO_SOT),
      dp2SortOrderPartFunc_(NULL),
      actualPartFunc_(actualPartFunc), 
      location_(plenum),  
      sourceOfData_(dsenum),
      indexDesc_(NULL),
      partSearchKey_(NULL),
      currentCountOfCPUs_(1),
      dp2CostInfo_(NULL),
      udrPlanInfo_(NULL),
      pushDownProperty_(NULL),
      memoryNeedsinCurrentFragment_(NULL),
      explodedOcbJoin_(FALSE),
      accessOnePartition_(FALSE),
      insertedDataIsSorted_(FALSE)
	{}

  PhysicalProperty(const PhysicalProperty &other)
    : sortKey_(other.sortKey_), 
      sortOrderType_(other.sortOrderType_),
      dp2SortOrderPartFunc_(other.dp2SortOrderPartFunc_),
      actualPartFunc_(other.actualPartFunc_), 
      location_(other.location_),  
      sourceOfData_(other.sourceOfData_),
      indexDesc_(other.indexDesc_),
      partSearchKey_(other.partSearchKey_),
      currentCountOfCPUs_(other.currentCountOfCPUs_),
      dp2CostInfo_(other.dp2CostInfo_),
      udrPlanInfo_(other.udrPlanInfo_),
      pushDownProperty_(other.pushDownProperty_),
      memoryNeedsinCurrentFragment_(other.memoryNeedsinCurrentFragment_),
      explodedOcbJoin_(other.explodedOcbJoin_),
      accessOnePartition_(other.accessOnePartition_),
      insertedDataIsSorted_(other.insertedDataIsSorted_)
  {}

  PhysicalProperty(const PhysicalProperty &other,
		   const ValueIdList &sortKey,
                   SortOrderTypeEnum sortOrderType,
                   PartitioningFunction* dp2SortOrderPartFunc 
                  )
    : sortKey_(sortKey), 
      sortOrderType_(sortOrderType),
      dp2SortOrderPartFunc_(dp2SortOrderPartFunc),
      actualPartFunc_(other.actualPartFunc_), 
      location_(other.location_),  
      sourceOfData_(other.sourceOfData_),
      indexDesc_(other.indexDesc_),
      partSearchKey_(other.partSearchKey_),
      currentCountOfCPUs_(other.currentCountOfCPUs_),
      dp2CostInfo_(other.dp2CostInfo_),
      udrPlanInfo_(other.udrPlanInfo_),
      pushDownProperty_(other.pushDownProperty_),
      memoryNeedsinCurrentFragment_(other.memoryNeedsinCurrentFragment_),
      explodedOcbJoin_(other.explodedOcbJoin_),
      accessOnePartition_(other.accessOnePartition_),
      insertedDataIsSorted_(other.insertedDataIsSorted_)
   {}

   PhysicalProperty(const PhysicalProperty &other,
		    const ValueIdList &sortKey,
                    SortOrderTypeEnum sortOrderType,
                    PartitioningFunction* dp2SortOrderPartFunc,
                    DataSourceEnum sourceOfData
                   )
    : sortKey_(sortKey), 
      sortOrderType_(sortOrderType),
      dp2SortOrderPartFunc_(dp2SortOrderPartFunc),
      actualPartFunc_(other.actualPartFunc_), 
      location_(other.location_),  
      sourceOfData_(sourceOfData),
      indexDesc_(other.indexDesc_),
      partSearchKey_(other.partSearchKey_),
      currentCountOfCPUs_(other.currentCountOfCPUs_),
      dp2CostInfo_(other.dp2CostInfo_),
      udrPlanInfo_(other.udrPlanInfo_),
      pushDownProperty_(other.pushDownProperty_),
      memoryNeedsinCurrentFragment_(other.memoryNeedsinCurrentFragment_),
      explodedOcbJoin_(other.explodedOcbJoin_),
      accessOnePartition_(other.accessOnePartition_),
      insertedDataIsSorted_(other.insertedDataIsSorted_)
   {}

  PhysicalProperty(const PhysicalProperty &other,
		   const ValueIdList &sortKey,
                   SortOrderTypeEnum sortOrderType,
                   PartitioningFunction* dp2SortOrderPartFunc,
		   PartitioningFunction* actualPartFunc
                  )
    : sortKey_(sortKey), 
      sortOrderType_(sortOrderType),
      dp2SortOrderPartFunc_(dp2SortOrderPartFunc),
      actualPartFunc_(actualPartFunc), 
      location_(other.location_),  
      sourceOfData_(other.sourceOfData_),
      indexDesc_(other.indexDesc_),
      partSearchKey_(other.partSearchKey_),
      currentCountOfCPUs_(other.currentCountOfCPUs_),
      dp2CostInfo_(other.dp2CostInfo_),
      udrPlanInfo_(other.udrPlanInfo_),
      pushDownProperty_(other.pushDownProperty_),
      memoryNeedsinCurrentFragment_(other.memoryNeedsinCurrentFragment_),
      explodedOcbJoin_(other.explodedOcbJoin_),
      accessOnePartition_(other.accessOnePartition_),
      insertedDataIsSorted_(other.insertedDataIsSorted_)
 
  {}


  virtual ~PhysicalProperty();
  
  // ---------------------------------------------------------------------
  // Accessor/Mutator functions
  // ---------------------------------------------------------------------

   const NABoolean getexplodedOcbJoinProperty() const
      { return explodedOcbJoin_; }

  // For determining if the partitioning key is a prefix of the
  // sort key (i.e. the clustering key) 
  NABoolean isPartKeyPrefixOfSortKey() const;

  // --- For sort key
  inline NABoolean isSorted() const   { return (sortKey_.entries() > 0); }
  inline const ValueIdList & getSortKey() const       { return sortKey_; }

  // accessors 
  inline SortOrderTypeEnum getSortOrderType() const
  { return sortOrderType_; }
  inline PartitioningFunction* getDp2SortOrderPartFunc() const
  { return dp2SortOrderPartFunc_; }

  // mutators
  void setSortOrderType(SortOrderTypeEnum sortOrderType)
  { 
    // Check that the synthesized sort order type is within the
    // allowable range for a synthesized sort order type.
    DCMPASSERT((sortOrderType >= NO_SOT) AND
               (sortOrderType <= DP2_SOT))
    sortOrderType_ = sortOrderType;
  }
  void setDp2SortOrderPartFunc(
                     PartitioningFunction* dp2SortOrderPartFunc)
  { dp2SortOrderPartFunc_ = dp2SortOrderPartFunc; }

  void setLocation(PlanExecutionEnum location)
  {location_ = location;}

  // --- For partitioning function
  inline NABoolean isPartitioned() const
  { return (actualPartFunc_ AND actualPartFunc_->getCountOfPartitions() > 1); }

  inline void scaleNumberOfPartitions(Lng32 npartns)
   { 
     if ( actualPartFunc_ )
        actualPartFunc_ = actualPartFunc_->scaleNumberOfPartitions(npartns); 
   }; 

  inline PartitioningFunction * getPartitioningFunction() const 
                                               { return actualPartFunc_; }
  inline Lng32 getCountOfPartitions() const
  {
    if (actualPartFunc_)
      return actualPartFunc_->getCountOfPartitions();
    else
      return 1;
  }

  // --- Read-only access to the partitioning key.
  inline const ValueIdSet & getPartitioningKey() const
                        { return  actualPartFunc_->getPartitioningKey(); }

  // --- For plan execution
  inline NABoolean executeInMasterOrESP() const 
                       { return (location_ == EXECUTE_IN_MASTER_OR_ESP); }
  inline NABoolean executeInMasterOnly() const 
                              { return (location_ == EXECUTE_IN_MASTER); }
  inline NABoolean executeInESPOnly() const 
                                 { return (location_ == EXECUTE_IN_ESP); }
  inline NABoolean executeInDP2() const 
                                 { return (location_ == EXECUTE_IN_DP2); }
  inline PlanExecutionEnum getPlanExecutionLocation() const
                                                     { return location_; }

  // -- For the source of the data
  inline DataSourceEnum getDataSourceEnum() const
                                                 { return sourceOfData_; }
  inline void setDataSourceEnum(DataSourceEnum s)
                                                    { sourceOfData_ = s; }

  // -- Accessor for the table descriptor
  inline const IndexDesc * getIndexDesc() const     { return indexDesc_; }
  inline void  setIndexDesc(const IndexDesc * val)   { indexDesc_ = val; }

  // -- Accessor and Mutator for the partition search key (part. key predicates)
  inline const SearchKey * getPartSearchKey() const
                                                { return partSearchKey_; }
  inline void setPartSearchKey(const SearchKey* partSearchKey)
                                       { partSearchKey_ = partSearchKey; }

  // -- Accessor and Mutator for cpuCountInDP2_.
  inline Lng32 getCurrentCountOfCPUs() const    { return currentCountOfCPUs_; }
  inline void setCurrentCountOfCPUs(const Lng32 value)
                                            { currentCountOfCPUs_ = value; }
				      
  // ---------------------------------------------------------------------
  // comparison functions (A > B means that A delivers all the
  // physical properties that B has plus some more).
  // ---------------------------------------------------------------------
  inline NABoolean operator > (const PhysicalProperty &other) const
                              { return compareProperties(other) == MORE; }
  inline NABoolean operator < (const PhysicalProperty &other) const
                              { return compareProperties(other) == LESS; }
  inline NABoolean operator == (const PhysicalProperty &other) const
                              { return compareProperties(other) == SAME; }

  // -----------------------------------------------------------------------
  // For costing data that gets computed at synthesis time:
  // -----------------------------------------------------------------------
  const DP2CostDataThatDependsOnSPP * getDP2CostThatDependsOnSPP() const
  { return dp2CostInfo_; }
  
  void setDP2CostThatDependsOnSPP(DP2CostDataThatDependsOnSPP * dp2Cost)
  { dp2CostInfo_ = dp2Cost; }

  // for UDRs (only to transfer this info to the code generator)
  tmudr::UDRPlanInfo *getUDRPlanInfo() const      { return udrPlanInfo_; }
  void setUDRPlanInfo(tmudr::UDRPlanInfo *pi)       { udrPlanInfo_ = pi; }
  
  // -----------------------------------------------------------------------
  // Make sure that all members are covered by the group attributes!
  //
  // Currently, we only check the sort key.  Someday we may check other
  // fields, such as the partitioning function.
  // -----------------------------------------------------------------------
  void enforceCoverageByGroupAttributes (const GroupAttributes * groupAttr) ;

  // ---------------------------------------------------------------------
  //  Utility functions
  // ---------------------------------------------------------------------
  void print(FILE* ofd = stdout,
	     const char * prefix = DEFAULT_INDENT,
             const char * suffix = "") const;

 
  void setPushDownProperty(const PushDownProperty* pdp) 
 	{ pushDownProperty_ = pdp; };
  const PushDownProperty* getPushDownProperty() const
	{ return pushDownProperty_; } ;

  void setBigMemoryEstimationProperty( CurrentFragmentBigMemoryProperty *c)
       { memoryNeedsinCurrentFragment_ = c;}

  const CurrentFragmentBigMemoryProperty * getBigMemoryEstimationProperty()
       { return memoryNeedsinCurrentFragment_; }

  void setAccessOnePartition(NABoolean x) { accessOnePartition_ = x; } ;
  NABoolean getAccessOnePartition() const { return accessOnePartition_; } ;

  void setInsertedDataIsSorted(NABoolean x) { insertedDataIsSorted_ = x; } ;
  NABoolean getInsertedDataIsSorted() const { return insertedDataIsSorted_; } ;

private:
  // ---------------------------------------------------------------------
  // Method for comparing two Physical property vectors.
  // ---------------------------------------------------------------------
  COMPARE_RESULT compareProperties(const PhysicalProperty & other) const;

  // ---------------------------------------------------------------------
  // Information about the order of the result rows
  // ---------------------------------------------------------------------
  ValueIdList  sortKey_;       // sorted by the specified cols/expressions

  // ---------------------------------------------------------------------
  // The type of sort order: NO_SOT, ESP_NO_SORT_SOT,
  // ESP_VIA_SORT_SOT, DP2_SOT
  // ---------------------------------------------------------------------
  SortOrderTypeEnum sortOrderType_;
  
  // ---------------------------------------------------------------------
  // The physical partitioning function of the access path that generated
  // the sort order. NULL if no sort order or if the sort order type is
  // not DP2.
  // ---------------------------------------------------------------------
  PartitioningFunction* dp2SortOrderPartFunc_;

  // ---------------------------------------------------------------------
  // The partitioning function encapsulates data parallelism.
  // When a plan fragment executes within DP2 the degree of operator
  // parallelism is equal to the number of partitions, i.e., the degree 
  // of data parallelism. In contrast, when a plan fragement executes
  // in ESP, the number of data streams, i.e., partitions, are expected
  // to be equal to the number of operator instances that are expected
  // to execute in parallel.
  // ---------------------------------------------------------------------
  PartitioningFunction * actualPartFunc_; 
  
  // ---------------------------------------------------------------------
  // Information about where the plan, or plan fragment, should be 
  // executed.
  // ---------------------------------------------------------------------
  PlanExecutionEnum  location_;
  
  // ---------------------------------------------------------------------
  // The source for the data, persistent table, temporary table or esp.
  // ---------------------------------------------------------------------
  DataSourceEnum  sourceOfData_;
  
  // ---------------------------------------------------------------------
  // The index which is the source of data. It points
  // to a table name only when sourceIsAPersistentTable() is TRUE.
  // Otherwise it is NULL.
  // This information is preserved until the first Exchange operator 
  // is reached.
  // ---------------------------------------------------------------------
  const IndexDesc * indexDesc_;

  // ---------------------------------------------------------------------
  // The search key to be used to determine partitions for indexDesc_.
  // This search key contains artificial predicates, designed to split
  // data into different streams when an operator is executed in parallel,
  // and any other predicates that may restrict the partititions used.
  // All predicates in partSearchKey_ have to be covered by the
  // characteristic inputs of the RelExpr that carries this object.
  // ---------------------------------------------------------------------
  const SearchKey * partSearchKey_;

  // ---------------------------------------------------------------------
  // No of CPU used if the operator executes in DP2. Meaningless if the
  // operator doesn't executes in DP2. This is for informational purpose
  // only. Should not be used to determine whether some ReqdPhysProperty
  // are satisfied.
  // ---------------------------------------------------------------------
  // $$$ This member should be moved to class
  // $$$ DP2CostDataThatDependsOnSPP!!!!
  Lng32 currentCountOfCPUs_;

  // -----------------------------------------------------------------------
  // The following class should contain all costing data for dp2
  // operators that gets computed at synthesis time:
  // -----------------------------------------------------------------------

  DP2CostDataThatDependsOnSPP * dp2CostInfo_;
  tmudr::UDRPlanInfo *udrPlanInfo_;

  const PushDownProperty* pushDownProperty_;

  CurrentFragmentBigMemoryProperty *memoryNeedsinCurrentFragment_;
  NABoolean explodedOcbJoin_;

  NABoolean accessOnePartition_;

  // set in DP2Insert::synthPhysicalProperty.
  // Indicates if the data to be inserted is sorted.
  NABoolean insertedDataIsSorted_;
}; // PhysicalProperty

// -----------------------------------------------------------------------
// Performance goals
//
// Optimize for N rows
//   Choose a plan that offers the lowest cost for returning the 
//   first N rows.
//
// Optimize for first row
//   Choose a plan that offers that offers the lowest first row cost
//
// Optimize for last row
//   Choose a plan that offers that offers the lowest last row cost
//
// Optimize for resource consumption
//   Choose a plan that offers that offers the lowest total cost
//
// -----------------------------------------------------------------------
class PerformanceGoal
{
public:
  virtual ~PerformanceGoal();
  
  virtual NABoolean isOptimizeForFirstRow() const;

  virtual NABoolean isOptimizeForLastRow() const;

  virtual NABoolean isOptimizeForResourceConsumption() const;

private:
}; // class PerformanceGoal

// -- Optimize for N rows
class OptimizeForNRows : public PerformanceGoal
{
public:
  OptimizeForNRows(Lng32 numberOfRows) : rowCount_(numberOfRows) 
                                            { assert(numberOfRows > 0); }
  virtual ~OptimizeForNRows() {}

  virtual NABoolean isOptimizeForFirstRow() const;
  
private:  
  Lng32 rowCount_;
}; // class OptimizeForNRows

// -- Optimize for first row - not used in SQ
class OptimizeForFirstRow : public OptimizeForNRows
{
public:
  OptimizeForFirstRow() : OptimizeForNRows(1)                          { }

  virtual ~OptimizeForFirstRow() {}

}; // class OptimizeForFirstRow

// -- Optimize for last row
class OptimizeForLastRow : public OptimizeForNRows
{
public:
  OptimizeForLastRow() : OptimizeForNRows(INT_MAX)                    { }
  
  virtual ~OptimizeForLastRow() {}

  virtual NABoolean isOptimizeForLastRow() const;
  virtual NABoolean isOptimizeForFirstRow() const;

}; // class OptimizeForLastRow

// -- Optimize for resource consumption - not used in SQ
class OptimizeForResourceConsumption : public PerformanceGoal
{
public:
  virtual ~OptimizeForResourceConsumption() {}

  virtual NABoolean isOptimizeForResourceConsumption() const;

}; // class OptimizeForResourceConsumption


// -----------------------------------------------------------------------
// Required physical properties
// -----------------------------------------------------------------------

class ReqdPhysicalProperty  : public NABasicObject
{

public:

  // ---------------------------------------------------------------------
  //  Constructor, copy constructor, destructor, and assignment operator
  // ---------------------------------------------------------------------

  ReqdPhysicalProperty(
           const ValueIdSet* const arrangedBy = NULL,
           const ValueIdList* const orderedBy = NULL,
           SortOrderTypeEnum sortOrderTypeReq = NO_SOT,
           PartitioningRequirement* dp2SortOrderPartReq = NULL,
           const NABoolean logicalOrderOrArrangement = FALSE,
           PartitioningRequirement* partReq = NULL,
           LogicalPartitioningRequirement* logicalPartReq = NULL,
           const PlanExecutionEnum location = DEFAULT_LOCATION,
           const Lng32 availableCPUs = DEFAULT_SINGLETON,
           const Lng32 pipelinesPerCPU = DEFAULT_SINGLETON,
           const CostWeight* const costWeight = CURRSTMT_OPTDEFAULTS->getDefaultCostWeight(),
           const PerformanceGoal* const perfGoal = CURRSTMT_OPTDEFAULTS->getDefaultPerformanceGoal(),
           RelExpr* mustMatch = NULL,
	   PushDownRequirement* pdp = NULL
  )
    : arrangedBy_(arrangedBy), orderedBy_(orderedBy),
      sortOrderTypeReq_(sortOrderTypeReq),
      dp2SortOrderPartReq_(dp2SortOrderPartReq),
      logicalOrderOrArrangement_(logicalOrderOrArrangement),
      partReq_(partReq),
      logicalPartReq_(logicalPartReq),
      location_(location),
      availableCPUs_(availableCPUs),
      pipelinesPerCPU_(pipelinesPerCPU),
      costWeight_(costWeight),
      perfGoal_(perfGoal),
      mustMatch_(mustMatch),
      pushDownRequirement_(pdp),
      noEspExchangeRequirement_(FALSE),
	  ocbEnabledCostingRequirement_(FALSE)
  {
#ifndef NDEBUG
    performConsistencyCheck();
#endif
  }

  // ---------------------------------------------------------------------
  // NOTE: mustMatch_ is not propagated from one reqd prop to another
  // ---------------------------------------------------------------------
  inline ReqdPhysicalProperty(const ReqdPhysicalProperty& other)
    : arrangedBy_(other.arrangedBy_), orderedBy_(other.orderedBy_), 
      sortOrderTypeReq_(other.sortOrderTypeReq_),
      dp2SortOrderPartReq_(other.dp2SortOrderPartReq_),
      logicalOrderOrArrangement_(other.logicalOrderOrArrangement_),
      partReq_(other.partReq_), 
      logicalPartReq_(other.logicalPartReq_),
      location_(other.location_),
      availableCPUs_(other.availableCPUs_), 
      pipelinesPerCPU_(other.pipelinesPerCPU_),
      costWeight_(other.costWeight_),
      perfGoal_(other.perfGoal_),
      mustMatch_(NULL),
      pushDownRequirement_(other.pushDownRequirement_),
      noEspExchangeRequirement_(other.noEspExchangeRequirement_),
	  ocbEnabledCostingRequirement_(other.ocbEnabledCostingRequirement_)
  {
#ifndef NDEBUG
    performConsistencyCheck();
#endif
  }

  // ---------------------------------------------------------------------
  // NOTE: mustMatch_ is not propagated from one reqd prop to another
  // ---------------------------------------------------------------------
  inline ReqdPhysicalProperty(const ReqdPhysicalProperty& other,
                  const ValueIdSet* const arrangedBy,
                  const ValueIdList* const orderedBy,
                  SortOrderTypeEnum sortOrderTypeReq,
                  PartitioningRequirement* dp2SortOrderPartReq
                             )
    : arrangedBy_(arrangedBy), orderedBy_(orderedBy), 
      sortOrderTypeReq_(sortOrderTypeReq),
      dp2SortOrderPartReq_(dp2SortOrderPartReq),
      logicalOrderOrArrangement_(other.logicalOrderOrArrangement_),
      partReq_(other.partReq_), 
      logicalPartReq_(other.logicalPartReq_),
      location_(other.location_),
      availableCPUs_(other.availableCPUs_), 
      pipelinesPerCPU_(other.pipelinesPerCPU_),
      costWeight_(other.costWeight_),
      perfGoal_(other.perfGoal_),
      mustMatch_(NULL),
      pushDownRequirement_(other.pushDownRequirement_),
      noEspExchangeRequirement_(other.noEspExchangeRequirement_),
	  ocbEnabledCostingRequirement_(other.ocbEnabledCostingRequirement_)
  {
#ifndef NDEBUG
    performConsistencyCheck();
#endif
  }

  // ---------------------------------------------------------------------
  // NOTE: mustMatch_ is not propagated from one reqd prop to another
  // NOTE: The logicalPartitionBoundariesFlag_ is not propagated from one
  // NOTE: required property to another when the partitioning requirement
  // NOTE: is changed
  // ---------------------------------------------------------------------
  ReqdPhysicalProperty(const ReqdPhysicalProperty& other,
                  const ValueIdSet* const arrangedBy,
                  const ValueIdList* const orderedBy,
                  SortOrderTypeEnum sortOrderTypeReq,
                  PartitioningRequirement* dp2SortOrderPartReq,
                  PartitioningRequirement* partReq
			     )
    : arrangedBy_(arrangedBy), orderedBy_(orderedBy), 
      sortOrderTypeReq_(sortOrderTypeReq),
      dp2SortOrderPartReq_(dp2SortOrderPartReq),
      logicalOrderOrArrangement_(other.logicalOrderOrArrangement_),
      partReq_(partReq), 
      logicalPartReq_(other.logicalPartReq_),
      location_(other.location_),
      availableCPUs_(other.availableCPUs_), 
      pipelinesPerCPU_(other.pipelinesPerCPU_),
      costWeight_(other.costWeight_),
      perfGoal_(other.perfGoal_),
      mustMatch_(NULL),
      pushDownRequirement_(other.pushDownRequirement_),
      noEspExchangeRequirement_(other.noEspExchangeRequirement_),
	  ocbEnabledCostingRequirement_(other.ocbEnabledCostingRequirement_)
  {
#ifndef NDEBUG
    performConsistencyCheck();
#endif
  }

  // ---------------------------------------------------------------------
  // NOTE: mustMatch_ is not propagated from one reqd prop to another
  // NOTE: The logicalPartitionBoundariesFlag_ is not propagated from one
  // NOTE: required property to another when the partitioning requirement
  // NOTE: is changed
  // ---------------------------------------------------------------------
  ReqdPhysicalProperty(const ReqdPhysicalProperty &other,
                  const ValueIdSet* const arrangedBy,
                  const ValueIdList* const orderedBy,
                  SortOrderTypeEnum sortOrderTypeReq,
                  PartitioningRequirement* dp2SortOrderPartReq,
                  PartitioningRequirement* partReq,
                  const PlanExecutionEnum location
			     )
    : arrangedBy_(arrangedBy), orderedBy_(orderedBy), 
      sortOrderTypeReq_(sortOrderTypeReq),
      dp2SortOrderPartReq_(dp2SortOrderPartReq),
      logicalOrderOrArrangement_(other.logicalOrderOrArrangement_),
      partReq_(partReq), 
      logicalPartReq_(other.logicalPartReq_),
      location_(location),
      availableCPUs_(other.availableCPUs_), 
      pipelinesPerCPU_(other.pipelinesPerCPU_),
      costWeight_(other.costWeight_),
      perfGoal_(other.perfGoal_),
      mustMatch_(NULL),
      pushDownRequirement_(other.pushDownRequirement_),
      noEspExchangeRequirement_(other.noEspExchangeRequirement_),
	  ocbEnabledCostingRequirement_(other.ocbEnabledCostingRequirement_)
  {
#ifndef NDEBUG
    performConsistencyCheck();
#endif
  }

  // ---------------------------------------------------------------------
  // NOTE: mustMatch_ is not propagated from one reqd prop to another
  // NOTE: The logicalPartitionBoundariesFlag_ is not propagated from one
  // NOTE: required property to another when the partitioning requirement
  // NOTE: is changed
  // ---------------------------------------------------------------------
  ReqdPhysicalProperty(const ReqdPhysicalProperty &other,
                  const ValueIdSet* const arrangedBy,
                  const ValueIdList* const orderedBy,
                  SortOrderTypeEnum sortOrderTypeReq,
                  PartitioningRequirement* dp2SortOrderPartReq,
                  PartitioningRequirement* partReq,
                  const PlanExecutionEnum location,
                  const Lng32 availableCPUs,
                  const Lng32 pipelinesPerCPU
			     )
    : arrangedBy_(arrangedBy), orderedBy_(orderedBy), 
      sortOrderTypeReq_(sortOrderTypeReq),
      dp2SortOrderPartReq_(dp2SortOrderPartReq),
      logicalOrderOrArrangement_(other.logicalOrderOrArrangement_),
      partReq_(partReq), 
      logicalPartReq_(other.logicalPartReq_),
      location_(location),
      availableCPUs_(availableCPUs), 
      pipelinesPerCPU_(pipelinesPerCPU),
      costWeight_(other.costWeight_),
      perfGoal_(other.perfGoal_),
      mustMatch_(NULL),
      pushDownRequirement_(other.pushDownRequirement_),
      noEspExchangeRequirement_(other.noEspExchangeRequirement_),
	  ocbEnabledCostingRequirement_(other.ocbEnabledCostingRequirement_)
  {
#ifndef NDEBUG
    performConsistencyCheck();
#endif
  }

  // create an empty requirement with only a must match in it
  ReqdPhysicalProperty(RelExpr* mustMatch)
    : arrangedBy_(NULL), orderedBy_(NULL),
      sortOrderTypeReq_(NO_SOT),
      dp2SortOrderPartReq_(NULL),
      logicalOrderOrArrangement_(FALSE),
      partReq_(NULL),
      logicalPartReq_(NULL),
      location_(DEFAULT_LOCATION),
      availableCPUs_(DEFAULT_SINGLETON),
      pipelinesPerCPU_(DEFAULT_SINGLETON),
      perfGoal_(CURRSTMT_OPTDEFAULTS->getDefaultPerformanceGoal()),
      costWeight_(CURRSTMT_OPTDEFAULTS->getDefaultCostWeight()),
      mustMatch_(mustMatch),
      pushDownRequirement_(NULL),
      noEspExchangeRequirement_(FALSE),
	  ocbEnabledCostingRequirement_(FALSE)
  {
#ifndef NDEBUG
    performConsistencyCheck();
#endif
  } 

  // ---------------------------------------------------------------------
  // NOTE: mustMatch_ is not propagated from one reqd prop to another
  // NOTE: This constructor is only used to change the "must match" 
  //       attribute of an operator's rpp. This constructor is never
  //       used when creating a new rpp for a child.
  // ---------------------------------------------------------------------
  ReqdPhysicalProperty(const ReqdPhysicalProperty& other,
                              RelExpr* mustMatch
                             )
    : arrangedBy_(other.arrangedBy_), orderedBy_(other.orderedBy_), 
      sortOrderTypeReq_(other.sortOrderTypeReq_),
      dp2SortOrderPartReq_(other.dp2SortOrderPartReq_),
      logicalOrderOrArrangement_(other.logicalOrderOrArrangement_),
      partReq_(other.partReq_), 
      logicalPartReq_(other.logicalPartReq_),
      location_(other.location_),
      availableCPUs_(other.availableCPUs_), 
      pipelinesPerCPU_(other.pipelinesPerCPU_),
      costWeight_(other.costWeight_),
      perfGoal_(other.perfGoal_),
      mustMatch_(mustMatch),
      pushDownRequirement_(other.pushDownRequirement_),
      noEspExchangeRequirement_(other.noEspExchangeRequirement_),
	  ocbEnabledCostingRequirement_(other.ocbEnabledCostingRequirement_)
  {
#ifndef NDEBUG
    performConsistencyCheck();
#endif
  }

  virtual ~ReqdPhysicalProperty();

  // --------------------------------------------------------------------
  // does a given plan satisfy the required property
  // ---------------------------------------------------------------------
  NABoolean satisfied(EstLogPropSharedPtr inputLogProp,
                      const RelExpr * const physExpr,
		      const PhysicalProperty * const physProp) const;

  // ---------------------------------------------------------------------
  // Comparison functions between two required phys. properties
  //
  // Return:
  //
  // LESS          if "this" required physical property requires LESS
  //               than the "other" required property
  // SAME          if both properties require the SAME props
  // MORE          if "this" required physical property requires MORE
  //               than the "other" required property
  // INCOMPATIBLE  if the properties are incompatible (A and B are incom-
  //               patible => no physical property exists that satisfies
  //               both A and B or the two contexts have incompatible
  //               optimization goals, such as optimization for n rows
  //               or statistics for input values)
  // UNDEFINED     can't tell which requires more or less (properties may
  //               in some subtle cases still be incompatible)
  // ---------------------------------------------------------------------
  COMPARE_RESULT compareRequirements(const ReqdPhysicalProperty & other) const;

  // ---------------------------------------------------------------------
  // Accessor/Mutator functions
  // ---------------------------------------------------------------------

  // ---------------------------------------------------------------------
  // Check whether any requirements are specified at all.
  // ---------------------------------------------------------------------
  NABoolean isEmpty() const;

  // ---------------------------------------------------------------------
  // User-specified cost weight.
  // ---------------------------------------------------------------------
  inline const CostWeight* getCostWeight() const { return costWeight_; }

  // ---------------------------------------------------------------------
  // User-specified performance goal.
  // ---------------------------------------------------------------------
  inline const PerformanceGoal* getPerformanceGoal() const
                                                     { return perfGoal_; }
  // ---------------------------------------------------------------------
  // Requirements related to imposing an order on the result.
  // ---------------------------------------------------------------------
  inline const ValueIdSet * getArrangedCols() const { return arrangedBy_; }
  inline const ValueIdList * getSortKey() const     { return orderedBy_; }
  static void initSortOrderTypeCompTab();
  static void initSortOrderTypeContextCompTab();

  //accessors  
  SortOrderTypeEnum getSortOrderTypeReq() const
  { return sortOrderTypeReq_; }
  PartitioningRequirement* getDp2SortOrderPartReq() const
  { return dp2SortOrderPartReq_; }

  

  // mutators
  void setSortOrderTypeReq (SortOrderTypeEnum sortOrderTypeReq)
  { 
    // Check that the required sort order type is within the
    // allowable range for a required sort order type.
    DCMPASSERT((sortOrderTypeReq >= NO_SOT) AND
               (sortOrderTypeReq <= DP2_OR_ESP_NO_SORT_SOT))
    sortOrderTypeReq_ = sortOrderTypeReq;
  }
  void setDp2SortOrderPartReq 
         (PartitioningRequirement* dp2SortOrderPartReq)
  { dp2SortOrderPartReq_ = dp2SortOrderPartReq; }

  NABoolean sortOrderTypeReqAndSynthCompatible
              (const SortOrderTypeEnum synthesizedSortOrderType) const;
  COMPARE_RESULT compareSortOrderTypeReqToReq
              (const SortOrderTypeEnum otherSortOrderTypeReq) const;
  NABoolean dp2SortOrderPartReqAndSynthCompatible
              (const PhysicalProperty* const spp) const;

  inline NABoolean getLogicalOrderOrArrangementFlag() const
                                    { return logicalOrderOrArrangement_; }
  inline void setLogicalOrderOrArrangementFlag(const NABoolean newValue)
                                { logicalOrderOrArrangement_ = newValue; }


  // ---------------------------------------------------------------------
  // Location for plan execution
  // ---------------------------------------------------------------------
  PlanExecutionEnum getPlanExecutionLocation() const
                                                     { return location_; }
  NABoolean executeInDP2() const { return (location_ == EXECUTE_IN_DP2); }

  // ---------------------------------------------------------------------
  // The number of pipelines that can be formed for executing a
  // plan fragment in parallel without (outside of) a DP2.
  // ---------------------------------------------------------------------
  inline Lng32 getCountOfPipelines() const
                             { return availableCPUs_ * pipelinesPerCPU_; }
  inline Lng32 getCountOfAvailableCPUs() const   { return availableCPUs_; }

  // ---------------------------------------------------------------------
  // The partitions, i.e., the number of data streams that should
  // be produced. This is specifed by means of a partitioning requirement.
  // ---------------------------------------------------------------------
  inline NABoolean requiresPartitioning() const 
                                           { return (partReq_ != NULL); }

  inline PartitioningRequirement * getPartitioningRequirement() const 
                                                     { return partReq_; }
  Lng32 getCountOfPartitions() const
                             { return partReq_->getCountOfPartitions(); }

  // --- Read-only access to the partitioning key.
  inline const ValueIdSet & getPartitioningKey() const
                              { return  partReq_->getPartitioningKey(); }

  // ---------------------------------------------------------------------
  // logical partitioning requirement for DP2 fragments
  // ---------------------------------------------------------------------
  LogicalPartitioningRequirement * getLogicalPartRequirement() const
                                               { return logicalPartReq_; }
  void setLogicalPartRequirement(LogicalPartitioningRequirement *lpr)
                                                { logicalPartReq_ = lpr; }

  // ---------------------------------------------------------------------
  // A pattern supplied for enforcing a certain shape on the query
  // tree of the plan.
  // ---------------------------------------------------------------------
  inline const RelExpr * getMustMatch() const       { return mustMatch_; }

  RelExpr* getInputMustMatch(Lng32 childIndex) const;


  void setPushDownRequirement(const PushDownRequirement* pdp) 
 	{ pushDownRequirement_ = pdp; };
  const PushDownRequirement* getPushDownRequirement() const
	{ return pushDownRequirement_ ; } ;
  NABoolean getNoEspExchangeRequirement() const
        { return noEspExchangeRequirement_; } ;
  void setNoEspExchangeRequirement(const NABoolean b)
       { noEspExchangeRequirement_ = b; };
  NABoolean getOcbEnabledCostingRequirement() const
        { return ocbEnabledCostingRequirement_; } ;
  void setOcbEnabledCostingRequirement(const NABoolean b)
       { ocbEnabledCostingRequirement_ = b; };
  // ---------------------------------------------------------------------
  //  Utility functions
  // ---------------------------------------------------------------------
  void print(FILE* ofd = stdout,
	     const char * prefix = DEFAULT_INDENT,
             const char * suffix = "") const;

private:

  // ---------------------------------------------------------------------
  // PRIVATE METHODS
  // ---------------------------------------------------------------------
  void performConsistencyCheck() const
  { 
    DCMPASSERT((availableCPUs_ > 0) AND 
               (pipelinesPerCPU_ > 0) AND
               (costWeight_ != NULL) AND 
               (perfGoal_ != NULL) );

#ifndef NDEBUG
    performSortOrderTypeConsistencyCheck();
#endif
  }

  void performSortOrderTypeConsistencyCheck() const
  {
    if ((arrangedBy_ == NULL) AND (orderedBy_ == NULL))
    {
      DCMPASSERT(sortOrderTypeReq_ == NO_SOT);
      DCMPASSERT(dp2SortOrderPartReq_ == NULL);
    }
    else
    {
      DCMPASSERT((sortOrderTypeReq_ != NO_SOT) OR
                 (location_ == EXECUTE_IN_DP2));
    }

    if ((dp2SortOrderPartReq_ != NULL) OR
        (sortOrderTypeReq_ == DP2_OR_ESP_NO_SORT_SOT) OR
        (sortOrderTypeReq_ == DP2_SOT))
    {
      DCMPASSERT(dp2SortOrderPartReq_ != NULL);
      DCMPASSERT((location_ == EXECUTE_IN_DP2 AND sortOrderTypeReq_ == NO_SOT) OR (sortOrderTypeReq_ == DP2_OR_ESP_NO_SORT_SOT) OR
                 (sortOrderTypeReq_ == DP2_SOT));
    }
  } // performSortOrderTypeConsistencyCheck()

  // ---------------------------------------------------------------------
  // PRIVATE DATA
  // ---------------------------------------------------------------------
  static THREAD_P LookupTable<NABoolean>* sortOrderTypeCompTab_;
  static THREAD_P LookupTable<COMPARE_RESULT>* sortOrderTypeContextCompTab_;

  const CostWeight* const costWeight_;    // weight used for comparing costs

  const PerformanceGoal* const perfGoal_; // the performance goal

  // ---------------------------------------------------------------------
  // The output rows are required to be "arranged" such that they are
  // sorted and the set of "arrangedBy_" values forms a prefix of the
  // sort key.
  // ---------------------------------------------------------------------
  const ValueIdSet* const arrangedBy_;

  // ---------------------------------------------------------------------
  // The output rows are required to be ordered by the given columns.
  // ---------------------------------------------------------------------
  const ValueIdList* const orderedBy_;

  // ---------------------------------------------------------------------
  // The type of sorted order needed: NO_SOT, ESP_NO_SORT_SOT, 
  // ESP_VIA_SORT_SOT, DP2_SOT, ESP_SOT, DP2_OR_ESP_NO_SORT_SOT
  // ---------------------------------------------------------------------
  SortOrderTypeEnum sortOrderTypeReq_;

  // ---------------------------------------------------------------------
  // The required physical partitioning for a sort order type of DP2 to
  // be valid.
  // ---------------------------------------------------------------------
  PartitioningRequirement* dp2SortOrderPartReq_;

  // ---------------------------------------------------------------------
  // Indicates whether any required order or arrangement is a logical one.
  // This flag will be TRUE if the current location is DP2, and there is
  // a required order or arrangement that came from an operator that is
  // not in DP2. A logical order or arrangement requirement has 
  // different rules as to whether the spp satisfies it. See the     
  // "satisfied" method for details.
  // ---------------------------------------------------------------------
  NABoolean logicalOrderOrArrangement_;

  // ---------------------------------------------------------------------
  // The number of instances of a plan fragment that shall execute
  // concurrently, in parallel.
  // ---------------------------------------------------------------------
  const Lng32 availableCPUs_;
  const Lng32 pipelinesPerCPU_;

  // ---------------------------------------------------------------------
  // Specification of the location where the plan must execute.
  // ---------------------------------------------------------------------
  const PlanExecutionEnum location_;

  // ---------------------------------------------------------------------
  // The partition requirement describes the characteristics of the 
  // data streams that are to be produced as output by using a 
  // built-in (system-defined) partitioning requirement. The destination
  // for the data streams could either be a partitioned file set or 
  // even be a set of ESP's. The absence of a partitioning requirement
  // implies that a single output stream must be produced.
  //
  // partReq_->getCountOfPartitions() specifies the number
  // of data streams that must be produced as output. The distribution
  // of rows amongst these data streams is dependant upon information
  // contained in the partitioning requirement.
  //
  // partReq_->getPartitioningKey() yields a set of expressions that 
  // form the partitioning key. The application of the partitioning
  // function to the values contained in the partitioning key columns 
  // decides the data stream (partition number) to which a certain row
  // is assigned.
  // ---------------------------------------------------------------------
  PartitioningRequirement* partReq_;

  // ---------------------------------------------------------------------
  // The logical partitioning requirement applies to contexts that
  // execute in DP2. In this case, logicalPartReq_ describes the
  // requirements of the PA or PAPA exchange above. This helps the
  // DP2 leaf node (scan, insert, update, delete) to perform "logical
  // partitioning", meaning to deal with the fact that multiple PAs or
  // ESPs will share the work for the operation.
  // ---------------------------------------------------------------------
  LogicalPartitioningRequirement *logicalPartReq_;
       
  // ---------------------------------------------------------------------
  // Requirement for matching a given tree shape
  // ---------------------------------------------------------------------
  RelExpr* mustMatch_;

  // PushDown requirement, if any.
  const PushDownRequirement* pushDownRequirement_;

  NABoolean noEspExchangeRequirement_;
  NABoolean ocbEnabledCostingRequirement_;

}; // ReqdPhysicalProperty

// this class collects fragment-wise memory related information
class CurrentFragmentBigMemoryProperty : public NABasicObject
{
public:
   CurrentFragmentBigMemoryProperty():
    currentFileSize_(0),
    cumulativeFileSizeofFragment_(0),
    noBigMemOpsSoFar_(0),
    Op_(NO_OPERATOR_TYPE)
   {};
   virtual ~CurrentFragmentBigMemoryProperty() {};

   void setCurrentFileSize(double d)
    { currentFileSize_=d;
      cumulativeFileSizeofFragment_=d;}

   double getCumulativeFileSize() 
   { return cumulativeFileSizeofFragment_; }

   void incrementCumulativeMemSize(double d)
   { cumulativeFileSizeofFragment_+=d;}

   void setOperatorType(OperatorTypeEnum op)
    { Op_ = op;}

private:
   double currentFileSize_;
   double cumulativeFileSizeofFragment_;
   Int32    noBigMemOpsSoFar_;
   OperatorTypeEnum    Op_;
};


// required push down property

class PushDownCSProperty;
class PushDownColocationProperty;

//
// PushDown property abstract class, which defines the interface
// for producing push-down property and generating push-down 
// requirement. 
//
class PushDownProperty : public NABasicObject
{

public:
   PushDownProperty() {};
   virtual ~PushDownProperty() {};

   // is this propery fully specified?
   virtual NABoolean isEmpty() const = 0;

   // generating a requirement from a propery.
   // used by various createContextForAChild() to echo the
   // requirement to the right child, given the push-down
   // property from the left child.
   virtual const PushDownRequirement* makeRequirement() const = 0;

   // dynamic type checking help function for PushDownColocationProperty
   virtual const PushDownColocationProperty* 
      castToPushDownColocationProperty() const { return NULL; };

   // dynamic type checking help function for PushDownCSProperty
   virtual const
   PushDownCSProperty* castToPushDownCSProperty() const { return NULL; };

private:
};

//
// Push-down colocation checking property.
//
class PushDownColocationProperty : public PushDownProperty
{

public:
   PushDownColocationProperty(const NodeMap* map = 0) : map_(map) {};
   virtual ~PushDownColocationProperty() {};

   const NodeMap* getNodeMap() const { return map_; };
   NABoolean isEmpty() const { return map_ == 0; };

   // generate a PushDownColocationRequirement from the property.
   const PushDownRequirement* makeRequirement() const;

   const PushDownColocationProperty* 
      castToPushDownColocationProperty() const { return this; };

private:
   const NodeMap* map_;
};

//
// Compound statement push down property.
//
class PushDownCSProperty : public PushDownColocationProperty
{

public:
   PushDownCSProperty(const PartitioningFunction* func = 0,
                    const SearchKey* key = 0) :
      PushDownColocationProperty( (func)? func->getNodeMap() : 0),
      partFunc_(func), searchKey_(key) {};
   ~PushDownCSProperty() {};

   // get data members
   const SearchKey* getSearchKey() const { return searchKey_; };
   const PartitioningFunction* getPartFunc() const { return partFunc_; };

   // partFunc will never be NULL for a concrete CS push-down
   // property. searchKey could be empty (e.g., "select * from t" 
   // where t is a single partitioned table)
   NABoolean isEmpty() const { return partFunc_ == 0; };

   // generating a CS push-down requirement.
   const PushDownRequirement* makeRequirement() const;

   // dynamic type checking help function
   const PushDownCSProperty* castToPushDownCSProperty() const { return this; };

private:
   const PartitioningFunction* partFunc_;
   const SearchKey* searchKey_;
};


// Push down requirement (physical always)
class PushDownCSRequirement;
class PushDownColocationRequirement;

//
// PushDown requirement abstract class, which defines the interface
// for verifying whether a push-down property satisfies a push-down 
// requirement.
//
class PushDownRequirement : public NABasicObject
{
public:
   PushDownRequirement() {};
   virtual ~PushDownRequirement() {};

   // check the null state of the requirement (is the requirement fully
   // specified?).
   virtual NABoolean isEmpty() const = 0;

   // verifying a requirement is met by a property.
   virtual NABoolean satisfied(const PushDownProperty&) const = 0;

   // dynamic type checking on PushDownColocationRequirement.
   virtual const PushDownColocationRequirement* 
      castToPushDownColocationRequirement() const { return NULL; };

   // dynamic type checking on PushDownCSRequirement.
   virtual const PushDownCSRequirement* 
      castToPushDownCSRequirement() const { return NULL; };

   virtual COMPARE_RESULT compare(const PushDownRequirement &other) const = 0;

private:
};

//
// Colocation requirement class hierarchy.
//
class PushDownColocationRequirement : public PushDownRequirement
{
public:
   PushDownColocationRequirement(const NodeMap* map = NULL) : map_(map) {};
   ~PushDownColocationRequirement() {};

   // The data member access function
   const NodeMap* getNodeMap() const { return map_; };

   NABoolean isEmpty() const { return map_ == NULL; };

   NABoolean satisfied(const PushDownProperty&) const;

   const PushDownColocationRequirement* 
      castToPushDownColocationRequirement() const { return this; };

   // test whether an instance of PushDownRequirement class is
   // actually a PushDownColocationRequirement.
   static NABoolean isInstanceOf(const PushDownRequirement* x)
     { return (x AND x->castToPushDownColocationRequirement()); };

   COMPARE_RESULT compare(const PushDownRequirement &other) const;

private:
   const NodeMap* map_;
};

//
// Compound statement push down requirement class hierarchy.
//
class PushDownCSRequirement : public PushDownColocationRequirement
{
public:
   PushDownCSRequirement(const PartitioningFunction* func = NULL, 
		    const SearchKey* key = NULL) :
      PushDownColocationRequirement((func)? func->getNodeMap() : NULL),
      partFunc_(func), searchKey_(key) {};

   ~PushDownCSRequirement() {};

   // data member access functions
   const SearchKey* getSearchKey() const { return searchKey_; };
   const PartitioningFunction* getPartFunc() const { return partFunc_; };

   // partFunc will never be NULL for a concrete CS push-down 
   // requirement
   NABoolean isEmpty() const { return partFunc_ == NULL; };

   NABoolean satisfied(const PushDownProperty&) const;

   const PushDownCSRequirement* 
      castToPushDownCSRequirement() const { return this; };

   // test whether an instance of PushDownRequirement class is
   // actually a PushDownCSRequirement.
   static NABoolean isInstanceOf(const PushDownRequirement* x)
     { return (x AND x->castToPushDownCSRequirement()); };

   COMPARE_RESULT compare(const PushDownRequirement &other) const;

private:
   const PartitioningFunction* partFunc_;
   const SearchKey* searchKey_;
};



// -----------------------------------------------------------------------
// Input physical properties
//
// Used by an operator to specify to its child any physical information
// concerning the parent, ancestors, or siblings that could be helpful
// in costing the current operator. It is currently only used by       
// nested join to pass physical information about the left child to the
// right child. If assumeSortedForCosting_ is set then all other fields will be NULL
// and if any of the nj... fields are set assumeSortedForCosting_ is FALSE.
// -----------------------------------------------------------------------

class InputPhysicalProperty : public NABasicObject
{
  public:
    
    // default and standard constructor
    InputPhysicalProperty(
       const ValueIdSet & outerCharOutputs,
       const ValueIdList* const outerOrder = NULL,
       const PartitioningFunction* const outerOrderPartFunc = NULL,
       const PartitioningFunction* const dp2SortOrderPartFunc =NULL,
       const NABoolean assumeSortedForCosting = FALSE,
	   NABoolean explodedOcbJoinForCosting = FALSE)
      : njOuterCharOutputs_(outerCharOutputs),
        njOuterOrder_(outerOrder),
        njOuterOrderPartFunc_(outerOrderPartFunc),
        njDp2OuterOrderPartFunc_(dp2SortOrderPartFunc),
	assumeSortedForCosting_(assumeSortedForCosting),
        njOuterPartFuncForNonUpdates_(outerOrderPartFunc),
		explodedOcbJoinForCosting_(explodedOcbJoinForCosting)
    {}
	// Constructor especially for Exploded Nested Join
	InputPhysicalProperty(
        const NABoolean assumeSortedProbesForCosting,
        NABoolean explodedOcbJoinForCosting = FALSE)
        :  assumeSortedForCosting_(assumeSortedProbesForCosting),
           explodedOcbJoinForCosting_(explodedOcbJoinForCosting),
           njOuterCharOutputs_(NULL),
           njOuterOrder_(NULL),
           njOuterOrderPartFunc_(NULL),
           njOuterPartFuncForNonUpdates_(NULL),
           njDp2OuterOrderPartFunc_(NULL)
    {}
    InputPhysicalProperty(
        const NABoolean assumeSortedProbesForCosting,
        const PartitioningFunction* const njOuterPartFunc,
		NABoolean explodedOcbJoinForCosting = FALSE)
        :  assumeSortedForCosting_(assumeSortedProbesForCosting),
           njOuterPartFuncForNonUpdates_(njOuterPartFunc),
		   explodedOcbJoinForCosting_(explodedOcbJoinForCosting),
           njOuterCharOutputs_(NULL),
           njOuterOrder_(NULL),
           njOuterOrderPartFunc_(NULL),
           njDp2OuterOrderPartFunc_(NULL)
    {}


    // copy constructor
    InputPhysicalProperty(const InputPhysicalProperty& other)
      : njOuterCharOutputs_(other.njOuterCharOutputs_),
        njOuterOrder_(other.njOuterOrder_),
        njOuterOrderPartFunc_(other.njOuterOrderPartFunc_),
        njDp2OuterOrderPartFunc_(other.njDp2OuterOrderPartFunc_),
	assumeSortedForCosting_(other.assumeSortedForCosting_),
        njOuterPartFuncForNonUpdates_(other.njOuterPartFuncForNonUpdates_),
		explodedOcbJoinForCosting_(other.explodedOcbJoinForCosting_)
    {}

    // destructor
    virtual ~InputPhysicalProperty();

    // Accessors
    const ValueIdSet& getNjOuterCharOutputs() const
      { return njOuterCharOutputs_; }

    const ValueIdList* getNjOuterOrder() const
      { return njOuterOrder_; }

    const PartitioningFunction* getNjOuterOrderPartFunc() const
      { return njOuterOrderPartFunc_; }

    const PartitioningFunction* getNjDp2OuterOrderPartFunc() const
      { return njDp2OuterOrderPartFunc_; }

    NABoolean getAssumeSortedForCosting() const
      { return assumeSortedForCosting_; }


    // Comparison method for use when comparing contexts
    COMPARE_RESULT compareInputPhysicalProperties(
                     const InputPhysicalProperty& other) const;

    const PartitioningFunction* getNjOuterOrderPartFuncForNonUpdates() const
      { return njOuterPartFuncForNonUpdates_;}
    NABoolean getExplodedOcbJoinForCosting() const
      { return explodedOcbJoinForCosting_; }

  private:

    // Used to pass the characteristic outputs from the left child
    // of a nested join to the right child. This is so the right
    // child can determine what its equijoin columns are.
    const ValueIdSet  njOuterCharOutputs_;

    // Used to pass the synthesized sort key of the left child of
    // a nested join to the right child for costing purposes.
    const ValueIdList * njOuterOrder_;

    // Used to pass the synthesized logical partitioning function 
    // of the left child of a nested join to the right child for
    // costing purposes.
    const PartitioningFunction* njOuterOrderPartFunc_;


    // Used to pass the synthesized physical partitioning function
    // of the left child access path to the right child, if the
    // sort order type of the left child's sort key was "dp2", 
    // for costing purposes.
    const PartitioningFunction* njDp2OuterOrderPartFunc_;

    // we want to find partition function even when order is not 
    // important. See case2 comment for assumeSortedForCosting_ below.
    const PartitioningFunction* njOuterPartFuncForNonUpdates_;

    // assumeSortedForCosting_ flag is set for two cases:
    // case 1: when input is rowset.
    // Used to pass information that the left child is an Unpack node
    // that is being used to flow input rowsets. We will assume that input rowsets 
    // are sorted with respect to whatever access path is being considered for the
    // right child. This assumption is made only for costing, and not to detrmine the
    // plan. This assumption will help us choose "optimistic" plans for rowset input,
    // assuming that rowset input is appropriately sorted, even though it may not be,
    // as we have no way to infer the sort order of the input rowset.
    // In this case njOuterPartFuncForNonUpdates_ will always NULL.

    // case 2: when left child partFunc njOuterPartFuncForNonUpdates_ is passed for 
    // NJ plan 0. This is only for cost estimation of exchange operator.
    // In this case njOuterPartFuncForNonUpdates_ will always be non-NULL.
    const NABoolean assumeSortedForCosting_ ;
    
	NABoolean explodedOcbJoinForCosting_ ;
}; // InputPhysicalProperty

#endif /* PHYPROP_HDR */



