/**********************************************************************
// @@@ 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 RELSET_H
#define RELSET_H
/* -*-C++-*-
******************************************************************************
*
* File:         RelSet.h
* Description:  Relational set operations (both physical and logical operators)
* Created:      4/28/94
* Language:     C++
*
*
*
*
******************************************************************************
*/


#include "ObjectNames.h"
#include "RelExpr.h"
#include "Rel3GL.h"

// -----------------------------------------------------------------------
// contents of this file
// -----------------------------------------------------------------------
class Union;
class Intersect;
class Except;

// The following are physical operators
class MergeUnion;

// -----------------------------------------------------------------------
// forward references
// -----------------------------------------------------------------------
class LogicalProperty;
class BindWA;
class Generator;
class AssignmentStArea;

// -----------------------------------------------------------------------
// Intersect Operator
// -----------------------------------------------------------------------

class Intersect : public RelExpr
{
public:
  // constructor
  Intersect(RelExpr *leftChild,
	RelExpr *rightChild);

  // virtual destructor
  virtual ~Intersect();

  // get the degree of this node (it is a binary op).
  virtual Int32 getArity() const;

  const NAString getText() const;

  virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, CollHeap* outHeap = 0);

  // a virtual function for performing name binding within the query tree
  virtual RelExpr * bindNode(BindWA *bindWAPtr);
};



// Except Operator
// -----------------------------------------------------------------------

class Except: public RelExpr
{
public:
  // constructor
  Except(RelExpr *leftChild,
	RelExpr *rightChild);

  // virtual destructor
  virtual ~Except();

  // get the degree of this node (it is a binary op).
  virtual Int32 getArity() const;

  const NAString getText() const;

  virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL, CollHeap* outHeap = 0);

  // a virtual function for performing name binding within the query tree
  virtual RelExpr * bindNode(BindWA *bindWAPtr);
};


// -----------------------------------------------------------------------
// Union Operator:
//
// What we call "Union" here is what is called "UNION ALL" in SQL. To
// achieve a true union a la Codd, a duplicate elimination (see class
// GroupByAgg) is needed above the union node.
// -----------------------------------------------------------------------
class UnionMap : public NABasicObject
{
  friend class Union;
  friend class MergeUnion;

  // The union map is a data struture that is shared by a number
  // of Union nodes that need to do the same mappings of values
  // from parent expressions to children expressions.
  // It is intended to be accessible only from Union methods.
private:

  // Constructor
  UnionMap() : count_(1)
  {}

  // copy ctor
  UnionMap (const UnionMap & rhs) :
       colMapTable_(rhs.colMapTable_),
       leftColMap_ (rhs.leftColMap_),
       rightColMap_(rhs.rightColMap_),
       count_(rhs.count_)
  {}

  // normalize all the expressions in the maps that are contributed
  // by the child, whose index is childIndex, in the map.
  void normalizeSpecificChild(NormWA & normWARef, Lng32 childIndex);

  // The map table contains a list of item expressions, where each item
  // expression is a ValueIdUnion that points to two Value Ids from the
  // left and right child. This list implements a mapping table indicating
  // how the columns of the left child and right child map the result
  // columns.
  ValueIdList colMapTable_;

  // two value id maps that contain the identical information as in
  // colMapTable_, for easier mapping
  ValueIdMap leftColMap_;
  ValueIdMap rightColMap_;

  // Reference Count
  Lng32 count_;
};

class AssignmentStHostVars;

class Union : public RelExpr
{

public:

  // constructor
  Union(RelExpr  *leftChild,
	RelExpr  *rightChild,
	UnionMap *colMapTable = NULL,
	ItemExpr *condExpr = NULL,
	OperatorTypeEnum otype = REL_UNION,
	CollHeap *outHeap = CmpCommon::statementHeap(),
    NABoolean sysGenerated = FALSE,
    NABoolean mayBeCacheable = FALSE
  );

  // copy ctor
  Union (const Union &) ; // not written

  // virtual destructor
  virtual ~Union();

  // get the degree of this node (it is a binary op).
  virtual Int32 getArity() const;

  // a virtual function for performing name binding within the query tree
  virtual RelExpr * bindNode(BindWA *bindWAPtr);

