#ifndef _CEGOSELECT_H_INCLUDED_
#define _CEGOSELECT_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoSelect.h
// ------------
// Cego select query handling
//
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2025 Bjoern Lemke
//
// INTERFACE MODULE
//
// Class: CegoSelect
// 
// Description: This class implements the SQL select query algorithm for the Cego database system 
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// base includes
#include <lfcbase/ListT.h>
#include <lfcbase/SetT.h>
#include <lfcbase/NanoTimer.h>

// xml includes
#include <lfcxml/Element.h>

// cego includes
#include "CegoProcBlock.h"
#include "CegoDefs.h"
#include "CegoFactor.h"
#include "CegoQueryManager.h"
#include "CegoQueryCursor.h"
#include "CegoField.h"
#include "CegoPredicate.h"
#include "CegoCondition.h"
#include "CegoContentObject.h"
#include "CegoOrderSpace.h"
#include "CegoGroupSpace.h"
#include "CegoTerm.h"
#include "CegoExpr.h"
#include "CegoContentObject.h"
#include "CegoQueryCache.h"

class CegoProcBlock;

class CegoSelect {
    
public:

    enum SelectMode { SIMPLE, PLAIN, AGGREGATION, GROUPING };
	
    CegoSelect(char* buf);
    CegoSelect(ListT<CegoContentObject*>& coList,
	       ListT<CegoExpr*>& exprList, 
	       CegoPredicate* pPred,
	       ListT<CegoAttrDesc*> *pGroupList,
	       CegoPredicate* pHavingPred,
	       ListT<CegoExpr*> *pOrderList,
	       ListT<CegoOrderNode::Ordering>* pOrderOptList,
	       bool isDistinct,
	       unsigned rowLimit,
	       CegoQueryManager* pGTM);
    ~CegoSelect();

    void setTableManager(CegoQueryManager* pGTM);
    void setTabSetId(unsigned tabSetId);

    void setUnionSelect(CegoSelect* pUnion);
    void cleanUp();
    void prepare(bool graceful = false);
    void reset();
    Element* getPlan();
    bool nextTuple(ListT<CegoField>& jfl);
    bool isCacheEnabled() const;
    bool isCached() const;
    Chain getQueryId() const;
    void getObjectList( SetT<CegoObject>& objList ) const;
    void checkValidRef();
    void setParentJoinBuf(ListT<CegoField>** pParentJoinBuf = 0);
    void setProcBlock(CegoProcBlock *pBlock);
    unsigned evalExtTableReferences(CegoContentObject* pCO, const ListT<CegoField>& fl);
    CegoPredicate* getPredicate();
    bool hasAliasReference() const;
    void getSchema(ListT<CegoField>& schema);
    Chain toChain(unsigned defTabSetId, const Chain& indent = Chain("")) const;
    Chain dbFormat(CegoDatabaseFormater *pForm) const;
    ListT<CegoAttrDesc*> getAttrRefList() const;
    void getFieldList(ListT<CegoField>& fl, ListT<CegoField>** pFLA) const;

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

    bool setViewCond(const Chain& viewAlias, CegoAttrCond& attrCond, CegoPredicate* pPred, ListT<CegoField> **pFLA);
    unsigned getExtRefCount() const;
    CegoSelect* clone( bool isAttrRef = false);

private:

    void evalSchema(bool graceful);	
    unsigned evalTableReferences(CegoContentObject* pCO, const ListT<CegoField>& fl);
    bool isPrepared() const;
    void analyzeJoin();
    bool nextAggTuple(ListT<CegoField>& jfl);
    bool nextOrderedTuple(ListT<CegoField>& jfl);
    bool nextResultTuple(ListT<CegoField>& jfl, ListT<CegoField>& ofl);
    bool nextGroupedTuple(ListT<CegoField>& jfl);
    bool nextJoinTuple(ListT<CegoField>& jfl, ListT<CegoField>& ofl);
    void createConjunctionList(CegoPredicate* pPred);
    void consolidateConjunctionList();
    void evalReferences();
    void filterRefs(const ListT<CegoField>& inSchema, ListT<CegoField>& outSchema);   
    void filterFacRef(CegoFactor *pFac, const ListT<CegoField>& inSchema, ListT<CegoField>& outSchema);
    void filterExprRef(CegoExpr *pExpr, const ListT<CegoField>& inSchema, ListT<CegoField>& outSchema);
    void filterTermRef(CegoTerm *pTerm, const ListT<CegoField>& inSchema, ListT<CegoField>& outSchema);
    void filterPredRef(CegoPredicate *pP, const ListT<CegoField>& inSchema, ListT<CegoField>& outSchema);
    void filterCondRef(CegoCondition* pC, const ListT<CegoField>& inSchema, ListT<CegoField>& outSchema);
    void filterAttrRef(CegoAttrDesc* pAttrDesc, const ListT<CegoField>& inSchema, ListT<CegoField>& outSchema);    
    void evalSelection(ListT<CegoExpr*>& exprList, ListT<CegoField>** joinBuf, ListT<CegoField>& ol);
    void buildJoinTables();
    void buildJoinRefs();
    void buildJoinConditions();
    void getPredObjectList(CegoPredicate *pPred, ListT<CegoContentObject*>& objectList);
    void getCondObjectList(CegoCondition * pC, ListT<CegoContentObject*>& objectList);
    void initAggregation();
    void aggregateTuple(ListT<CegoField>& aggTuple);
    void evalAggregation(ListT<CegoField>& resultList);
    void prepareOrder();    
    bool matchFieldValue(const CegoFieldValue& fv1, const CegoFieldValue& fv2, CegoComparison comp);    
    void setAggregationValue(CegoExpr *pExpr, ListT<CegoField>& jfl);
    void addObject4CO(CegoContentObject *pCO, SetT<CegoObject>& objList) const;
    void setExtRefCount(unsigned refCount);
    void mergeBuffer();

    void startCaching();
    void finishCaching();
    
    ListT<CegoPredicate*> _viewConjunctionList;
    ListT<CegoPredicate*> _conjunctionList;
    ListT<CegoPredicate*> _consolidationList;
    ListT<CegoExpr*> _exprList;
    CegoPredicate* _pPred;
    ListT<CegoPredicate*> _joinPredList;
    CegoQueryManager* _pGTM;
    ListT<CegoContentObject*> _coList;
    ListT<CegoContentObject*> _joinList;
    ListT<CegoField> _joinFields;
    unsigned _joinLevel;
    unsigned _joinSize;
    unsigned _dcount;
    ListT<CegoField>* _joinBuf[TABMNG_MAXJOINLEVEL];
    ListT<CegoField>**  _pParentJoinBuf;

    ListT<CegoField>* _mergeBuf[TABMNG_MAXJOINLEVEL];
    ListT<CegoField>**  _pMergedBuf;
    
    
    CegoQueryCursor*_pTC[TABMNG_MAXJOINLEVEL];
    CegoAttrCond _attrCond[TABMNG_MAXJOINLEVEL];
    bool _attrCondFlag[TABMNG_MAXJOINLEVEL];
    CegoPredicate* _attrPred[TABMNG_MAXJOINLEVEL];
    CegoPredicate* _cursorPred[TABMNG_MAXJOINLEVEL];
    bool _firstTuple[TABMNG_MAXJOINLEVEL];
    CegoDatabaseManager *_pDBMng;
    unsigned _aggregationCount;
    unsigned _nextAid;
    unsigned _tabSetId;
    ListT<CegoAttrDesc*>* _pGroupList;
    CegoPredicate* _pHavingPred;
    ListT<CegoExpr*>* _pNativeOrderList;
    ListT<CegoExpr*>* _pOrderList;
    ListT<CegoOrderNode::Ordering>* _pNativeOrderOptList;
    ListT<CegoOrderNode::Ordering>* _pOrderOptList;
    CegoProcBlock *_pBlock;
    enum SelectMode _selectMode;
    bool _aggDone;
    bool _orderingDone;
    bool _groupingDone;
    bool _simpleDone;
    bool _isDistinct;
    ListT<CegoField> _orderedSchema;
    ListT<CegoField> _dfl;
    ListT<CegoField> _evalSchema;
    bool _cacheEnabled;
    CegoQueryCache *_pCache;
    ListT<CegoField> _cacheSchema;
    CegoFieldValue*** _pCacheArray;
    ListT< ListT<CegoFieldValue> >* _pCacheList;
    unsigned _cacheRows;
    unsigned long _cacheEntrySize;
    bool _isCached;
    Chain _viewCondId;
    Chain _queryId;
    CegoOrderCursor *_pOrderCursor;
    CegoOrderSpace* _pOrderSpace;
    CegoGroupCursor *_pGroupCursor;
    CegoGroupSpace* _pGroupSpace;
    bool _isPrepared;
    unsigned _rowCount;
    unsigned _rowLimit;
    bool _checkUnion;
    CegoSelect* _pUnionSelect;
    unsigned _extRefCount;
    NanoTimer _execTime;
 
    unsigned long _modId;
};
#endif




