#ifndef _CEGOPREDICATE_H_INCLUDED_
#define _CEGOPREDICATE_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoPredicate.h
// ---------------
// Cego predicate structure class definition
//          
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2025 Bjoern Lemke
//
// INTERFACE MODULE
//
// Class: CegoPredicate
// 
// Description: The CegoPredicate class is a container class for the query predicate representation
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// LFC INCLUDES
#include <lfcbase/Chain.h>
#include <lfcbase/Matcher.h>
#include <lfcbase/SetT.h>
#include <lfcxml/Element.h>

// CEGO INCLUDES
#include "CegoComparison.h"
#include "CegoExpr.h"

class CegoQueryManager;
class CegoSelect;
class CegoCondition;

class CegoPredicate {
    
public:
    
    enum CompMode { EXPRONLY, EXPRCOMP, EXISTSCOMP, ISLIKE, ISNOTLIKE, ISNCLIKE, ISNOTNCLIKE, IN, NOTIN, INSUB, NOTINSUB, NULLCOMP, NOTNULLCOMP, NOTPRED, BETWEEN, CONDITION };
        
    CegoPredicate(char* buf);
    CegoPredicate(const CegoPredicate& p);
    CegoPredicate(CegoExpr *pExpr1, CegoExpr *pExpr2, const CegoComparison& comp);
    CegoPredicate(CegoExpr *pExpr1, CegoExpr *pExpr2, CegoExpr *pExpr3);
    CegoPredicate(CegoExpr *pExpr1, const Chain& pattern, bool isNegated, bool isCaseSensitive);
    CegoPredicate(CegoCondition* pC);
    CegoPredicate(CegoPredicate* pNotPred);
    CegoPredicate(CegoSelect* pSelect);
    CegoPredicate(CegoExpr *pExpr, ListT<CegoExpr*>& exprList, bool isNegated);
    CegoPredicate(CegoExpr *pExpr, CegoSelect* pSelect, bool isNegated);
    CegoPredicate(CegoExpr *pExpr, bool isNull);
    CegoPredicate(CegoExpr *pExpr);
    
    ~CegoPredicate();

    void setQueryManager(CegoQueryManager* pTabMng);
    void setTabSetId(unsigned tabSetId);

    void getPlanList(ListT<Element*>& planList);

    CegoExpr* getExpr1();
    CegoExpr* getExpr2();
    CegoExpr* getExpr3();
    ListT<CegoExpr*>& getExprList();
    CegoCondition* getCondition();
    CegoPredicate* getNotPred();
    CegoComparison getComparison();
    const Chain& getPattern() const;

    void liftCondition();
    
    void analyzeSelect();
    CegoSelect* getSelectQuery();
    void getSelectQueryList(ListT<CegoSelect*>& queryList);
    CompMode getMode();

    void setChecked(bool val);
    void setCheckedRec(bool val);
    bool isChecked() const;

    bool isCursorPred() const;
    
    bool prioOnJoin() const;
    bool hasOrCond() const;
    void clearAttrCache();
    void cleanUp();

    bool match(const CegoFieldValue& val);
    SetT<Chain> getTableRefSet() const;
    ListT<CegoAttrDesc*> getAttrRefList() const;
    void getFieldList(ListT<CegoField>& fl, ListT<CegoField>** pFLA) const;
    unsigned evalReferences(CegoContentObject *pCO, const ListT<CegoField>& fl);
    ListT<CegoAggregation*> getAggregationList();
    
    void setAggregationValue(ListT<CegoField>& jfl);

    bool eval(ListT<CegoField>** pParentJoinBuf,
	      unsigned parentJoinBufPos,
	      ListT<CegoField>** pJoinBuf,
	      unsigned pos,
	      CegoProcBlock *pBlock);


    
    CegoPredicate* clone(bool isAttrRef = false);
    Chain getId(CegoProcBlock *pBlock) const;
    Chain toChain(unsigned defTabSetId, const Chain& indent = Chain("")) const;
    Chain dbFormat(CegoDatabaseFormater *pForm);

    void encode(char *buf, CegoProcBlock *pBlock);
    void decode(char *buf);
    unsigned getEncodingLength(CegoProcBlock *pBlock = 0) const;

    CegoPredicate& operator = ( const CegoPredicate& p);
    friend ostream& operator << (ostream& s, const CegoPredicate& p);

    CegoField evalField(const ListT<CegoField>& fl, bool graceful) const;

    CegoPredicate* map(const Chain& viewAlias, ListT<CegoExpr*> exprList) const;

    CegoFieldValue getExprOnlyValue() const;

    CegoPredicate* getReduced(const Chain& tableAlias) const;
    CegoPredicate* getReduced(const ListT<Chain>& aliasList) const;
    
private:

    CompMode _mode;
    CegoExpr* _pExpr1; 
    CegoExpr* _pExpr2;
    CegoExpr* _pExpr3;
    ListT<CegoExpr*> _exprList;
    CegoComparison _comp;
    CegoCondition* _pC;
    CegoPredicate* _pNotPred;
    Matcher* _pMatcher;
    Chain _pattern;
    CegoSelect *_pSelect;
    bool _isChecked;

    CegoFieldValue _exprOnlyVal;

    bool evalFields(CegoComparison comp, const CegoFieldValue& f1, const CegoFieldValue& f2);
    bool evalBetween(const CegoFieldValue& f1, const CegoFieldValue& f2, const CegoFieldValue& f3);
    
    void setAggregationValueForExpr(CegoExpr* pExpr, ListT<CegoField>& jfl);

    CegoExpr* mapExpr(const Chain& viewAlias, const ListT<CegoExpr*>& exprList, CegoExpr* pExpr) const;
    CegoExpr* reduceExpr(const ListT<Chain>& aliasList, CegoExpr* pExpr) const;
    
};
#endif
