#ifndef _CEGOSELECT_H_INCLUDED_
#define _CEGOSELECT_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoSelect.h
// ------------
// Cego select query handling
//
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2010 Bjoern Lemke
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// INTERFACE MODULE
//
// Class: CegoSelect
// 
// Description: This class implements the SQL select query algorithm for the Cego database system 
//
// Status: QG-2.6
//
///////////////////////////////////////////////////////////////////////////////

// base includes
#include <lfc/ListT.h>
#include <lfc/SetT.h>

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

// cego includes
#include "CegoProcBlock.h"
#include "CegoDefs.h"
#include "CegoTableDesc.h"
#include "CegoFactor.h"
#include "CegoDistManager.h"
#include "CegoDistCursor.h"
#include "CegoField.h"
#include "CegoPredDesc.h"
#include "CegoCondDesc.h"
#include "CegoContentObject.h"
#include "CegoOrderSpace.h"
#include "CegoGroupSpace.h"
#include "CegoHavingDesc.h"
#include "CegoTerm.h"
#include "CegoExpr.h"
#include "CegoContentObject.h"

class CegoProcBlock;

class CegoSelect {
    
public:

    CegoSelect(char* buf, CegoDistManager* pGTM);
    CegoSelect(Element* pSelectElement, CegoDistManager* pGTM);
    CegoSelect(ListT<CegoContentObject*>& coList,
	       ListT<CegoExpr*>& exprList, 
	       CegoPredDesc* pPred,
	       ListT<CegoAttrDesc*> *pGroupList,
	       CegoHavingDesc* pHaving,
	       ListT<CegoExpr*> *pOrderList,
	       ListT<CegoOrderNode::Ordering>* pOrderOptList,
	       bool isDistinct,
	       int rowLimit,
	       CegoDistManager* pGTM);

    ~CegoSelect();

    void setTableManager(CegoDistManager* pGTM);

    void setUnionSelect(CegoSelect* pUnion);

    void cleanUp();
    void prepare();
    void reset(bool doRelease);

    Element* getPlan();

    bool nextTuple(ListT<CegoField>& jfl);

    void enableCache();
    void disableCache();

    bool isCacheEnabled();

    void setCaching(bool doCaching);
    bool isCaching();
    bool isCached();

    void checkValidRef();
    void setParentJoinBuf(ListT<CegoField>* pParentJoinBuf = 0 , int size = 0);
    void setProcBlock(CegoProcBlock *pBlock);

    int evalExtTableReferences(CegoContentObject* pCO, const ListT<CegoField>& fl);

    CegoPredDesc* getPredicate();
    void getSchema(ListT<CegoField>& schema);
    Chain toChain(const Chain& indent = Chain("")) const;

    Element* toElement() const;
    void fromElement(Element *pSelectElement, CegoDistManager* pGTM);
    
    ListT<CegoAttrDesc*> getAttrRefList() const;
    ListT<CegoField> getFieldList() const;

    void encode(char *buf);
    void decode(char *buf, CegoDistManager* pGTM);
    int getEncodingLength() const;
    
    void setViewCond(const CegoAttrCond& attrCond);
    
    void setTabSetId(int tabSetId);

    int getExtRefCount() const;

    CegoSelect* clone( bool isAttrRef = false);

private:

    int evalTableReferences(CegoContentObject* pCO, const ListT<CegoField>& fl);

    bool isPrepared() const;
    void analyzeJoin();

    enum SelectMode { PLAIN, AGGREGATION, GROUPING };

    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(CegoPredDesc* pPred);
    void consolidateConjunctionList();

    void evalReferences();

    void filterRefs(ListT<CegoField>& inSchema, ListT<CegoField>& outSchema);   
    void filterFacRef(CegoFactor *pFac, ListT<CegoField>& inSchema, ListT<CegoField>& outSchema);
    void filterExprRef(CegoExpr *pExpr, ListT<CegoField>& inSchema, ListT<CegoField>& outSchema);
    void filterTermRef(CegoTerm *pTerm, ListT<CegoField>& inSchema, ListT<CegoField>& outSchema);
    void filterPredRef(CegoPredDesc *pP, ListT<CegoField>& inSchema, ListT<CegoField>& outSchema);
    void filterCondRef(CegoCondDesc* pC, ListT<CegoField>& inSchema, ListT<CegoField>& outSchema);
    void filterAttrRef(CegoAttrDesc* pAttrDesc, ListT<CegoField>& inSchema, ListT<CegoField>& outSchema);

    void evalSelection(ListT<CegoField>& ol);

    void buildJoinTables();
    void buildJoinRefs();
    void buildJoinConditions();

    void getPredObjectList(CegoPredDesc *pPred, ListT<CegoContentObject*>& objectList);
    void getCondObjectList(CegoCondDesc* pC, ListT<CegoContentObject*>& objectList);

    void initAggregation();
    void aggregateTuple(ListT<CegoField>& aggTuple);
    void evalAggregation(ListT<CegoField>& resultList);

    void makeOrder(); 
    bool matchFieldValue(const CegoFieldValue& fv1, const CegoFieldValue& fv2, CegoComparison comp);    
    void setAggregationValue(CegoExpr *pExpr, ListT<CegoField>& jfl);

    ListT<CegoPredDesc*> _viewConjunctionList;
    ListT<CegoPredDesc*> _conjunctionList;

    ListT<CegoExpr*> _exprList;
    CegoPredDesc* _pPred;
    ListT<CegoPredDesc*> _joinPredList;


    CegoDistManager* _pGTM;

    // ListT<CegoGroupAggregation> _groupList;
    
    ListT<CegoContentObject*> _coList;
    ListT<CegoContentObject*> _joinList;

    ListT<CegoField> _joinFields;

    int _joinLevel;
    int _joinSize;

    int _dcount;

    ListT<CegoField> _joinBuf[TABMNG_MAXJOINLEVEL];
    ListT<CegoField>*  _pParentJoinBuf;
    int _parentJoinBufSize;

    CegoDistCursor*_pTC[TABMNG_MAXJOINLEVEL];

    CegoAttrCond _attrCond[TABMNG_MAXJOINLEVEL];
    bool _attrCondFlag[TABMNG_MAXJOINLEVEL];
    CegoPredDesc* _attrPred[TABMNG_MAXJOINLEVEL];
    int _joinStep[TABMNG_MAXJOINLEVEL];

    bool _firstTuple[TABMNG_MAXJOINLEVEL];

    Logger* _pLogger;

    int _aggregationCount;
    int _nextAid;
    int _tabSetId;

    ListT<CegoAttrDesc*>* _pGroupList;
    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 _isDistinct;

    ListT<CegoField> _orderedSchema;
    ListT<CegoField> _dfl;

    ListT< ListT<CegoField> > _queryCache;

    CegoOrderCursor *_pOrderCursor;
    CegoOrderSpace* _pOrderSpace;

    CegoGroupCursor *_pGroupCursor;
    CegoGroupSpace* _pGroupSpace;

    CegoHavingDesc* _pHaving;

    bool _isPrepared;
    int _rowCount;
    int _rowLimit;

    bool _checkUnion;
    CegoSelect* _pUnionSelect;

    int _extRefCount;

    bool _doCaching;
    bool _isCached;
    bool _firstFromCache;
    bool _cacheEnabled;

    unsigned long _modId;

};
#endif




