#ifndef _CEGOACTION_H_INCLUDED_
#define _CEGOACTION_H_INCLUDED_
///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoAction.h  
// ------------
// Cego semantic actions interface definition
//
// Design and Implementation by Bjoern Lemke
//
// (C)opyright 2000-2019 Bjoern Lemke
//
// INTERFACE MODULE
//
// Class: CegoAction
// 
// Description: The CegoAction class is the derived parser class for all semantic database 
//              actions. This requires a dragon generated parser class.
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

// LFC INCLUDES
#include <lfcbase/StackT.h>
#include <lfcbase/ListT.h>

// CEGO INCLUDES
#include "Cego.h"
#include "CegoComparison.h"
#include "CegoDataType.h"
#include "CegoTableManager.h"
#include "CegoTransactionManager.h"
#include "CegoDatabaseManager.h"
#include "CegoField.h"
#include "CegoQuery.h"
#include "CegoSelect.h"
#include "CegoCondDesc.h"
#include "CegoAttrDesc.h"
#include "CegoPredDesc.h"
#include "CegoDbHandler.h"
#include "CegoProcVar.h"
#include "CegoProcBlock.h"
#include "CegoProcedure.h"
#include "CegoExpr.h"
#include "CegoTerm.h"
#include "CegoFactor.h"
#include "CegoProcCond.h"
#include "CegoProcPred.h"
#include "CegoAlterDesc.h"
#include "CegoProcException.h"
#include "CegoCaseCond.h"
#include "CegoTrigger.h"
#include "CegoAttrAlias.h"

class CegoDbThreadPool;

class CegoAction : public Cego {

    
public:

    CegoAction(CegoDistManager *pTabMng, CegoDbThreadPool *pDbPool = 0 );
    ~CegoAction();

    void setTableSet(const Chain& tableSet);
    const Chain& getTableSet();

    void setDbHandle(CegoDbHandler *pDbHandle);
    void setLogToFile(bool logToFile);
	
    CegoSelect* getSelect();
    CegoProcedure* getProcedure();
    CegoTrigger* getTrigger();

    void cleanUp();
    void setCommandChain(char* pC);
    char nextChar();
    void readChain();
    void backChar();

    void printTokenList();
    
    /////////////////////////////////////////////////
    /////////// start of semantic actions ///////////
    /////////////////////////////////////////////////

    void setSyncMethod() { _execMethod = EXECSYNC; };
    void setListTableSetMethod() { _execMethod = EXECLISTTABLESET; };
    void setListTableMethod() { _execMethod = EXECLISTTABLE; };
    void setListViewMethod() { _execMethod = EXECLISTVIEW; };
    void setListProcMethod() { _execMethod = EXECLISTPROC; };
    void setListTriggerMethod() { _execMethod = EXECLISTTRIGGER; };
    void setListAliasMethod() { _execMethod = EXECLISTALIAS; };
    void setListIndexMethod() { _execMethod = EXECLISTINDEX; };
    void setListBTreeMethod() { _execMethod = EXECLISTBTREE; };
    void setListKeyMethod() { _execMethod = EXECLISTKEY; };
    void setListCounterMethod() { _execMethod = EXECLISTCOUNTER; };
    void setListSysObjMethod() { _execMethod = EXECLISTSYSOBJ; };
    void setListTmpObjMethod() { _execMethod = EXECLISTTMPOBJ; };
    void setListCheckMethod() { _execMethod = EXECLISTCHECK; };


    void setTableSetOpt();

    void setTableInfoMethod() { _execMethod = EXECTABLEINFO; };
    void setTableSizeMethod() { _execMethod = EXECTABLESIZE; };
    void setTupleInfoMethod() { _execMethod = EXECTUPLEINFO; };
    void setShowUptimeMethod() { _execMethod = EXECSHOWUPTIME; };
    void setShowPoolMethod() { _execMethod = EXECSHOWPOOL; };
    void setShowSystemSpaceMethod() { _execMethod = EXECSHOWSYSTEMSPACE; };
    void setTableDescMethod() { _execMethod = EXECTABLEDESC; };
    void setIndexDescMethod() { _execMethod = EXECINDEXDESC; };
    void setBTreeDescMethod() { _execMethod = EXECBTREEDESC; };
    void setViewDescMethod() { _execMethod = EXECVIEWDESC; };
    void setKeyDescMethod() { _execMethod = EXECKEYDESC; };
    void setCheckDescMethod() { _execMethod = EXECCHECKDESC; };
    void setAliasDescMethod() { _execMethod = EXECALIASDESC; };
    void setProcDescMethod() { _execMethod = EXECPROCDESC; };