  // accessor functions
  // Provide a short-lived read-write access to the contents ofthe colMapTable_
  inline ValueIdList & colMapTable()             { return unionMap_->colMapTable_; }
  inline const ValueIdList & colMapTable() const { return unionMap_->colMapTable_; }
  inline ValueIdMap & getLeftMap()               { return unionMap_->leftColMap_; }
  inline ValueIdMap & getLeftMap() const         { return unionMap_->leftColMap_; }
  inline ValueIdMap & getRightMap()              { return unionMap_->rightColMap_; }
  inline ValueIdMap & getRightMap() const        { return unionMap_->rightColMap_; }
// warning elimination (removed "inline")
  ValueIdMap & getMap(Lng32 i)
  {
    CMPASSERT(i == 0 OR i == 1);
    if (i == 0) return unionMap_->leftColMap_;
    else return unionMap_->rightColMap_;
  }
  inline UnionMap * getUnionMap()       { return unionMap_; }

  void addValueIdUnion(ValueId vidUnion, CollHeap* heap);

  // This method rewrites unionExpr in terms of the values produced
  // produced by the left and the right children and returns
  // them in the sets exprForLeftChild and exprForRightChild
  // respectively.
  void rewriteUnionExpr(const ValueIdSet & unionExpr,
			ValueIdSet & exprForLeftChild,
			ValueIdSet & exprForRightChild) const;

  // 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
  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.
  virtual RelExpr * normalizeNode(NormWA & normWARef);

  virtual RelExpr * semanticQueryOptimizeNode(NormWA & normWARef);

  // Method to push down predicates from a Union node into the
  // children
  virtual
  void pushdownCoveredExpr(const ValueIdSet & outputExprOnOperator,
                           const ValueIdSet & newExternalInputs,
                           ValueIdSet& predOnOperator,
			   const ValueIdSet * nonPredExprOnOperator = NULL,
                           Lng32 childId = (-MAX_REL_ARITY) );

  // The set of values that I can potentially produce as output.
  virtual void getPotentialOutputValues(ValueIdSet & vs) const;

  // methods for common subexpressions
  virtual NABoolean prepareTreeForCSESharing(
       const ValueIdSet &outputsToAdd,
       const ValueIdSet &predicatesToRemove,
       const ValueIdSet &commonPredicatesToAdd,
       const ValueIdSet &inputsToRemove,
       ValueIdSet &valuesForVEGRewrite,
       ValueIdSet &keyColumns,
       CSEInfo *info);

  // ---------------------------------------------------------------------
  // Function for testing the eligibility of this
  // Union to form a plan using the given required physical properties.
  // This method is called by UnionRule::topMatch().
  // ---------------------------------------------------------------------
  NABoolean rppAreCompatibleWithOperator
              (const ReqdPhysicalProperty* const rppForUnion) const;

  // ---------------------------------------------------------------------
  // Union::createPartitioningRequirement()
  // It is not declared as a const method because it can supply the
  // ValueIdMap, colMapTable(), for copying and rewriting the
  // partitioning requirement.
  // ---------------------------------------------------------------------
  PartitioningRequirement* createPartitioningRequirement
                           (const ReqdPhysicalProperty* const rppForUnion,
			    Lng32 currentChildIndex);

  virtual HashValue topHash();
  virtual NABoolean duplicateMatch(const RelExpr & other) const;
  virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL,
				CollHeap* outHeap = CmpCommon::statementHeap());

  // method to do code generation
  virtual short codeGen(Generator*);

  // synthesize logical properties
  virtual void synthLogProp(NormWA * normWAPtr = NULL);
  virtual void synthEstLogProp(const EstLogPropSharedPtr& inputEstLogProp);

  virtual void addLocalExpr(LIST(ExprNode *) &xlist,
			    LIST(NAString) &llist) const;

  // get a printable string that identifies the operator
  const NAString getText() const;

  // adds information about this node to the Explain tree
  ExplainTuple *addSpecificExplainInfo(ExplainTupleMaster *explainTuple,
					      ComTdb * tdb,
					      Generator *generator);


