text: //---------------------------------------------------------------------------
  //	Greenplum Database
  //	Copyright 2011 EMC Corp.
  //
  //	@filename:
  //		CLogicalLeftAntiSemiApply.h
  //
  //	@doc:
  //		Logical Left Anti Semi Apply operator
  //---------------------------------------------------------------------------
  #ifndef GPOPT_CLogicalLeftAntiSemiApply_H
  #define GPOPT_CLogicalLeftAntiSemiApply_H
  
  #include "gpos/base.h"
  #include "gpopt/operators/CLogicalApply.h"
  #include "gpopt/operators/CExpressionHandle.h"
  
  namespace gpopt
  {
  
  
  	//---------------------------------------------------------------------------
  	//	@class:
  	//		CLogicalLeftAntiSemiApply
  	//
  	//	@doc:
  	//		Logical Left Anti Semi Apply operator
  	//
  	//---------------------------------------------------------------------------
  	class CLogicalLeftAntiSemiApply : public CLogicalApply
  	{
  
  		private:
  
  			// private copy ctor
  			CLogicalLeftAntiSemiApply(const CLogicalLeftAntiSemiApply &);
  
  		public:
  
  			// ctor
  			explicit
  			CLogicalLeftAntiSemiApply
  				(
  				CMemoryPool *mp
  				)
  				:
  				CLogicalApply(mp)
  			{}
  
  			// ctor
  			CLogicalLeftAntiSemiApply
  				(
  				CMemoryPool *mp,
  				CColRefArray *pdrgpcrInner,
  				EOperatorId eopidOriginSubq
  				)
  				:
  				CLogicalApply(mp, pdrgpcrInner, eopidOriginSubq)
  			{}
  
  			// dtor
  			virtual
  			~CLogicalLeftAntiSemiApply()
  			{}
  
  			// ident accessors
  			virtual
  			EOperatorId Eopid() const
  			{
  				return EopLogicalLeftAntiSemiApply;
  			}
  
  			// return a string for operator name
  			virtual
  			const CHAR *SzId() const
  			{
  				return "CLogicalLeftAntiSemiApply";
  			}
  
  			// return true if we can pull projections up past this operator from its given child
  			virtual
  			BOOL FCanPullProjectionsUp
  				(
  				ULONG child_index
  				) const
  			{
  				return (0 == child_index);
  			}
  
  			//-------------------------------------------------------------------------------------
  			// Derived Relational Properties
  			//-------------------------------------------------------------------------------------
  
  			// derive output columns
  			virtual
  			CColRefSet *DeriveOutputColumns
  				(
  				CMemoryPool *, // mp
  				CExpressionHandle &exprhdl
  				)
  			{
  				GPOS_ASSERT(3 == exprhdl.Arity());
  
  				return PcrsDeriveOutputPassThru(exprhdl);
  			}
  
  			// derive not nullable output columns
  			virtual
  			CColRefSet *DeriveNotNullColumns
  				(
  				CMemoryPool *,// mp
  				CExpressionHandle &exprhdl
  				)
  				const
  			{
  				return PcrsDeriveNotNullPassThruOuter(exprhdl);
  			}
  
  			// dervive keys
  			virtual 
  			CKeyCollection *DeriveKeyCollection(CMemoryPool *mp, CExpressionHandle &exprhdl) const;
  						
  			// derive max card
  			virtual
  			CMaxCard DeriveMaxCard(CMemoryPool *mp, CExpressionHandle &exprhdl) const;
  
  			// derive constraint property
  			virtual
  			CPropConstraint *DerivePropertyConstraint
  				(
  				CMemoryPool *, //mp,
  				CExpressionHandle &exprhdl
  				)
  				const
  			{
  				return PpcDeriveConstraintPassThru(exprhdl, 0 /*ulChild*/);
  			}
  
  			//-------------------------------------------------------------------------------------
  			// Transformations
  			//-------------------------------------------------------------------------------------
  
  			// candidate set of xforms
  			virtual
  			CXformSet *PxfsCandidates(CMemoryPool *mp) const;
  
  			//-------------------------------------------------------------------------------------
  			//-------------------------------------------------------------------------------------
  			//-------------------------------------------------------------------------------------
  
  			// return true if operator is a left anti semi apply
  			virtual
  			BOOL FLeftAntiSemiApply() const
  			{
  				return true;
  			}
  
  			// return a copy of the operator with remapped columns
  			virtual
  			COperator *PopCopyWithRemappedColumns(CMemoryPool *mp, UlongToColRefMap *colref_mapping, BOOL must_exist);
  
  			// conversion function
  			static
  			CLogicalLeftAntiSemiApply *PopConvert
  				(
  				COperator *pop
  				)
  			{
  				GPOS_ASSERT(NULL != pop);
  				GPOS_ASSERT(CUtils::FLeftAntiSemiApply(pop));
  
  				return dynamic_cast<CLogicalLeftAntiSemiApply*>(pop);
  			}
  
  	}; // class CLogicalLeftAntiSemiApply
  
  }
  
  
  #endif // !GPOPT_CLogicalLeftAntiSemiApply_H
  
  // EOF
  