    void setProcShowMethod() { _execMethod = EXECPROCSHOW; };
    void setViewShowMethod() { _execMethod = EXECVIEWSHOW; };
    void setCheckShowMethod() { _execMethod = EXECCHECKSHOW; };
    void setTriggerShowMethod() { _execMethod = EXECTRIGGERSHOW; };

    void setSetTableSetMethod() { _execMethod = EXECSETTABLESET; };
    void setAuthUserMethod() { _execMethod = EXECAUTHUSER; };

    void setEnableAppendModeMethod() { _execMethod = EXECENABLEAPPENDMODE; };
    void setDisableAppendModeMethod() { _execMethod = EXECDISABLEAPPENDMODE; };
    
    void setEnableAutoCommitMethod() { _execMethod = EXECENABLEAUTOCOMMIT; };
    void setDisableAutoCommitMethod(){ _execMethod = EXECDISABLEAUTOCOMMIT; };

    void setSetIsolationMethod() { _execMethod = EXECSETISOLATION; };

    void setTableReorganizeMethod() { _execMethod = EXECTABLEREORGANIZE; };
    void setIndexReorganizeMethod() { _execMethod = EXECINDEXREORGANIZE; };
    void setSelectMethod() { _execMethod = EXECSELECT; };
    void setSelectPlanMethod() { _execMethod = EXECSELECTPLAN; };
    void setQueryMethod() { _execMethod = EXECQUERY; };

    void setViewCreateMethod() { _execMethod = EXECVIEWCREATE; };
    void setViewLoadMethod() { _execMethod = EXECVIEWLOAD; };
    void setViewDropMethod() { _execMethod = EXECVIEWDROP; };

    void setTriggerCreateMethod() { _execMethod = EXECTRIGGERCREATE; };
    void setTriggerLoadMethod() { _execMethod = EXECTRIGGERLOAD; };
    void setTriggerDropMethod() { _execMethod = EXECTRIGGERDROP; };

    void setProcCreateMethod() { _execMethod = EXECPROCCREATE; };
    void setProcLoadMethod() { _execMethod = EXECPROCLOAD; };
    void setProcCallMethod() { _execMethod = EXECPROCCALL; };
    void setFuncCallMethod() { _execMethod = EXECFUNCCALL; };

    void setUserTableCreateMethod() { _execMethod = EXECUSERTABLECREATE; };
    void setPrimaryIndexCreateMethod() { _execMethod = EXECPRIMARYINDEXCREATE; };
    void setIndexCreateMethod() { _execMethod = EXECINDEXCREATE; };
    void setTableTruncateMethod() { _execMethod = EXECTABLETRUNCATE; };
    void setTableDropMethod() { _execMethod = EXECTABLEDROP; };
    void setIndexDropMethod() { _execMethod = EXECINDEXDROP; };
    void setProcDropMethod() { _execMethod = EXECPROCDROP; };
    void setFKeyDropMethod() { _execMethod = EXECFKEYDROP; };
    void setCheckDropMethod() { _execMethod = EXECCHECKDROP; };
    void setBTreeDropMethod() { _execMethod = EXECBTREEDROP; };
    void setAliasDropMethod() { _execMethod = EXECALIASDROP; };
    
    void setForeignKeyCreateMethod() { _execMethod = EXECFOREIGNKEYCREATE; };
    void setCheckCreateMethod() { _execMethod = EXECCHECKCREATE; };
    void setAssignStatementMethod() { _execMethod = EXECASSIGNSTATEMENT; };
    void setPrintMethod() { _execMethod = EXECPRINT; };
    void setIndexCheckMethod() { _execMethod = EXECINDEXCHECK; };
    void setCreateCounterMethod() { _execMethod = EXECCREATECOUNTER; };
    void setDropCounterMethod() { _execMethod = EXECDROPCOUNTER; };
    void setSetCounterMethod() { _execMethod = EXECSETCOUNTER; };