// merge of R1.5 to R2, renumbered
  enum UnionFlags {
    UNION_NONE		= 0x000,
    UNION_ORDERED	= 0x001,
    UNION_COND_UNARY	= 0x002,
    UNION_COND_EMPTY_IFELSE	= 0x004,        // set when ELSE part IF statement
                                                // is missing or empty
    UNION_FOR_IF	= 0x008,
    UNION_DISTINCT	= 0x010,		// Ansi SQL default, opp. of "UNION ALL"
    UNION_COND_EMPTY_IFTHEN = 0x020,            // set when we see
                                                // IF (expression) THEN
                                                //  BEGIN   END ;
                                                //  ELSE
                                                //  some sql statement/sqlstatements
                                                //  END IF ;
    UNION_BLOCKED       = 0x040    // UNION_BLOCKED was added for trigger project
  };

  void setSerialUnion()            {isSerialUnion_ = TRUE;}
   NABoolean getSerialUnion() const  {return isSerialUnion_;}

  void setOrderedUnion()	     {flags_ |= UNION_ORDERED;}
  NABoolean getOrderedUnion() const  {return (flags_ & UNION_ORDERED) != 0;}

  void setCondUnary()		     {flags_ |= UNION_COND_UNARY;}
  NABoolean getCondUnary() const     {return (flags_ & UNION_COND_UNARY) != 0;}

  void setCondEmptyIfElse()		     {flags_ |= UNION_COND_EMPTY_IFELSE;}
  NABoolean getCondEmptyIfElse() const     {return (flags_ &UNION_COND_EMPTY_IFELSE) != 0;}

  void setUnionForIF()		     {flags_ |= UNION_FOR_IF;}
  NABoolean getUnionForIF() const    {return (flags_ & UNION_FOR_IF) != 0; }

  void setDistinctUnion()	     {flags_ |= UNION_DISTINCT;}
  NABoolean getDistinctUnion() const {return (flags_ & UNION_DISTINCT) != 0;}

  void setCondEmptyIfThen()	     {flags_ |= UNION_COND_EMPTY_IFTHEN;}
  NABoolean getCondEmptyIfThen() const {return (flags_ & UNION_COND_EMPTY_IFTHEN) != 0;}

  void setUnionFlags(ULng32 f)	{flags_ = f;}
  ULng32 getUnionFlags() const	{return flags_;}
  // UNION_BLOCKED was added for trigger project
  inline void setBlockedUnion(){flags_ = UNION_BLOCKED;}
  inline Int32 getBlockedUnion(){return flags_ == UNION_BLOCKED;}



  // controlFlags were added for trigger project
  // setNoOutput can be applied to OrderUnion or BlockedUnion
  void setNoOutputs();
  inline Int32 hasNoOutputs(){return controlFlags_ & NO_OUTPUTS;}

  // inNotAtomicStmt is applied for unary unions to raise an error during execution
  // if an after trigger is enabled and we are executing a notAtomicStatement.
  void setInNotAtomicStatement()	     {controlFlags_ |= IN_NOT_ATOMIC_STMT;}
  NABoolean getInNotAtomicStatement() const {return (controlFlags_ & IN_NOT_ATOMIC_STMT) != 0;}

  // a blocked union is temporary if it is used to inline
  // a after row trigger (statement MVs too). This union will be
  // removed during optimization.
  void setIsTemporary()	     {controlFlags_ |= IS_TEMPORARY;}
  NABoolean getIsTemporary() const {return (controlFlags_ & IS_TEMPORARY) != 0;}

  inline void setControlFlags(Int32 flg){controlFlags_ = flg;}
  inline Int32 getControlFlags() const {return controlFlags_;}

  void addCondExprTree(ItemExpr *condExpr);
  ItemExpr *getCondExprTree();
  ItemExpr *removeCondExprTree();

  ValueIdList &condExpr()		{return condExpr_;}
  const ValueIdList &condExpr() const	{return condExpr_;}
  ValueIdList getCondExpr()		{return condExpr_;}
  void setCondExpr(ValueIdList condExpr)	{condExpr_ = condExpr;}

  // support methods for the Triggered Action Exception
  void addTrigExceptExprTree(ItemExpr *trigExceptExpr);
  ItemExpr *getTrigExceptExprTree();
  ItemExpr *removeTrigExceptExprTree();

  ValueIdList       &trigExceptExpr()		{return trigExceptExpr_;}
  const ValueIdList &trigExceptExpr() const	{return trigExceptExpr_;}
  ValueIdList       getTrigExceptExpr()		{return trigExceptExpr_;}
  void setTrigExceptExpr(ValueIdList trigExceptExpr)
                                      {trigExceptExpr_ = trigExceptExpr;}

  // These functions are to support functionality of compound statements.
  // Please see documentation of data members below.
  Union * getPreviousIF() { return previousIF_; }
  void setPreviousIF(Union * node) { previousIF_ = node; }
  AssignmentStHostVars *&leftList() { return leftList_; }
  AssignmentStHostVars *&rightList() { return rightList_; }
  short &currentChild() { return currentChild_; }
  AssignmentStHostVars *getCurrentList(BindWA *bindWA);

  // When we are in a CompoundStatement and we have IF statements in it,
  // we must create a RETDesc for this Union node (which is
  // actually an IF node). In this function, we create a list of
  // ValueIdUnion nodes. We figure out which valueids
  // of the left child must be matched with those of the right child
  // (for instance, if SET :a appears in both children) and which must
  // be matched with previously existing valueids (for instance, if
  // SET :a = ... only appears in one branch, then the ValueIdUnion associated
  // with that SET statement must reference the value id of :a that existed before
  // this IF statement).
  RETDesc * createReturnTable(AssignmentStArea *assignArea, BindWA *bindWA);

  //Used only for conditional union. Copies the leftlist and rightlist this conditional
  //union to the leftlist of the conditional union node pointed to by the previousIF argument,
  //if the calling conditional union is in the left subtree of the previousIF conditional union.
  //If the calling conditional union is in the right subtree of the previousIF conditional union
  //then we copy to the rightlist of the previousIF conditional union.
  void copyLeftRightListsToPreviousIF(Union * previousIF, BindWA * bindWA);


  // MV ++
  // MV refresh optimization refer to MVRefreshBuilder.cpp
  // MultiTxnMavBuilder::buildUnionBetweenRangeAndIudBlocks()
  // THIS OPTIMIZATION IS FOR MV REFRESH ONLY AND IS BASED ON THE KNOWLEDGE THAT RANGES RECORDS
  // IN THE RANGE LOG DO NOT OVERLAPPED
  void addAlternateRightChildOrderExprTree(ItemExpr *alternateRightChildOrderExprTree);
  ItemExpr *removeAlternateRightChildOrderExprTree();

  inline ValueIdList &alternateRightChildOrderExpr() {return alternateRightChildOrderExpr_;}
  inline const ValueIdList &alternateRightChildOrderExpr() const {return alternateRightChildOrderExpr_;}
  inline ValueIdList getAlternateRightChildOrderExpr() {return alternateRightChildOrderExpr_;}
  inline void setAlternateRightChildOrderExpr(ValueIdList alternateRightChildOrderExpr)
  {
    alternateRightChildOrderExpr_ = alternateRightChildOrderExpr;
  }
  // MV --

  // added for trigger project, to activate after trigger transformation
  virtual RelExpr * fixupTriggers(NABoolean & treeModified);

  // check for & warn against UNIONs that have inconsistent access/lock modes
  void checkAccessLockModes();

  // append an ascii-version of Union into cachewa.qryText_
  void generateCacheKey(CacheWA &cwa) const;

