#ifndef _CEGOQUERYHELPER_H_INCLUDED_
#define _CEGOQUERYHELPER_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoQueryHelper.h
// -----------------
// Cego query helper
//
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2025 Bjoern Lemke
//
// INTERFACE MODULE
//
// Class: CegoQueryHelper
// 
// Description: The CegoQueryHelper class provides several utility methods
//              which are used for tuple retrieval and evalution
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

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

// cego includes
#include "CegoAttrCond.h"
#include "CegoPredicate.h"
#include "CegoCondition.h"
#include "CegoField.h"
#include "CegoFieldValue.h"
#include "CegoProcBlock.h"
#include "CegoExpr.h"
#include "CegoBlob.h"
#include "CegoClob.h"
#include "CegoTupleState.h"
#include "CegoAttrAlias.h"
#include "CegoAliasObject.h"

class CegoQueryHelper {
    
public:

    enum AttrCondMatch { INAPP, PARTIAL, COMPLETE };

    CegoQueryHelper();
    ~CegoQueryHelper();

    // makes conjunctive normal form for the given condition
    static void makeCNF(CegoCondition *pC);
    static void createConjunctionList(CegoPredicate* pPred, ListT<CegoPredicate*>* pConjunctionList);
    // evaluates the given predicate with the given join buffers and returns the logical result

    
    // filters a normalized attribute condition from the given predicate
    static AttrCondMatch checkAttrCond(CegoAttrCond& ac,
		      CegoPredicate* pP, 
		      const ListT<CegoField>& schema,
		      ListT<CegoField>* flArray, 
		      unsigned flSize, 
		      CegoProcBlock *pBlock);
    // internal debugging methods, not used by any class
    static Chain condToChain(CegoCondition* pC, unsigned depth);
    static Chain predToChain(CegoPredicate* pP, unsigned depth);
    // for grouping and aggregation queries, these methods are used by CegoSelect and CegoGroupSpace
    static void aggregateTuple(ListT<CegoField>& aggTuple, CegoExpr* pExpr);
    static void aggregateTuple(ListT<CegoField>& aggTuple, CegoAggregation* pAgg);
    // the given field value is checked for type information of the given field and casted if required 
    static void prepareFieldValue(CegoField* pFV, CegoFieldValue& fv, CegoTableManager* pTM, unsigned tabSetId);
    static bool checkIndexForPredicate(unsigned tabSetId, CegoQueryManager* pGTM, CegoPredicate *pPred, ListT<CegoContentObject*>& coList);
    // field list encoding and decoding methods
    static void encodeFL(const ListT<CegoField>& fvl, char* &pBufBase, unsigned &buflen);    
    static void decodeFL(ListT<CegoField>& fvl, char* pc, unsigned len);
    static unsigned encodeFVL(unsigned long long tid, unsigned long long tastep, CegoTupleState ts, const ListT<CegoField>& fvl, char* &pBufBase, unsigned& buflen);
    static unsigned encodeFVL(unsigned long long tid, unsigned long long tastep, CegoTupleState ts, const ListT<CegoField>& fvl, const ListT<CegoBlob>& blobList, const ListT<CegoClob>& clobList, char* &pBufBase, unsigned& buflen);
    static unsigned skipTupleHeader();
    static unsigned encodeTupleHeader(unsigned long long tid, unsigned long long tastep, CegoTupleState ts, char* p);
    static unsigned decodeTupleHeader(unsigned long long& tid, unsigned long long& tastep, CegoTupleState& ts, char* p);
    static void decodeFVL(ListT<CegoField>& fvl, char* pc, unsigned len);
    static void decodeFVL(ListT<CegoField>& fvl, ListT<CegoBlob>& blobList, ListT<CegoClob>& clobList, char* pc, unsigned len);
    static void decodeNativeFVL(ListT<CegoFieldValue>& fvl, ListT<CegoBlob>& blobList, ListT<CegoClob>& clobList, char* pc, unsigned len);
    static void decodeUpdRec(Chain& tableAlias,
			     CegoPredicate* &pPred, 
			     ListT<CegoField>& updList, 
			     ListT<CegoExpr*>& exprList,
			     bool& returnOnFirst, 
			     char* pBuf, unsigned buflen,
			     CegoQueryManager* pGTM, unsigned tabSetId); 
    static void encodeUpdRec(const Chain& tableAlias,
			     CegoPredicate* pPred, 
			     const ListT<CegoField>& updList,
			     const ListT<CegoExpr*>& exprList,
			     const ListT<CegoBlob>& blobList,
			     const ListT<CegoClob>& clobList,
			     const bool returnOnFirst,
			     CegoProcBlock* pBlock,
			     char* &pBuf, unsigned &buflen);
    static void decodeDelRec(Chain& tableAlias,
			     CegoPredicate* &pPred,
			     char* pBuf, unsigned buflen);
    static void encodeDelRec(const Chain& tableAlias,
			     CegoPredicate* pPred,
			     CegoProcBlock* pBlock,
			     char* &pBuf, unsigned &buflen);
    static void mapAliasSchema(ListT<CegoField>& schema, const ListT<CegoAttrAlias>& aliasList);
    static void mapAliasPredicate(CegoPredicate* pPred, const Chain& tableAlias, const ListT<CegoAttrAlias>& aliasList);
    static CegoAttrCond mapAttrCond(const CegoAttrCond& attrCond, CegoAliasObject* pAO);
    static void mapFLA(ListT<CegoField>* pFLAmap, ListT<CegoField>** pFLA, unsigned offset, unsigned size, CegoAliasObject* pAO);
    static void propFLA(ListT<CegoField>* pFLAprop, ListT<CegoField>** pFLA, unsigned offset, unsigned size, CegoAliasObject* pAO);
    static unsigned maxFieldSize(CegoField *pF);
    static bool string2Clob(CegoFieldValue& fv, CegoTableManager* pTM, unsigned tabSetId);
    static Chain skipComment(Chain& line);
    static bool hasOpenString(Chain& line);
    static void localizeFL(ListT<CegoField>& returnList);
    static Chain sql2Regex(const Chain& sqlPattern);
    
private:

    // static bool evalFields(CegoComparison comp, const CegoFieldValue& f1, const CegoFieldValue& f2);
    // static bool evalBetween(const CegoFieldValue& f1, const CegoFieldValue& f2, const CegoFieldValue& f3);
    static void createConjunctionList(CegoPredicate* pPred, ListT<CegoPredicate*>& conjunctionList);
    static AttrCondMatch evalAttrCond(CegoAttrCond& ac,		      
		      CegoPredicate* pP, 
		      const ListT<CegoField>& schema,
		      ListT<CegoField>* flArray, 
		      unsigned flSize, 
		      CegoProcBlock *pBlock);
    static AttrCondMatch evalAttrCondbyCondition(CegoAttrCond& ac,
					  CegoCondition* pC,
					  const ListT<CegoField>& schema,
					  ListT<CegoField>* flArray, 
					  unsigned flSize,
					  CegoProcBlock* pBlock);
    static unsigned max(unsigned i1, unsigned i2, unsigned i3, unsigned i4);

};
#endif