    void setAliasCreateMethod() { _execMethod = EXECALIASCREATE; };
    
    // JDBC info calls 
    void setJDBCInfoMethod() { _execMethod = EXECJDBCINFO; };
    void jdbcArg1();
    void jdbcArg2();
    void dropOpt1();
    void dropOpt2();
    void setCounterId();

    // trigger actions
    void triggerHead();
    void triggerStore();
    void setTriggerBefore();
    void setTriggerAfter();
    
    void addInsertTrigger();
    void addUpdateTrigger();
    void addDeleteTrigger();
    
    // procedure actions

    void procHead();
    void procStore();
    void procReturnOpt();
    void procArg1();
    void procArg2();
    void procStoreBlock();
    void procVarStatement();
    void procCursorCreateStatement();
    void procCursorCloseStatement();
    void procAssignStatement();
    void procAssign2NullStatement();
    void procInitialAssignment1();
    void procInitialAssignment2();

    void procThrowStatement();
    void procNoopStatement();
    void procIfStatement();
    void procStoreIfBlock();
    void procStoreElseBlock();
    void procElsePart();
    void procIfCondition();
    void procElsIfCondition();
    void procWhileStatement();
    void procWhileCondition();
    void procCondition1();
    void procCondition2();
    void procCondition3();
    void procPredicate1();
    void procPredicate2();
    void procPredicate3();
    void procPredicate4();

    void procExceptionStatement();
    void procExceptionCondition();

    void procExpr1();
    void procExpr2();
    void procExpr3();
    void procExpr4();
    void procTerm1();
    void procTerm2();
    void procTerm3();
    void procFactor1();
    void procFactor2();
    void procFactor3();
    void procFactor4();
    void procFactor5();
    void procFactor6();
    void procFactor7();
    void procFactor8();

    void procFactor9();
    void procFactor10();
    void procFactor11();
    void procFactor12();
    void procFactor13();
    void procFactor14();

    void caseClause();
    void caseConditionList1();
    void caseConditionList2();
    void caseCondition();
    void casePrepare();

    void procStoreFetchArg1();
    void procStoreFetchArg2();
    void procQueryStatement();
    void procValueSpec(); 
    void procExprValue();
    void procReturnStatement1();
    void procReturnStatement2();
    void procBlockStart();
    void procBlockStatement();

    void setUniqueIndex();
    void setCachedOption();
    void setAVLIndex();
    void setBTreeIndex();

    void setAliasAttr();
    
    void setPrimaryColumn();
    void setOrdinaryColumn();
    void setColumnDesc();
    void setNullOpt();
    void setNotNullOpt();

    void defaultOpt();
    void defaultNullOpt();

    void createSimpleAttrList();
    void createSimpleAttr();

    void startStore();
    void commitStore();
    void rollbackStore();
    void lockStore();
    void unlockStore();

    // query actions

    void insertStore();
    void insertPrepare();
    void insertBySelectStore();
    void insertArg();
    void insertValueSpecStore();     
    void insertExprValue();    

    void unionAllStore();
    void selectStore();
    void noFromOption();
    
    void selectSelectionStore1();
    void selectSelectionStore2();
    void selectionList1();
    void selectionList2();
    void selectItem();

    void selectTableListStore();
    void selectJoinSpecStore();
    void selectTable1();
    void selectTable2();
    void selectStackJoinTable();

    void selectInnerJoinStore1();
    void selectInnerJoinStore2();
    void selectLeftOuterJoinStore1();
    void selectLeftOuterJoinStore2();
    void selectRightOuterJoinStore1();
    void selectRightOuterJoinStore2();

    void aliasOpt();
    void noAliasOpt();

    void selectGroupClause();
    void selectEmptyGroupClause();

    void selectGroupList1();
    void selectGroupList2();
    void selectHavingClause();
    void selectEmptyHavingClause();

    void selectOrderingClause();
    void selectEmptyOrderingClause();
    void selectOrderingList1();
    void selectOrderingList2();
    void selectOrderingAsc();
    void selectOrderingDesc();

    void selectDistinctOpt();
    void selectNoDistinctOpt();
    void selectLimitOpt1();
    void selectLimitOpt2();

    void updateStore();
    void updateAssignment();
    void returnVarAssignment();
    void returnOnFirstTrue();
    void returnOnFirstFalse();
    