private:
 // controlFlags were added for trigger project
  enum controlFlags { NO_OUTPUTS = 0x0001,
		      IN_NOT_ATOMIC_STMT = 0x0002,
		      IS_TEMPORARY = 0x0004};

  // ---------------------------------------------------------------------
  // Union::createPartitioningRequirement()
  // It is not declared as a const method because it can supply the
  // ValueIdMap, equiJoinExpressions_, for copying and rewriting the
  // partitioning function to match. The rewrite requires a read-write
  // access to the ValueIdMap (interfaces supported by class ValueIdMap).
  // ---------------------------------------------------------------------
  PartitioningFunction* createPartitioningRequirement
                           (const ReqdPhysicalProperty* const rppForUnion,
                            const PartitioningFunction* const partFuncToMatch,
			    Lng32 currentChildIndex,
                            Lng32 currentPlanNumber);

  // MV --
  // A debugging method for dumping the columns in the RETDesc of both
  // children when they do not match.
  void dumpChildrensRETDescs(const RETDesc& leftTable,
		             const RETDesc& rightTable);

  // Conditional union expression.
  ItemExpr *condExprTree_;
  ValueIdList condExpr_;

  // expression used by triggeres to implement the ANSI
  // triggered action exception.
  ItemExpr *trigExceptExprTree_;
  ValueIdList trigExceptExpr_;

  // MV ++
  ItemExpr *alternateRightChildOrderExprTree_;
  ValueIdList alternateRightChildOrderExpr_;
  // MV --

  // The union map is shared by a number of Union nodes that were
  // transformed from one another
  UnionMap *unionMap_;

  // see unionFlags
  ULng32 flags_;

  // We keep a list of all variables that appear on the left side of a SET
  // statement and that appear below this Union node. Please see compound
  // statements documentation. In this way, we can keep track of SET statements
  // that appear within IF statements
  LIST(HostVar *) variablesSet_;

  // We keep a pointer to the closest Union node that is an ancestor of this
  // one. This is to support functionality for compound statements, in particular
  // for SET statements within IF statements.
  Union *previousIF_;

  // These lists contain all the variables that have been SET in the left and
  // right childs, respectively
  AssignmentStHostVars * leftList_;
  AssignmentStHostVars * rightList_;

  // Child we are currently visiting
  short currentChild_;

  //++ Triggers -
  // see controlFlags
  Int32 controlFlags_;

  // true iff this Union is system-generated (ie, is not user-specified)
  NABoolean isSystemGenerated_;

  NABoolean isSerialUnion_;
};