    void deleteStore();

    void alterStore();
    void alterAddCol();
    void alterDropCol();
    void alterModCol();
    void alterModDefault();
    void alterRenameCol();
   
    void renameTable();
    void renameIndex();
    void renameBTree();
    void renameKey();
    void renameProcedure();
    void renameView();
    void renameCheck();
    void renameTrigger();

    void functionNative();
    void functionNextCount();
    void functionSetCount();

    void functionUserDef1();
    void functionUserDef2();

    void storeExprList1();
    void storeExprList2();
    
    void wcWhereClause();
    void wcEmptyClause();
   
    void wcConditionAnd();
    void wcConditionOr();
    void wcConditionPredicate();

    void wcPredicateQueryExists();

    void wcPredicateIn();
    void wcPredicateNotIn();

    void wcPredicateQueryIn();
    void wcPredicateQueryNotIn();

    void wcPredicateQueryComp();

    void wcPredicateExprComp();
    void wcPredicateBetween();

    void wcPredicateNullComp();
    void wcPredicateNotNullComp();
    void wcPredicateLikeComp();
    void wcPredicateNotLikeComp();

    void wcPredicateCondition();
    void wcPredicateNotPredicate();

    void miscIntType();
    void miscLongType();
    void miscStringType();
    void miscBoolType();
    void miscDateTimeType();
    void miscBigIntType();
    void miscFloatType();
    void miscDoubleType();
    void miscSmallIntType();
    void miscTinyIntType();
    void miscDecimalType();
    void miscFixedType();
    void miscBlobType();
    void miscClobType();

    void miscDecimalDim1();
    void miscDecimalDim2();
    
    void miscEqualComp();
    void miscNotEqualComp();
    void miscLessComp();
    void miscMoreComp();
    void miscLessEqualComp();
    void miscMoreEqualComp();
    void miscAttribute1();
    void miscAttribute2();
    void miscAttribute3();


    void miscIntString();
    void miscNegatedIntString();

    void miscFloatString();
    void miscNegatedFloatString();

    
    void miscStringValue();
    void miscIntValue();
    void miscLongValue();
    void miscBigIntValue();
    void miscSmallIntValue();
    void miscTinyIntValue();

    void miscFloatValue();
    void miscDoubleValue();
    void miscDecimalValue();
    void miscFixedValue();

    void miscNull();
    void miscSysDate();
    void miscFormatDate();
    
    void miscDateFormat();
    void miscDateValue();

    void miscTrueValue();
    void miscFalseValue();
    void miscBlobRef();
    void miscClobRef();

    void setObject1();
    void setObject2();
    void setObject3();

    void setUpdDelAlias();

    void execute();

    bool processBatchFile(const Chain& batchFileName, bool ignoreError, bool consoleOut, Chain& errorMsg);
    
private:
    
    enum ExecutionMethod {
	EXECSYNC,
	EXECLISTTABLESET,
	EXECLISTTABLE,
	EXECLISTVIEW,
	EXECLISTPROC,
	EXECLISTINDEX,
	EXECLISTBTREE,
	EXECLISTKEY,
	EXECLISTCOUNTER,
	EXECLISTSYSOBJ,
	EXECLISTTMPOBJ,
	EXECLISTCHECK,
	EXECLISTTRIGGER,
	EXECLISTALIAS,
	EXECTABLEINFO,
	EXECTABLESIZE,
	EXECTUPLEINFO,
	EXECSHOWUPTIME,
	EXECSHOWPOOL,
	EXECSHOWSYSTEMSPACE,
	EXECTABLEDESC,
	EXECINDEXDESC,
	EXECBTREEDESC,
	EXECVIEWDESC,
	EXECKEYDESC,
	EXECALIASDESC,
	EXECCHECKDESC,
	EXECPROCDESC,
	EXECPROCSHOW,
	EXECVIEWSHOW,
	EXECCHECKSHOW,
	EXECTRIGGERSHOW,
	EXECSETTABLESET,
	EXECAUTHUSER,
	EXECENABLEAPPENDMODE,
	EXECDISABLEAPPENDMODE,
	EXECENABLEAUTOCOMMIT,
	EXECDISABLEAUTOCOMMIT,
	EXECSETISOLATION,
	EXECTABLEREORGANIZE,
	EXECINDEXREORGANIZE,
	EXECSELECT,
	EXECSELECTPLAN,
	EXECQUERY,
	EXECVIEWCREATE,
	EXECVIEWLOAD,
	EXECVIEWDROP,
	EXECTRIGGERCREATE,
	EXECTRIGGERLOAD,
	EXECTRIGGERDROP,
	EXECPROCCREATE,
	EXECPROCLOAD,
	EXECPROCCALL,
	EXECFUNCCALL,
	EXECUSERTABLECREATE,
	EXECPRIMARYINDEXCREATE,
	EXECINDEXCREATE,
	EXECTABLEDROP,
	EXECTABLETRUNCATE,
	EXECINDEXDROP,
	EXECPROCDROP,
	EXECFKEYDROP,
	EXECCHECKDROP,
	EXECALIASDROP,
	EXECBTREEDROP,
	EXECFOREIGNKEYCREATE,
	EXECCHECKCREATE,
	EXECALIASCREATE,
	EXECASSIGNSTATEMENT,
	EXECPRINT,
	EXECINDEXCHECK,
	EXECCREATECOUNTER,
	EXECDROPCOUNTER,
	EXECSETCOUNTER,
	EXECJDBCINFO
    };