// -----------------------------------------------------------------------
// physical Union node
// -----------------------------------------------------------------------
class MergeUnion : public Union
{
public:

  // constructor
// warning elimination (removed "inline")
  MergeUnion(RelExpr *leftChild,
		    RelExpr *rightChild,
		    UnionMap *unionMap = NULL,
		    OperatorTypeEnum otype = REL_MERGE_UNION,
		    CollHeap *oHeap = CmpCommon::statementHeap())
  : Union(leftChild, rightChild, unionMap, NULL, otype, oHeap),
    mergeExpr_(NULL) {}

  // copy ctor
  MergeUnion (const MergeUnion &) ; // not written

  // virtual destructor
  virtual ~MergeUnion();

  virtual NABoolean isLogical () const;
  virtual NABoolean isPhysical() const;

  virtual HashValue topHash();
  virtual NABoolean duplicateMatch(const RelExpr & other) const;
  virtual RelExpr * copyTopNode(RelExpr *derivedNode = NULL,
				CollHeap* outHeap = CmpCommon::statementHeap());

  // Cascades-related functions
  virtual CostMethod* costMethod() const;
  virtual Context* createContextForAChild(Context* myContext,
                     PlanWorkSpace* pws,
                     Lng32& childIndex);
  virtual NABoolean findOptimalSolution(Context* myContext,
                                        PlanWorkSpace* pws);
  virtual PhysicalProperty *synthPhysicalProperty(const Context *context,
                                                  const Lng32    planNumber,
                                                  PlanWorkSpace  *pws);

  // Helper function for plan generation.
  Context* createChildContext(Context* context, PlanWorkSpace* pws,
			      Lng32 childIndex);

  // handling sort order and merge expression
  inline const ValueIdList &getSortOrder()          { return sortOrder_; }
  void setSortOrder(const ValueIdList &newSortOrder);
  inline ItemExpr *getMergeExpr() const             { return mergeExpr_; }

  // method to do code generation
  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);

  // add all the expressions that are local to this
  // node to an existing list of expressions (used by GUI tool)
  virtual void addLocalExpr(LIST(ExprNode *) &xlist,
			    LIST(NAString) &llist) const;

// Given an input synthesized child sort key, a required arrangement,
// and a input required sort order (if any), generate a new sort key
// that has all the expressions in the required sort key and required
// arrangement, and only those expressions, in an order that matches
// the child sort key.  Return this new sort key, which can then be used
// as a sort key requirement for the other child of the union or as the
// synthesized union sort key after being mapped.
  void synthUnionSortKeyFromChild (const ValueIdList &childSortKey,
                                   const ValueIdSet &reqArrangement,
                                   ValueIdList &unionSortKey) const;

  // -----------------------------------------------------------------------
  // Performs mapping on the partitioning function, from the union to the
  // designated child.
  // -----------------------------------------------------------------------
  virtual PartitioningFunction* mapPartitioningFunction(
                          const PartitioningFunction* partFunc,
                          NABoolean rewriteForChild0) ;

  // -----------------------------------------------------------------------
  // This help function tries to make the Union sort key the same
  // length as the arrangement requirement of Union cols. The key
  // can be shorter when some of the Union columns are duplicated.
  //
  // -----------------------------------------------------------------------
  NABoolean finalizeUnionSortKey(const ValueIdList& knownSortKey,  // IN
                            Lng32 knownSide,                   // IN
                            const ValueIdSet& arrCols,        // IN
                            ValueIdList& unionSortKey);       // IN&OUT

private:

  // the sorting order of the union result (if any), expressed in terms
  // of the union's outputs
  ValueIdList sortOrder_;

  // The merge expression is a boolean expression telling which of the
  // children to read next (TRUE means read the left child, FALSE means
  // read the right child). It is used to merge two sorted child streams
  // into a sorted output stream if the expression is (left value <= right).
  ItemExpr *mergeExpr_;

  // a private method to build the merge expression from the sort order
  void buildMergeExpr();
};

#endif /* RELSET_H */