    ExecutionMethod _execMethod;
    
    /////////////////////////////////////////
    /////////// execution methods ///////////
    /////////////////////////////////////////

    void execSync();
    void execListTableSet();
    void execListTable();
    void execListView();
    void execListProc();
    void execListIndex();
    void execListBTree();
    void execListKey();
    void execListCounter();
    void execListSysObj();
    void execListTmpObj();
    void execListCheck();
    void execListTrigger();
    void execListAlias();

    void execTableInfo();
    void execTableSize();
    void execTupleInfo();
    void execShowUptime();
    void execShowPool();
    void execShowSystemSpace();
    void execTableDesc();
    void execIndexDesc();
    void execBTreeDesc();
    void execViewDesc();
    void execKeyDesc();
    void execCheckDesc();
    void execAliasDesc();
    void execProcDesc();

    void execProcShow();
    void execViewShow();
    void execCheckShow();
    void execTriggerShow();

    void execSetTableSet();
    void execAuthUser();

    void execEnableAppendMode();
    void execDisableAppendMode();

    void execEnableBTreeCache();
    void execDisableBTreeCache();
    
    void execEnableAutoCommit();
    void execDisableAutoCommit();

    void execSetIsolation();

    void execTableReorganize();
    void execIndexReorganize();
    void execSelect();
    void execSelectPlan();
    void execQuery();

    void execViewCreate();
    void execViewLoad();
    void execViewDrop();

    void execTriggerCreate();
    void execTriggerLoad();
    void execTriggerDrop();

    void execProcCreate();
    void execProcLoad();
    void execProcCall();
    void execFuncCall();

    void execUserTableCreate();
    void execPrimaryIndexCreate();
    void execIndexCreate();
    void execTableDrop();
    void execTableTruncate();
    void execIndexDrop();
    void execProcDrop();
    void execFKeyDrop();
    void execCheckDrop();
    void execAliasDrop();
    void execBTreeDrop();

    void execForeignKeyCreate();
    void execCheckCreate();
    void execAliasCreate();
    void execAssignStatement();
    void execPrint();
    void execIndexCheck();
    void execCreateCounter();
    void execDropCounter();
    void execSetCounter();

    // JDBC info calls 
    void execJDBCInfo();

    
    void reallocateStringBuf();
    Chain getPlanString(Element *pPlan, const Chain& title, int indent = 0);
    Chain getJoinPlanString(Element *pJoin, const Chain& title, int indent = 0);

    void formatTableInfo(const Chain& tableSet, const Chain& tableName, 
			 const ListT<CegoTableObject>& idxList,
			 const ListT<CegoBTreeObject>& btreeList,
			 const ListT<CegoKeyObject>& keyList,
			 const ListT<CegoCheckObject>& checkList,
			 const ListT<CegoTriggerObject>& triggerList,
			 const ListT<CegoAliasObject>& aliasList,
			 CegoTableObject& oe,
			 ListT< ListT<CegoFieldValue> > &fa, bool withSize);


    char *_pC;

    int _stringBufLen;
    char *_stringBuf; // [MAXSTRINGLEN];

    Chain _fieldName;
    CegoDataType _dataType;
    int _dataLen;
    int _dataDim;

    CegoDistManager* _pTabMng;
    
    CegoFieldValue _fieldValue;
    CegoFieldValue _defaultValue;

    // list variables

    ListT<CegoField> _fal;
    ListT<CegoContentObject*> _coList;
    ListT<CegoProcCond*> *_pCondList;
    ListT<CegoProcBlock*> *_pIfBlockList;
    ListT<CegoField> _fieldList;
    ListT<CegoAlterDesc> _alterList;
    ListT<CegoField> _idxList;
    ListT<Chain> _jdbcArgList;
    ListT<CegoAttrDesc*>* _pGroupList;
    ListT<CegoExpr*>* _pOrderingList;
    ListT<CegoOrderNode::Ordering>* _pOrderingOptList;

    ListT<CegoProcVar> _procArgList;
    ListT<Chain> _fetchList;
    ListT<CegoExpr*> _exprList;
    ListT<ListT<CegoExpr*> > _exprListArray;
    ListT<CegoReturnVar*> _returnVarList;
    
    ListT<CegoAttrAlias> _aliasList;
    
    // stack variables

    StackT< ListT<CegoField> > _fieldListStack;
    StackT<CegoPredDesc*> _predDescStack;
    StackT<CegoAttrDesc*> _attrDescStack;
    StackT<CegoCondDesc*> _condDescStack;
    StackT<CegoHavingDesc*> _havingDescStack;
    StackT<CegoCaseCond*> _caseCondStack;
    StackT<ListT<CegoContentObject*> > _coListStack;
    StackT<ListT<CegoExpr*> > _exprListStack;
    StackT<ListT<CegoAttrDesc*>*> _groupClauseStack;
    StackT<ListT<CegoExpr*>*> _orderingClauseStack;
    StackT<CegoProcBlock*> _blockStack;
    StackT<CegoProcCond*> _condStack;
    StackT<CegoProcPred*> _predStack;
    StackT<CegoTerm*> _termStack;
    StackT<CegoFactor*> _factorStack;
    StackT<CegoExpr*> _exprStack;
    StackT<CegoFunction*> _functionStack;
    StackT<CegoSelect*> _unionStack;
    StackT<ListT<CegoProcCond*>* > _condListStack;
    StackT<ListT<CegoProcBlock*>* > _ifBlockListStack;
    StackT<CegoComparison> _compStack;
    StackT<bool> _distinctStack;
    StackT<int> _limitStack;

    CegoOrderNode::Ordering _orderingOpt;
    
    StackT<ListT<CegoOrderNode::Ordering>*> _orderingOptStack;

    StackT<Chain> _objNameStack;
    StackT<Chain> _objTableSetStack;

    CegoCaseCond *_pCaseCond;
    CegoSelect *_pSelect;
    
    bool _isUnique;
    bool _isCached;
    bool _isBTree;

    bool _initialAssignment;
    bool _ifExistsOpt;
    bool _returnOnFirst;
    
    CegoDbHandler* _pDbHandle;
    bool _logToFile;
    
    Chain _tableSet;
    Chain _defTableSet;
    Chain _updDelAlias;


    // trigger declarations
    CegoTrigger* _pTrigger;
    bool _isTriggerBefore;
    bool _isTriggerOnUpdate;
    bool _isTriggerOnInsert;
    bool _isTriggerOnDelete;
    
    
    // procedure declarations

    CegoProcBlock* _pBlock;

    Chain _triggerTableSet;
    Chain _procTableSet;
    
    CegoDataType _returnType;
    int _returnTypeLen;
    int _returnTypeDim;
    
    CegoProcedure::ProcType _procType;
    
    CegoProcedure* _pProc;
    CegoQuery* _pQuery;
    
    CegoProcBlock* _pMasterBlock;

    bool _isNullable;
    
    Chain _dateFormat;
    Chain _dateValue;

    Chain _intString;
    Chain _floatString;

    Chain _counterName;

    CegoException _exception;
    
    CegoDbThreadPool* _pDbPool;
    
    unsigned long _modId;
};

#endif
