///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoAction.cc  
// -------------                                                        
// Cego semantic parser actions
//
// Design and Implementation by Bjoern Lemke
//     
// (C)opyright 2000-2025 Bjoern Lemke
//
// IMPLEMENTATION MODULE
//
// Class: CegoAction
// 
// Description: All semantic actions for the cego SQL parser
//
// Status: CLEAN
//
///////////////////////////////////////////////////////////////////////////////

#include <lfcbase/StackT.h>
#include <lfcbase/Timer.h>
#include <lfcbase/Datetime.h>
#include <lfcbase/Tokenizer.h>
#include <lfcbase/AESCrypt.h>

#include "CegoDefs.h"
#include "CegoOutput.h"
#include "CegoAction.h"
#include "CegoXMLdef.h"
#include "CegoSelect.h"
#include "CegoProcedure.h"
#include "CegoProcAssignStmt.h"
#include "CegoProcThrowStmt.h"
#include "CegoProcIfStmt.h"
#include "CegoProcQueryStmt.h"
#include "CegoProcWhileStmt.h"
#include "CegoProcBlockStmt.h"
#include "CegoProcNoopStmt.h"
#include "CegoProcReturnStmt.h"
#include "CegoProcFetch.h"
#include "CegoProcCursorCreateStmt.h"
#include "CegoProcCursorCloseStmt.h"
#include "CegoJDBCInfo.h"
#include "CegoDbThreadPool.h"
#include "CegoAVLIndexManager.h"
#include "CegoJoinObject.h"
#include "CegoTypeConverter.h"

#include <ctype.h>
#include <stdlib.h>
#include <string.h>

extern char __quoteEscapeFlag;
extern char __caseSensitiveFlag;

#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MAXCMDLEN 20000

CegoAction::CegoAction(CegoQueryManager* pTabMng, CegoDbThreadPool* pDbPool) 
{
    _pTabMng = pTabMng;
    _pMasterBlock = new CegoProcBlock(0);

    _pC = 0;
    _pDbHandle = 0;
    _logToFile = false;

    _pQuery = 0;
    _pProc = 0;
    _pTrigger = 0;
    _pCond = 0;
    _pSelect = 0;
    
    _pDbPool = pDbPool;
    _isGrace = false;
    _procType = CegoProcedure::PROCEDURE;
    _pPredList = 0;
    _pIfBlockList = 0;
    _pGroupList = 0;
    _pOrderingList = 0;
    _pOrderingOptList = 0;

    _isTriggerBefore = false;
    _isTriggerOnInsert = false;
    _isTriggerOnUpdate = false;
    _isTriggerOnDelete = false;
    
    _stringBuf = (char*)malloc(MAXSTRINGLEN);
    _stringBufLen = MAXSTRINGLEN;
    
    if ( _stringBuf == 0 ) 
    {
	Chain msg("Malloc system error"); 
	throw Exception(EXLOC, msg);
    }

    if ( pTabMng )
	_modId = pTabMng->getDBMng()->getModId("CegoAction");
}

CegoAction::~CegoAction()  
{
    cleanUp();
    if ( _pMasterBlock )
	delete _pMasterBlock;
    if ( _stringBuf ) 
	free(_stringBuf);
}

void CegoAction::setCommandChain(char *pC)
{
    _pC = pC;
}

char CegoAction::nextChar() 
{   
    if ( _pC == 0 )
	return 0;

    if ( (int)(*_pC) < 0 )
    {
	Chain msg = Chain("Invalid character <") + Chain((int)(*_pC)) + Chain("> detected"); 
	throw Exception(EXLOC, msg);
    }

    // cout << "Character read : " << *_pC << endl;
    
    if ( *_pC == '\'' )
    {
	_pC++;
	readChain();
	return 0;
    }
 
    if ( *_pC == 0 )
    {
        return 0; 
    }
    
    char c = *_pC; 
    _pC++;

    if ( __caseSensitiveFlag == 0 )
	return c;
    else
	return (char)tolower((int)c);
} 

void CegoAction::readChain()
{
    setReserved(STRINGVAL); 
    
    unsigned i=0;    

    if ( __quoteEscapeFlag )
    {
	bool moreChar = true; 
	while ( moreChar )
	{	    
	    if ( *_pC == '\'' ) 
	    {
		_pC++;
		if ( *_pC == '\'' )
		{
		    _stringBuf[i] = '\'';
		    i++;
		}
		else
		{
		    moreChar = false;
		}
	    }
	    else
	    {
		_stringBuf[i] = *_pC; 		
		i++;
	    }
	  
	    if ( i == _stringBufLen ) 
	    { 
		reallocateStringBuf();
	    }
	    
	    if ( moreChar )
	    {
		_pC++;
		
		if ( *_pC == 0 )
		{
		    Chain msg("Unterminated string"); 
		    throw Exception(EXLOC, msg);
		}
	    }
	}
    }
    else
    {
    
	while ( *_pC != '\'' ) 
	{ 
	    // cout << "Storing: " << *_pC << endl; 

	    if ( *_pC == '\\' ) 
	    { 
		_pC++; 
		
		if ( *_pC == 'n' ) 
		{ 
		    _stringBuf[i] = '\n'; 
		} 
		else if ( *_pC == 'r' ) 
		{ 
		    _stringBuf[i] = '\r'; 
		} 
		else if ( *_pC == 't' ) 
		{ 
		    _stringBuf[i] = '\t'; 
		} 
		else if ( *_pC == '\'' ) 
		{ 
		    _stringBuf[i] = '\''; 
		}
		else if ( *_pC == '\\' ) 
		{ 
		    _stringBuf[i] = '\\'; 
		}
		else 
		{ 
		    Chain msg = Chain("Invalid escape character <") + Chain(*_pC) + Chain(">"); 
		    throw Exception(EXLOC, msg);
		} 
	    } 
	    else
	    { 
		_stringBuf[i] = *_pC; 
	    } 
	    
	    _stringBuf[i] = *_pC; 
	    i++; 
	    
	    if ( i == _stringBufLen ) 
	    {
		reallocateStringBuf();
	    }
	    
	    _pC++;
	    
	    if ( *_pC == 0 )
	    {
		Chain msg("Unterminated string"); 
		throw Exception(EXLOC, msg);
	    }
	}

	_pC++; 

    }

    _stringBuf[i] = 0; 

    return; 
}

void CegoAction::backChar() 
{
    if ( _pC != 0 )
	_pC--;
}

void CegoAction::reallocateStringBuf()
{
    // reallocation required
    _stringBufLen += MAXSTRINGLEN;
    char *newBuf = (char*)malloc( _stringBufLen );
    if ( newBuf == 0 ) 
    {
	Chain msg("Malloc system error"); 
	throw Exception(EXLOC, msg);
    }

    // we just have to copy the previous len
    memcpy(newBuf, _stringBuf, _stringBufLen - MAXSTRINGLEN);
    free(_stringBuf);
    _stringBuf=newBuf;
}

void CegoAction::printTokenList() 
{    
    cout << "TokenList is " << endl;
	
    ListT<Chain> tlist =  getTokenList();
    Chain* pS = tlist.First();
    while ( pS )
    {
	cout << *pS << endl;
	pS = tlist.Next();
    }    
}

void CegoAction::cleanUp() 
{
    _fal.Empty();
    _exprList.Empty();
    _fieldList.Empty();
    _idxList.Empty();
    _coList.Empty();
    _alterList.Empty();
    _jdbcArgList.Empty();

    if ( _pPredList )
    {
	_pPredList->Empty();
	delete _pPredList;
	_pPredList = 0;
    }
    if ( _pIfBlockList )
    {
	_pIfBlockList->Empty();
	delete _pIfBlockList;
	_pIfBlockList = 0;
    }
    if ( _pGroupList ) 
    {
	_pGroupList->Empty();
	delete _pGroupList;
	_pGroupList = 0;
    }
    
    if ( _pOrderingList )
    {
	_pOrderingList->Empty();
	delete _pOrderingList;
	_pOrderingList = 0;
    }
    if ( _pOrderingOptList )
    {
	_pOrderingOptList->Empty();
	delete _pOrderingOptList;
	_pOrderingOptList = 0;
    }
    
    _procArgList.Empty();
    _fetchList.Empty();
    _returnVarList.Empty();

    _fieldListStack.Empty();
    _predDescStack.Empty();
    _attrDescStack.Empty();
    _condDescStack.Empty();
    _caseCondStack.Empty();
    _coListStack.Empty();
    _exprListStack.Empty();
    _groupClauseStack.Empty();
    
    _objNameStack.Empty();
    _objTableSetStack.Empty();
    _termStack.Empty();
    _factorStack.Empty();
    _exprStack.Empty();
    _functionStack.Empty();
    _unionStack.Empty();
    _orderingClauseStack.Empty();
    _orderingOptStack.Empty();

    _blockStack.Empty();
    _ifBlockListStack.Empty();
    _compStack.Empty();
    _distinctStack.Empty();
    _limitStack.Empty();
  
    _isUnique = false;
    _isCached = false;

    if ( _pQuery )
    {
	delete _pQuery;
	_pQuery = 0;
    }

    if ( _pSelect )
    {
	delete _pSelect;
	_pSelect = 0;
    }

    if ( _pProc )
    {
	delete _pProc;
	_pProc = 0;
    }

    if ( _pTrigger )
    {
	delete _pTrigger;
	_pTrigger = 0;
    }

    if ( _pCond )
    {
	delete _pCond;
	_pCond = 0;
    }
    
    _tableSet = _defTableSet;
}

void CegoAction::setTableSet(const Chain& tableSet)
{
    _defTableSet = tableSet;
    _tableSet = tableSet;
}

const Chain& CegoAction::getTableSet()
{
    return _tableSet;
}

void CegoAction::setGraceMode(bool isGrace)
{
    _isGrace = isGrace;
}

void CegoAction::setDbHandle(CegoDbHandler* pDbHandle)
{
    _pDbHandle = pDbHandle;
}

void CegoAction::setLogToFile(bool logToFile)
{
    _logToFile = logToFile;
}

void CegoAction::execute()
{
    switch ( _execMethod )
    {
    case EXECSYNC:
	execSync();
	break;
    case EXECLISTTABLESET:
	execListTableSet();
	break;
    case EXECLISTTABLE:
	execListTable();
	break;
    case EXECLISTVIEW:
	execListView();
	break;
    case EXECLISTPROC:
	execListProc();
	break;
    case EXECLISTINDEX:
	execListIndex();
	break;
    case EXECLISTBTREE:
	execListBTree();
	break;
    case EXECLISTKEY:
	execListKey();
	break;
    case EXECLISTCOUNTER:
	execListCounter();
	break;
    case EXECLISTSYSOBJ:
	execListSysObj();
	break;
    case EXECLISTTMPOBJ:
	execListTmpObj();
	break;
    case EXECLISTCHECK:
	execListCheck();
	break;
    case EXECLISTTRIGGER:
	execListTrigger();
	break;
    case EXECLISTALIAS:
	execListAlias();
	break;
    case EXECTABLEINFO:
	execTableInfo();
	break;
    case EXECTABLESIZE:
	execTableSize();
	break;
    case EXECTUPLEINFO:
	execTupleInfo();
	break;
    case EXECSHOWUPTIME:
	execShowUptime();
	break;
    case EXECSHOWPOOL:
	execShowPool();
	break;
    case EXECSHOWSYSTEMSPACE:
	execShowSystemSpace();
	break;
    case EXECTABLEDESC:
	execTableDesc();
	break;
    case EXECINDEXDESC:
	execIndexDesc();
	break;
    case EXECBTREEDESC:
	execBTreeDesc();
	break;
    case EXECVIEWDESC:
	execViewDesc();
	break;
    case EXECKEYDESC:
	execKeyDesc();
	break;
    case EXECALIASDESC:
	execAliasDesc();
	break;
    case EXECCHECKDESC:
	execCheckDesc();
	break;
    case EXECPROCDESC:
	execProcDesc();
	break;
    case EXECPROCSHOW:
	execProcShow();
	break;
    case EXECVIEWSHOW:
	execViewShow();
	break;
    case EXECCHECKSHOW:
	execCheckShow();
	break;
    case EXECTRIGGERSHOW:
	execTriggerShow();
	break;
    case EXECSETTABLESET:
	execSetTableSet();
	break;
    case EXECAUTHUSER:
	execAuthUser();
	break;
    case EXECENABLEGRACEMODE:
	execEnableGraceMode();
	break;
    case EXECDISABLEGRACEMODE:
	execDisableGraceMode();
	break;
    case EXECENABLEAPPENDMODE:
	execEnableAppendMode();
	break;
    case EXECDISABLEAPPENDMODE:
	execDisableAppendMode();
	break;
    case EXECENABLEAUTOCOMMIT:
	execEnableAutoCommit();
	break;
    case EXECDISABLEAUTOCOMMIT:
	execDisableAutoCommit();
	break;
    case EXECSETISOLATION:
	execSetIsolation();
	break;
    case EXECTABLEREORGANIZE:
	execTableReorganize();
	break;
    case EXECINDEXREORGANIZE:
	execIndexReorganize();
	break;
    case EXECSELECT:
	execSelect();
	break;
    case EXECSELECTPLAN:
	execSelectPlan();
	break;
    case EXECQUERY:
	execQuery();
	break;
    case EXECVIEWCREATE:
	execViewCreate();
	break;
    case EXECVIEWLOAD:
	execViewLoad();
	break;
    case EXECVIEWDROP:
	execViewDrop();
	break;
    case EXECQUERYCONDLOAD:
	execQueryCondLoad();
	break;
    case EXECTRIGGERCREATE:
	execTriggerCreate();
	break;
    case EXECTRIGGERLOAD:
	execTriggerLoad();
	break;
    case EXECTRIGGERDROP:
	execTriggerDrop();
	break;
    case EXECPROCCREATE:
	execProcCreate();
	break;
    case EXECPROCLOAD:
	execProcLoad();
	break;
    case EXECPROCCALL:
	execProcCall();
	break;
    case EXECFUNCCALL:
	execFuncCall();
	break;
    case EXECUSERTABLECREATE:
	execUserTableCreate();
	break;
    case EXECPRIMARYINDEXCREATE:
	execPrimaryIndexCreate();
	break;
    case EXECINDEXCREATE:
	execIndexCreate();
	break;
    case EXECTABLEDROP:
	execTableDrop();
	break;
    case EXECTABLETRUNCATE:
	execTableTruncate();
	break;
    case EXECINDEXDROP:
	execIndexDrop();
	break;
    case EXECPROCDROP:
	execProcDrop();
	break;
    case EXECFKEYDROP:
	execFKeyDrop();
	break;
    case EXECCHECKDROP:
	execCheckDrop();
	break;
    case EXECALIASDROP:
	execAliasDrop();
	break;
    case EXECBTREEDROP:
	execBTreeDrop();
	break;
    case EXECFOREIGNKEYCREATE:
	execForeignKeyCreate();
	break;
    case EXECCHECKCREATE:
	execCheckCreate();
	break;
    case EXECALIASCREATE:
	execAliasCreate();
	break;
    case EXECASSIGNSTATEMENT:
	execAssignStatement();
	break;
    case EXECPRINT:
	execPrint();
	break;
    case EXECINDEXCHECK:
	execIndexCheck();
	break;
    case EXECCREATECOUNTER:
	execCreateCounter();
	break;
    case EXECDROPCOUNTER:
	execDropCounter();
	break;
    case EXECSETCOUNTER:
	execSetCounter();
	break;
    case EXECJDBCINFO:
	execJDBCInfo();
	break;
    case EXECDUMPTABLE:
	execDumpTable();
	break;
    case EXECDUMPBTREE:
	execDumpBTree();
	break;
    }
}

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////// exec semantic actions  //////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

void CegoAction::execSync() 
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");
    
    _pTabMng->getDBMng()->writeCheckPoint(_tableSet, true, true, _pTabMng->getLockHandle());
    
    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());
    
    msg = Chain("TableSet ") + _tableSet + Chain(" in sync");

    o.chainOut(msg);
}

void CegoAction::execListTableSet()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    ListT<Chain> tsList;
    _pTabMng->getDBMng()->getTableSetList(tsList);
    
    ListT<CegoField> schema;
    schema.Insert( CegoField("SYSTEM", "SYSTEM", "TABLESET", VARCHAR_TYPE, MAX_OBJNAME_LEN));
    
    CegoOutput o(schema);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());
    
    o.headOut();
    
    Chain *pS = tsList.First();
    while ( pS )
    {
	ListT<CegoFieldValue> fa;
	fa.Insert( CegoFieldValue(VARCHAR_TYPE, *pS) );
	o.rowOut(fa);
	pS = tsList.Next();
    }
    o.tailOut();
}    

void CegoAction::execListTable()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
	
    ListT<Chain> objList;
    _pTabMng->getObjectList(tabSetId, CegoObject::TABLE, objList);
    
    ListT<CegoField> schema;
    schema.Insert( CegoField("TABLE", "TABLE", "TABLENAME", VARCHAR_TYPE, MAX_OBJNAME_LEN));
    
    CegoOutput o(schema);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());
    
    o.headOut();
    
    Chain *pS = objList.First();
    while ( pS )
    {
	ListT<CegoFieldValue> fa;
	fa.Insert( CegoFieldValue(VARCHAR_TYPE, *pS) );
	o.rowOut(fa);
	pS = objList.Next();
    }
    o.tailOut();
}

void CegoAction::execListView()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");
    
    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);

    ListT<Chain> objList;
    _pTabMng->getObjectList(tabSetId, CegoObject::VIEW, objList);

    unsigned viewLen=0;
    Chain *pS = objList.First();    
    while ( pS )
    {
	if (viewLen < (unsigned)pS->length() )
	    viewLen = (unsigned)pS->length();
	pS = objList.Next();
    }

    ListT<CegoField> schema;
    schema.Insert( CegoField("View", "View", "Name", VARCHAR_TYPE, viewLen ));
    schema.Insert( CegoField("View", "View", "Status", VARCHAR_TYPE, 15 ));
    
    CegoOutput o(schema);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());
    
    o.headOut();
    
    pS = objList.First();
    while ( pS )
    {
	ListT<CegoFieldValue> fa;
	fa.Insert( CegoFieldValue(VARCHAR_TYPE, *pS) );

	if ( _pTabMng->checkCompView(tabSetId, *pS ) )
	    fa.Insert( CegoFieldValue(VARCHAR_TYPE, Chain("compiled")));
	else
	    fa.Insert( CegoFieldValue(VARCHAR_TYPE, Chain("not compiled")));
			    
	o.rowOut(fa);
	pS = objList.Next();
    }
    o.tailOut();
}    

void CegoAction::execListProc()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);

    ListT<Chain> objList;
    _pTabMng->getObjectList(tabSetId, CegoObject::PROCEDURE, objList);

    unsigned procLen=0;
    Chain *pS = objList.First();    
    while ( pS )
    {
	if (procLen < (unsigned)pS->length() )
	    procLen = (unsigned)pS->length();
	pS = objList.Next();
    }
    
    ListT<CegoField> schema;
    schema.Insert( CegoField("Procedure", "Procedure", "Name", VARCHAR_TYPE, procLen ));
    schema.Insert( CegoField("Procedure", "Procedure", "Status", VARCHAR_TYPE, 15 ));
    
    CegoOutput o(schema);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.headOut();
    
    pS = objList.First();
    while ( pS )
    {
	ListT<CegoFieldValue> fa;
	fa.Insert( CegoFieldValue(VARCHAR_TYPE, *pS) );

	if ( _pTabMng->checkCompProcedure(tabSetId, *pS ) )
	    fa.Insert( CegoFieldValue(VARCHAR_TYPE, Chain("compiled")));
	else
	    fa.Insert( CegoFieldValue(VARCHAR_TYPE, Chain("not compiled")));


	o.rowOut(fa);
	pS = objList.Next();
    }
    o.tailOut();
}    

void CegoAction::execListIndex()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
    
    ListT<Chain> objList;
    _pTabMng->getObjectList(tabSetId, CegoObject::AVLTREE, objList);
    
    ListT<CegoField> schema;
    schema.Insert( CegoField("Index", "Index", "Name", VARCHAR_TYPE, MAX_OBJNAME_LEN ));
    
    CegoOutput o(schema);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());
    
    o.headOut();
    
    Chain *pS = objList.First();
    while ( pS )
    {
	ListT<CegoFieldValue> fa;
	fa.Insert( CegoFieldValue(VARCHAR_TYPE, *pS) );       

	o.rowOut(fa);
	pS = objList.Next();
    }
    o.tailOut();
}    


void CegoAction::execListBTree()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
	
    ListT<Chain> objList;
    _pTabMng->getObjectList(tabSetId, CegoObject::BTREE, objList);
    
    ListT<CegoField> schema;
    schema.Insert( CegoField("Btree", "Btree", "Name", VARCHAR_TYPE, MAX_OBJNAME_LEN ));
    
    CegoOutput o(schema);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.headOut();
    
    Chain *pS = objList.First();
    while ( pS )
    {
	ListT<CegoFieldValue> fa;
	fa.Insert( CegoFieldValue(VARCHAR_TYPE, *pS) );       

	o.rowOut(fa);
	pS = objList.Next();
    }
    o.tailOut();
}    

void CegoAction::execListKey()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
    
    ListT<Chain> objList;
    _pTabMng->getObjectList(tabSetId, CegoObject::FKEY, objList);
    
    ListT<CegoField> schema;
    schema.Insert( CegoField("Key", "Key", "Name", VARCHAR_TYPE, MAX_OBJNAME_LEN ));
    
    CegoOutput o(schema);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());
    
    o.headOut();
    
    Chain *pS = objList.First();
    while ( pS )
    {
	ListT<CegoFieldValue> fa;
	fa.Insert( CegoFieldValue(VARCHAR_TYPE, *pS) );
	o.rowOut(fa);
	pS = objList.Next();
    }
    o.tailOut();
}    

void CegoAction::execListCounter()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");
    
    ListT<Chain> counterNameList;
    
    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
    _pTabMng->getDBMng()->getCounterList(tabSetId, counterNameList);    

    unsigned maxCounterLen=0;
    Chain *pS = counterNameList.First();
    while ( pS )
    {
	if ( (unsigned)pS->length() > maxCounterLen )
	    maxCounterLen = (unsigned)pS->length();
	pS = counterNameList.Next();
    }

    ListT<CegoField> schema;
    schema.Insert( CegoField("Counter", "Counter", "Name", VARCHAR_TYPE, maxCounterLen ));
    schema.Insert( CegoField("Counter", "Counter", "Value", LONG_TYPE, sizeof(long long) ));
    
    CegoOutput o(schema);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.headOut();
    
    pS = counterNameList.First();
    while ( pS )
    {
	ListT<CegoFieldValue> fa;
	fa.Insert( CegoFieldValue(VARCHAR_TYPE, *pS) );
        unsigned long long v = _pTabMng->getDBMng()->getCounterValue(tabSetId, *pS);
	fa.Insert( CegoFieldValue(LONG_TYPE, Chain(v)));
	o.rowOut(fa);
	pS = counterNameList.Next();
    }
    o.tailOut();    
}

void CegoAction::execListTmpObj()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
    
    ListT<Chain> objList;
    _pTabMng->getObjectList(tabSetId, CegoObject::RBSEG, objList);
    
    ListT<CegoField> schema;
    schema.Insert( CegoField("TmpObj", "TmpObj", "Name", VARCHAR_TYPE, MAX_OBJNAME_LEN ));
    
    CegoOutput o(schema);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());
    
    o.headOut();
    
    Chain *pS = objList.First();
    while ( pS )
    {
	ListT<CegoFieldValue> fa;
	fa.Insert( CegoFieldValue(VARCHAR_TYPE, *pS) );
	o.rowOut(fa);
	pS = objList.Next();
    }
    o.tailOut();    
}

void CegoAction::execListSysObj()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
    
    ListT<Chain> objList;
    _pTabMng->getObjectList(tabSetId, CegoObject::SYSTEM, objList);
    
    ListT<CegoField> schema;
    schema.Insert( CegoField("SysObj", "SysObj", "Name", VARCHAR_TYPE, MAX_OBJNAME_LEN ));
    
    CegoOutput o(schema);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.headOut();
    
    Chain *pS = objList.First();
    while ( pS )
    {
	ListT<CegoFieldValue> fa;
	fa.Insert( CegoFieldValue(VARCHAR_TYPE, *pS) );
	o.rowOut(fa);
	pS = objList.Next();
    }
    o.tailOut();    
}

void CegoAction::execListCheck()
{

    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
	
    ListT<Chain> objList;
    _pTabMng->getObjectList(tabSetId, CegoObject::CHECK, objList);
    
    ListT<CegoField> schema;
    schema.Insert( CegoField("Check", "Check", "Name", VARCHAR_TYPE, MAX_OBJNAME_LEN ));
    
    CegoOutput o(schema);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.headOut();
    
    Chain *pS = objList.First();
    while ( pS )
    {
	ListT<CegoFieldValue> fa;
	fa.Insert( CegoFieldValue(VARCHAR_TYPE, *pS) );
	o.rowOut(fa);
	pS = objList.Next();
    }
    o.tailOut();    
}

void CegoAction::execListTrigger()
{

    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
    
    ListT<Chain> objList;
    _pTabMng->getObjectList(tabSetId, CegoObject::TRIGGER, objList);
    
    ListT<CegoField> schema;
    schema.Insert( CegoField("Trigger", "Trigger", "Name", VARCHAR_TYPE, MAX_OBJNAME_LEN ));
    
    CegoOutput o(schema);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.headOut();
    
    Chain *pS = objList.First();
    while ( pS )
    {
	ListT<CegoFieldValue> fa;
	fa.Insert( CegoFieldValue(VARCHAR_TYPE, *pS) );
	o.rowOut(fa);
	pS = objList.Next();
    }
    o.tailOut();    
}

void CegoAction::execListAlias()
{

    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
    
    ListT<Chain> objList;
    _pTabMng->getObjectList(tabSetId, CegoObject::ALIAS, objList);
    
    ListT<CegoField> schema;
    schema.Insert( CegoField("Alias", "Alias", "Name", VARCHAR_TYPE, MAX_OBJNAME_LEN ));
    
    CegoOutput o(schema);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.headOut();
    
    Chain *pS = objList.First();
    while ( pS )
    {
	ListT<CegoFieldValue> fa;
	fa.Insert( CegoFieldValue(VARCHAR_TYPE, *pS) );
	o.rowOut(fa);
	pS = objList.Next();
    }
    o.tailOut();    
}

void CegoAction::execJDBCInfo()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    CegoJDBCInfo jdbcInfo(_pTabMng, _pDbHandle);

    jdbcInfo.handleRequest( _jdbcArgList );
}

void CegoAction::jdbcArg1()
{
    Chain* pS = getTokenList().First();
    _jdbcArgList.Insert(*pS);
}

void CegoAction::jdbcArg2()
{
    _jdbcArgList.Empty();
    Chain* pS = getTokenList().First();
    _jdbcArgList.Insert(*pS);    
}

void CegoAction::execDumpTable()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");
	
    Chain tableName;
    Chain tableSet;

    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);

    Chain chainDump;
    _pTabMng->dumpObject(tableSet, tableName, CegoObject::TABLE, chainDump);
    
    unsigned maxLen = 0;
    Tokenizer tok(chainDump, Chain("\n"));
    Chain l;
    while ( tok.nextToken(l) )
    {
	if ( maxLen < (unsigned)l.length() )
	    maxLen = (unsigned)l.length();
    }

    ListT<CegoField> schema;
    schema.Insert(CegoField(Chain("TABDUMP"), Chain("TABDUMP"), tableName, VARCHAR_TYPE, maxLen));

    ListT< ListT < CegoFieldValue > > fa;    
    ListT<CegoFieldValue> fvl;
    fvl.Insert(CegoFieldValue(VARCHAR_TYPE, chainDump));
    fa.Insert(fvl);

    CegoOutput o(schema, Chain("m"));

    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);    
}

void CegoAction::execDumpBTree()
{
   if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");
	
    Chain btreeName;
    Chain tableSet;

    _objNameStack.Pop(btreeName);
    _objTableSetStack.Pop(tableSet);

    Chain chainDump;
    _pTabMng->dumpObject(tableSet, btreeName, CegoObject::BTREE, chainDump);
    
    unsigned maxLen = 0;
    Tokenizer tok(chainDump, Chain("\n"));
    Chain l;
    while ( tok.nextToken(l) )
    {
	if ( maxLen < (unsigned)l.length() )
	    maxLen = (unsigned)l.length();
    }

    ListT<CegoField> schema;
    schema.Insert(CegoField(Chain("BTREEDUMP"), Chain("BTREEDUMP"), btreeName, VARCHAR_TYPE, maxLen));

    ListT< ListT < CegoFieldValue > > fa;    
    ListT<CegoFieldValue> fvl;
    fvl.Insert(CegoFieldValue(VARCHAR_TYPE, chainDump));
    fa.Insert(fvl);

    CegoOutput o(schema, Chain("m"));

    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);    
}


void CegoAction::setTableSetOpt()
{
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	_tableSet = *pS;
    }
}

void CegoAction::execTupleInfo()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    
    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);

    CegoTableObject toe;
    _pTabMng->getQueryObject(tableSet, tableName, CegoObject::TABLE, toe);
    
    ListT<CegoField> schema = toe.getSchema();
    
    CegoObjectCursor *pOC = _pTabMng->getObjectCursor(tabSetId, tableName, tableName, CegoObject::TABLE);


    unsigned long long rowCount = 0;
    unsigned long long numInserted = 0;
    unsigned long long numDeleted = 0;
    unsigned long long numObsolete = 0;
    unsigned long long numCommitted = 0;
	
    unsigned len;
    CegoDataPointer dp;
    char* pc = (char*)pOC->getFirst(len, dp);

    while ( pc && len > 0 )
    {
	rowCount++;
	
	unsigned long long tid;
	unsigned long long tastep; 
	CegoTupleState ts;

	// decodeTupleHeader returns toff, but is not needed here
	CegoQueryHelper::decodeTupleHeader(tid, tastep, ts, pc);

	// cout << "Decoding tuple header with tid = " << tid << " tastep = " << tastep << " ts=" << ts << endl;
	if ( tid != 0 ) 
	{
	    if  ( ts == CegoTupleState::INSERTED )
		numInserted++;
	    else if ( ts == CegoTupleState::DELETED )
		numDeleted++;
	    else if ( ts == CegoTupleState::OBSOLETE )
		numObsolete++;
	    else if ( ts == CegoTupleState::COMMITTED )
		numCommitted++;
	}
	
	pc = (char*)pOC->getNext(len, dp);
    }
        
    ListT< ListT < CegoFieldValue > > fa;

    ListT<CegoField> tupleSchema;
    tupleSchema.Insert(CegoField(Chain("TUPLEINFO"), Chain("TUPLEINFO"), Chain("ROWS"), VARCHAR_TYPE, 15));
    tupleSchema.Insert(CegoField(Chain("TUPLEINFO"), Chain("TUPLEINFO"), Chain("COMMITTED"), VARCHAR_TYPE, 15));
    tupleSchema.Insert(CegoField(Chain("TUPLEINFO"), Chain("TUPLEINFO"), Chain("DELETED"), VARCHAR_TYPE, 15));
    tupleSchema.Insert(CegoField(Chain("TUPLEINFO"), Chain("TUPLEINFO"), Chain("INSERTED"), VARCHAR_TYPE, 15));
    tupleSchema.Insert(CegoField(Chain("TUPLEINFO"), Chain("TUPLEINFO"), Chain("OBSOLETE"), VARCHAR_TYPE, 15));

    CegoTableObject oe = CegoTableObject(0, CegoObject::SYSTEM, Chain("SYSINFO"), tupleSchema, Chain("SYSINFO"));

    ListT<CegoFieldValue> fv;
    
    fv.Insert(CegoFieldValue(VARCHAR_TYPE, Chain(rowCount)));	
    fv.Insert(CegoFieldValue(VARCHAR_TYPE, Chain(numCommitted)));
    fv.Insert(CegoFieldValue(VARCHAR_TYPE, Chain(numDeleted)));
    fv.Insert(CegoFieldValue(VARCHAR_TYPE, Chain(numInserted)));
    fv.Insert(CegoFieldValue(VARCHAR_TYPE, Chain(numObsolete)));
    fa.Insert(fv);

    CegoOutput o(oe.getSchema());
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);   
}

void CegoAction::execTableInfo()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    
    ListT<CegoTableObject> idxList;
    ListT<CegoBTreeObject> btreeList;
    ListT<CegoKeyObject> keyList;
    ListT<CegoCheckObject> checkList;
    ListT<CegoTriggerObject> triggerList;
    ListT<CegoAliasObject> aliasList;
    unsigned numInvalid;

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
	
    _pTabMng->getObjectListByTable(tabSetId, tableName, idxList, btreeList, keyList, checkList, triggerList, aliasList, numInvalid);

    CegoTableObject oe;
    ListT< ListT < CegoFieldValue > > fa;
    
    formatTableInfo(tableSet, tableName, idxList, btreeList, keyList, checkList, triggerList, aliasList, oe, fa, false);
    
    CegoOutput o(oe.getSchema());
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);   
}

void CegoAction::execTableSize()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    
    ListT<CegoTableObject> idxList;
    ListT<CegoBTreeObject> btreeList;
    ListT<CegoKeyObject> keyList;
    ListT<CegoCheckObject> checkList;
    ListT<CegoTriggerObject> triggerList;
    ListT<CegoAliasObject> aliasList;
    unsigned numInvalid;

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
    
    _pTabMng->getObjectListByTable(tabSetId, tableName, idxList, btreeList, keyList, checkList, triggerList, aliasList, numInvalid);

    CegoTableObject oe;
    ListT< ListT < CegoFieldValue > > fa;

    formatTableInfo(tableSet, tableName, idxList, btreeList, keyList, checkList, triggerList, aliasList, oe, fa, true);
    
    CegoOutput o(oe.getSchema());
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());
    
    o.tabOut(fa);   
}

void CegoAction::execShowUptime() 
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");
    
    ListT<CegoField> schema;
    schema.Insert( CegoField("BUFFERPOOL", "BUFFERPOOL", "UPTIME", VARCHAR_TYPE, MAX_OBJNAME_LEN));

    CegoOutput o(schema);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.headOut();
    
    unsigned long long uptime = _pTabMng->getDBMng()->uptime();

    // calculate time string
    unsigned long long d = uptime / ( 3600 * 24 );
    unsigned long long h = ( uptime - ( d * 24 * 3600 )) / 3600;
    unsigned long long m = ( uptime - ( d * 24 * 3600 ) - ( h * 3600) ) / 60;
    unsigned long long s = uptime % 60;
    
    Chain ss = Chain("0") + Chain(s);
    Chain sec = ss.subChain(ss.length()-2,ss.length());

    Chain ms = Chain("0") + Chain(m);
    Chain min = ms.subChain(ms.length()-2,ms.length());
    
    Chain uptimeString = Chain(d) + Chain(" days, ") + Chain(h) + Chain(":") + min + Chain(":") + sec; 

    ListT<CegoFieldValue> t1;
    t1.Insert( CegoFieldValue(VARCHAR_TYPE, uptimeString));
    o.rowOut(t1);   
    o.tailOut();   	        
}

void CegoAction::execShowPool() 
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    CegoTableObject oe;
    ListT< ListT < CegoFieldValue > > fa;
    
    _pTabMng->getPoolInfo(oe, fa);
    
    CegoOutput o(oe.getSchema());
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);
}

void CegoAction::execShowSystemSpace() 
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    CegoTableObject oe;
    ListT< ListT < CegoFieldValue > > fa;
    
    Chain format;
    _pTabMng->getSystemInfo(_tableSet, oe, fa, format);
    
    CegoOutput o(oe.getSchema(), format);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);
} 

void CegoAction::execTableDesc()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    
    ListT<CegoField> schema;
    ListT< ListT < CegoFieldValue > > fa;

    if ( tableName[0] == SYSTAB_PREFIX )
    {
	Chain sysTable = tableName.truncLeft(Chain(SYSTAB_PREFIX));
	_pTabMng->getObjectDesc(tableSet, sysTable, CegoObject::SYSTEM, schema, fa);
    }
    else
    {
	_pTabMng->getObjectDesc(tableSet, tableName, CegoObject::TABLE, schema, fa);
    }

    CegoOutput o(schema);

    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);    
}

void CegoAction::execIndexDesc()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain idxName;
    Chain tableSet;
    
    _objNameStack.Pop(idxName);
    _objTableSetStack.Pop(tableSet);

    ListT<CegoField> schema;
    ListT< ListT < CegoFieldValue > > fa;
    
    _pTabMng->getObjectDesc(tableSet, idxName, CegoObject::AVLTREE, schema, fa);
    
    CegoOutput o(schema);

    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);
}

void CegoAction::execBTreeDesc()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain btreeName;
    Chain tableSet;
    
    _objNameStack.Pop(btreeName);
    _objTableSetStack.Pop(tableSet);

    
    ListT<CegoField> schema;
    ListT< ListT < CegoFieldValue > > fa;
    
    _pTabMng->getObjectDesc(tableSet, btreeName, CegoObject::BTREE, schema, fa);
    
    CegoOutput o(schema);

    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);
}

void CegoAction::execKeyDesc()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain keyName;
    Chain tableSet;

    _objNameStack.Pop(keyName);
    _objTableSetStack.Pop(tableSet);

    ListT<CegoField> schema;
    ListT< ListT < CegoFieldValue > > fa;
    
    _pTabMng->getObjectDesc(tableSet, keyName, CegoObject::FKEY, schema, fa);
    
    CegoOutput o(schema);

    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);
}

void CegoAction::execCheckDesc()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain checkName;
    Chain tableSet;

    _objNameStack.Pop(checkName);
    _objTableSetStack.Pop(tableSet);

        
    ListT<CegoField> schema;
    ListT< ListT < CegoFieldValue > > fa;
    
    _pTabMng->getObjectDesc(tableSet, checkName, CegoObject::CHECK, schema, fa);
    
    CegoOutput o(schema);

    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);
}

void CegoAction::execAliasDesc()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain aliasName;
    Chain tableSet;

    _objNameStack.Pop(aliasName);
    _objTableSetStack.Pop(tableSet);

        
    ListT<CegoField> schema;
    ListT< ListT < CegoFieldValue > > fa;
    
    _pTabMng->getObjectDesc(tableSet, aliasName, CegoObject::ALIAS, schema, fa);
    
    CegoOutput o(schema);

    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);
}

void CegoAction::execViewDesc()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain viewName;
    Chain tableSet;

    _objNameStack.Pop(viewName);
    _objTableSetStack.Pop(tableSet);
        
    ListT<CegoField> schema;
    ListT< ListT < CegoFieldValue > > fa;

    _pTabMng->getObjectDesc(tableSet, viewName, CegoObject::VIEW, schema, fa);

    CegoOutput o(schema);

    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);
   
}

void CegoAction::execProcDesc()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain procName;
    Chain procTableSet;
    
    _objNameStack.Pop(procName);
    _objTableSetStack.Pop(procTableSet);
    
    ListT<CegoField> schema;
    ListT< ListT < CegoFieldValue > > fa;
    
    _pTabMng->getObjectDesc(procTableSet, procName, CegoObject::PROCEDURE, schema, fa);
    
    CegoOutput o(schema);

    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);
}

void CegoAction::execViewShow()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain viewName;
    Chain viewTableSet;
    
    _objNameStack.Pop(viewName);
    _objTableSetStack.Pop(viewTableSet);
    
    CegoViewObject vo;
    _pTabMng->getQueryObject(viewTableSet, viewName,  CegoObject::VIEW, vo);

    unsigned maxLen = 0;
    Tokenizer tok(vo.getViewStmt(), Chain("\n"));
    Chain l;
    while ( tok.nextToken(l) )
    {
	if ( maxLen < (unsigned)l.length() )
	    maxLen = (unsigned)l.length();
    }

    ListT<CegoField> schema;
    schema.Insert(CegoField(Chain("VIEWTEXT"), Chain("VIEWTEXT"), viewName, VARCHAR_TYPE, maxLen));

    ListT< ListT < CegoFieldValue > > fa;    
    ListT<CegoFieldValue> fvl;
    fvl.Insert(CegoFieldValue(VARCHAR_TYPE, vo.getViewStmt()));
    fa.Insert(fvl);

    CegoOutput o(schema, Chain("m"));

    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);
}

void CegoAction::execCheckShow()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain checkName;
    Chain checkTableSet;
    
    _objNameStack.Pop(checkName);
    _objTableSetStack.Pop(checkTableSet);
    
    CegoCheckObject co;
    _pTabMng->getQueryObject(checkTableSet, checkName, CegoObject::CHECK, co);

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(checkTableSet);
	
    unsigned maxLen = 0;
    Tokenizer tok(co.getPredDesc()->toChain(tabSetId), Chain("\n"));
    Chain l;
    while ( tok.nextToken(l) )
    {
	if ( maxLen < (unsigned)l.length() )
	    maxLen = (unsigned)l.length();
    }

    ListT<CegoField> schema;
    schema.Insert(CegoField(Chain("CHECKTEXT"), Chain("CHECKTEXT"), checkName, VARCHAR_TYPE, maxLen));

    ListT< ListT < CegoFieldValue > > fa;
    ListT<CegoFieldValue> fvl;
    fvl.Insert(CegoFieldValue(VARCHAR_TYPE, co.getPredDesc()->toChain(tabSetId)));
    fa.Insert(fvl);

    CegoOutput o(schema, Chain("m"));

    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);
}

void CegoAction::execTriggerShow()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain triggerName;
    Chain triggerTableSet;
    
    _objNameStack.Pop(triggerName);
    _objTableSetStack.Pop(triggerTableSet);
    
    CegoTriggerObject to;
    _pTabMng->getQueryObject(triggerTableSet, triggerName, CegoObject::TRIGGER, to);

    unsigned maxLen = 0;
    Tokenizer tok(to.toChain(), Chain("\n"));
    Chain l;
    while ( tok.nextToken(l) )
    {
	if ( maxLen < (unsigned)l.length() )
	    maxLen = (unsigned)l.length();
    }

    ListT<CegoField> schema;
    schema.Insert(CegoField(Chain("TRIGGERTEXT"), Chain("TRIGGERTEXT"), triggerName, VARCHAR_TYPE, maxLen));

    ListT< ListT < CegoFieldValue > > fa;
    ListT<CegoFieldValue> fvl;
    fvl.Insert(CegoFieldValue(VARCHAR_TYPE, to.toChain()));
    fa.Insert(fvl);

    CegoOutput o(schema, Chain("m"));

    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);
}

void CegoAction::execProcShow()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain procName;
    Chain procTableSet;
    
    _objNameStack.Pop(procName);
    _objTableSetStack.Pop(procTableSet);
    
    CegoProcObject po;
    _pTabMng->getQueryObject(procTableSet, procName, CegoObject::PROCEDURE, po);

    unsigned maxLen = 0;
    Tokenizer tok(po.getProcText(), Chain("\n"));
    Chain l;
    while ( tok.nextToken(l) )
    {
	if ( maxLen < (unsigned)l.length() )
	    maxLen = (unsigned)l.length();
    }

    ListT<CegoField> schema;
    ListT< ListT < CegoFieldValue > > fa;
    schema.Insert(CegoField(Chain("PROCTEXT"), Chain("PROCTEXT"), procName, VARCHAR_TYPE, maxLen));

    ListT<CegoFieldValue> fvl;
    fvl.Insert(CegoFieldValue(VARCHAR_TYPE, po.getProcText()));
    fa.Insert(fvl);
    
    CegoOutput o(schema, Chain("m"));
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.tabOut(fa);
}

void CegoAction::execSetTableSet()
{
    Chain tableSet;
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	tableSet = *pS;
    }
	
    setTableSet(tableSet);
    
    CegoOutput o;
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
    {
	if ( _pTabMng == 0 )
	    throw Exception(EXLOC, "No valid table manager set up");	
	o.setDBMng(_pTabMng->getDBMng());
    }

    msg = Chain("Tableset ") + tableSet + Chain(" set");
    o.chainOut(msg);
}

void CegoAction::execAuthUser()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain tableSet;
    Chain user;
    Chain passwd(_stringBuf);

    Chain* pS = getTokenList().First();
    if ( pS )
    {
	tableSet = *pS;
    }
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    if ( pS )
    {
	user = *pS;
    }
   
    AESCrypt aescrypt(CEGOAESKEY, CEGOAESKEYLEN);
    _pTabMng->setActiveUser(tableSet, user, aescrypt.encrypt(passwd));

    CegoOutput o;
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    msg = Chain("User ") + user + Chain(" authorized for ") + tableSet;
    o.chainOut(msg);
}

void CegoAction::execEnableGraceMode()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    _isGrace = true;


    _pTabMng->setGraceMode(_isGrace);

    
    CegoOutput o;	
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    Chain msg;
    msg = Chain("Grace mode enabled");   
    o.chainOut(msg);
}

void CegoAction::execDisableGraceMode()
{

    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    _isGrace = false;

    _pTabMng->setGraceMode(_isGrace);

    CegoOutput o;	
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    Chain msg;
    msg = Chain("Grace mode disabled");
    o.chainOut(msg);
}

void CegoAction::execEnableAppendMode()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    _pTabMng->setAppend(true);

    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    msg = Chain("Append mode enabled");   
    o.chainOut(msg);
}

void CegoAction::execDisableAppendMode()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    _pTabMng->setAppend(false);

    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    msg = Chain("Append mode disabled");
    o.chainOut(msg);
}

void CegoAction::execEnableAutoCommit()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    _pTabMng->setAutoCommit(true);

    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    msg = Chain("AutoCommit enabled");
    
    o.chainOut(msg);
}

void CegoAction::execDisableAutoCommit()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    _pTabMng->setAutoCommit(false);
    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    msg = Chain("AutoCommit disabled");
    
    o.chainOut(msg);
}

void CegoAction::execSetIsolation()
{
    
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain level;
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	level = *pS;
    }
	
    if ( level.toLower() == Chain("read_uncommitted") )
    {
	_pTabMng->setIsolationLevel(CegoTableManager::READ_UNCOMMITTED);
    }
    else if ( level.toLower() == Chain("read_committed") )
    {
	_pTabMng->setIsolationLevel(CegoTableManager::READ_COMMITTED);
    }
    else
    {
	throw Exception(EXLOC, "Unknown isolation level " + level);
    }

    CegoOutput o;
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    msg = Chain("Isolation level set");
    
    o.chainOut(msg);
}

void CegoAction::execTableReorganize()
{
    
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain objName;
    Chain tableSet;
    
    _objNameStack.Pop(objName);
    _objTableSetStack.Pop(tableSet);
    
    _pTabMng->reorgQueryObject(tableSet, objName, CegoObject::TABLE);
    
    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    msg = Chain("Table ") + objName + Chain(" reorganized");
    
    o.chainOut(msg);    
}

void CegoAction::execIndexReorganize()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");
    
    Chain objName;
    Chain tableSet;
    
    _objNameStack.Pop(objName);
    _objTableSetStack.Pop(tableSet);
    
    _pTabMng->reorgQueryObject(tableSet, objName, CegoObject::AVLTREE);
    
    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    msg = Chain("Index ") + objName + Chain(" reorganized");
    
    o.chainOut(msg);    
}

void CegoAction::execSelect()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    if ( _pSelect )
    {	
	try
	{           
	    _pSelect->setProcBlock(_pMasterBlock);

	    _pSelect->prepare();
	    _pSelect->setParentJoinBuf();

	    _pSelect->checkValidRef();


	    ListT<CegoField> schema;
	    _pSelect->getSchema(schema);
	    
	    CegoOutput output(schema);
   
	    if ( _pDbHandle )
		output.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
	    else if ( _logToFile )
		output.setDBMng(_pTabMng->getDBMng());

	    output.headOut();

	    ListT<CegoField> fl;

	    bool moreTuple = _pSelect->nextTuple(fl);

	    while ( moreTuple )
	    {
		output.rowOut(fl);

		if ( _pDbHandle )
		{
		    if ( _pDbHandle->wasReset() )
		    {		    
			_pSelect->reset();
		    }
		}

		// we have to catch abort requests separately
		
		try
		{
		    moreTuple = _pSelect->nextTuple(fl);
		}
                catch ( Exception e )
                {		    
		    Chain msg;
		    e.pop(msg);
		    output.abort(msg);
                    moreTuple=false;
                    delete _pSelect;
		    _pSelect = 0;
                    return;
		}
	    }
	    
	    output.tailOut();

	    delete _pSelect;
	    _pSelect = 0;
	}
	catch ( Exception e )
	{
	    delete _pSelect;
	    _pSelect = 0;
	    throw Exception(EXLOC, Chain("Cannot execute select"), e);
	}
    }
    else
    {
	throw Exception(EXLOC, "No valid select handle");
    }
}

void CegoAction::execSelectPlan()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    if ( _pSelect )
    {
	try
	{           
	    _pSelect->prepare();
	    _pSelect->setProcBlock(_pMasterBlock);
	    _pSelect->checkValidRef();
	    
	    Chain planString;
	    planString = getPlanString(_pSelect->getPlan(), Chain("Execution plan"));
	    
	    unsigned maxLen = 0;
	    Tokenizer tok(planString, Chain("\n"));
	    Chain l;
	    while ( tok.nextToken(l) )
	    {
		if ( maxLen < (unsigned)l.length() )
		    maxLen = (unsigned)l.length();
	    }
	    
	    ListT<CegoField> schema;
	    ListT< ListT < CegoFieldValue > > fa;
	    schema.Insert(CegoField(Chain("PLAN"), Chain("PLAN"), Chain("DESCRIPTION"), VARCHAR_TYPE, maxLen));
	    
	    ListT<CegoFieldValue> fvl;
	    fvl.Insert(CegoFieldValue(VARCHAR_TYPE, planString));
	    fa.Insert(fvl);

	    CegoOutput o(schema, Chain("m"));
    
	    if ( _pDbHandle )
		o.setDbHandle(_pDbHandle);
	    else if ( _logToFile )
		o.setDBMng(_pTabMng->getDBMng());

	    o.tabOut(fa);	    
		
	    delete _pSelect;
	    _pSelect = 0;
	}
	catch ( Exception e )
	{
	    delete _pSelect;
	    _pSelect = 0;
	    throw Exception(EXLOC, "Cannot evaluate plan", e);
	}
    }
    else
    {
	throw Exception(EXLOC, Chain("No valid select handle"));
    }
}

void CegoAction::execQuery()
{
    try 
    {	
	Chain msg;
	CegoOutput o;

	msg = _pQuery->execute(_pMasterBlock);
	unsigned long long affCount = _pQuery->getAffectedCount();

	if ( _pDbHandle )
	    o.setDbHandle(_pDbHandle);
	else if ( _logToFile )
	    o.setDBMng(_pTabMng->getDBMng());

	o.chainOut(msg, affCount);
	
	delete _pQuery;
	_pQuery=0;	
    }
    catch ( Exception e )
    {
	delete _pQuery;
	_pQuery = 0;
	throw Exception(EXLOC, Chain("Cannot execute query"), e);
    }
}

void CegoAction::execViewCreate() 
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain viewName;
    Chain tableSet;
    
    _objNameStack.Pop(viewName);
    _objTableSetStack.Pop(tableSet);

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
    ListT<CegoField> schema;

    try
    {
	_pSelect->prepare(_isGrace);
	
	if ( _pSelect->hasAliasReference() )
	{
	    if ( _isGrace == false )
		_pSelect->getSchema(schema);
	}
	else
	{
	    throw Exception(EXLOC, "Missing alias reference for view create");
	}
    }
    catch ( Exception e )
    {	
	delete _pSelect;
	_pSelect = 0;
	throw Exception(EXLOC, Chain("Cannot create view"), e);
    }

    Chain viewStmt = Chain("view ") + viewName + Chain(" as\n") + _pSelect->toChain(tabSetId) + Chain(";");
    _pTabMng->createQueryView(tableSet, viewName, schema, viewStmt);

    _pTabMng->getDBMng()->useObject(tabSetId, viewName, CegoObject::VIEW, CegoDatabaseManager::EXCLUSIVE_WRITE, _pTabMng);
    
    try
    {	    	    
	if ( _pDbPool ) 
	{
	    // object is invalidated for recompilation by each db thread
	    _pDbPool->invalidateObject(tabSetId, viewName, CegoObject::VIEW);
	    delete _pSelect;
	    _pSelect = 0;
	}
	else
	{
	    // in grace mode, views have to be recompiled for usage 
	    if ( _isGrace == false )
	    {
		CegoView *pView = new CegoView(viewName, _pSelect);
		_pTabMng->addCompView(tabSetId, pView);
		_pSelect = 0;
	    }
	    else
	    {
		delete _pSelect;
		_pSelect = 0;
	    }
	}	    
    }
    catch ( Exception e )
    {
	if ( _pSelect )
	    delete _pSelect;
	_pSelect = 0;
	
	_pTabMng->getDBMng()->unuseObject(tabSetId, viewName, CegoObject::VIEW);
	Chain msg = Chain("Compile error for view ") + viewName;
	throw Exception(EXLOC, msg, e );
    }
    _pTabMng->getDBMng()->unuseObject(tabSetId, viewName, CegoObject::VIEW);
    
    Chain msg;
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    msg = Chain("View ") + viewName + Chain(" created");
    
    o.chainOut(msg);    
}

void CegoAction::execViewLoad() 
{
    CegoOutput o;
    if ( _pDbHandle )
    {
	o.setDbHandle(_pDbHandle);	
	Chain msg = Chain("View loaded (Note : This statement is for internal use only)");	
	o.chainOut(msg);
    }
}

void CegoAction::execQueryCondLoad() 
{
    _condDescStack.Pop(_pCond);

    CegoOutput o;
    if ( _pDbHandle )
    {
	o.setDbHandle(_pDbHandle);	
	Chain msg = Chain("Condition loaded (Note : This statement is for internal use only)");
	o.chainOut(msg);
    }
}

void CegoAction::execViewDrop() 
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain viewName;
    Chain tableSet;
    
    _objNameStack.Pop(viewName);
    _objTableSetStack.Pop(tableSet);

    bool doDrop=true;

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
    
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->objectExists(tabSetId, viewName, CegoObject::VIEW) == false )
	    doDrop=false;
    }

    Chain msg;
    
    if ( doDrop )
    {   

	_pTabMng->dropQueryObject(viewName, tableSet, CegoObject::VIEW);
	
	if ( _pDbPool )
	    _pDbPool->invalidateObject(tabSetId, viewName, CegoObject::VIEW);
	else
	    _pTabMng->removeCompView(tabSetId, viewName);
	
	msg = Chain("View ") + viewName + Chain(" dropped");	
    }
    else
    {
	msg = Chain("View ") + viewName + Chain(" does not exist");
    }
    
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.chainOut(msg);
}

void CegoAction::execTriggerCreate()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");
    
    Chain triggerName;
    unsigned tabSetId;

    if ( _pTrigger )
    {
	triggerName = _pTrigger->getName();
	tabSetId = _pTabMng->getDBMng()->getTabSetId(_triggerTableSet);

	Chain triggerText = _pTrigger->getTriggerText(tabSetId);
	
	Chain triggerEscText;
	
	if ( __quoteEscapeFlag )
	{
	    // nothing to do
	    triggerEscText = triggerText;
	}
	else
	{
	    triggerText.replaceAll(Chain("\\"), Chain("\\\\"), triggerEscText);
	}
	
	_pTabMng->createQueryTrigger(_triggerTableSet, _pTrigger->getName(),
				    _pTrigger->isBefore(),
				    _pTrigger->isOnInsert(),
				    _pTrigger->isOnUpdate(),
				    _pTrigger->isOnDelete(),
				    _pTrigger->getTableName(),
				    triggerEscText);
    }
    else
    {
	Chain msg = Chain("Cannot create trigger") + triggerName;
	throw Exception(EXLOC, msg);
    }

    _pTabMng->getDBMng()->useObject(tabSetId, triggerName, CegoObject::TRIGGER, CegoDatabaseManager::EXCLUSIVE_WRITE, _pTabMng);

    try 
    {
	if ( _pDbPool ) 
	{
	    // object is invalidated for recompilation by  each db thread
	    _pDbPool->invalidateObject(tabSetId, _pTrigger->getName(), CegoObject::TRIGGER);
	    delete _pTrigger;
	    _pTrigger = 0;
	}
	else
	{
	    if ( _isGrace == false )
	    {
		_pTabMng->addCompTrigger(tabSetId, _pTrigger);
	    }
	    else
	    {
		delete _pTrigger;
	    }
	    _pTrigger = 0;
	}
	
	Chain msg;
	CegoOutput o;
	
	if ( _pDbHandle )
	    o.setDbHandle(_pDbHandle);
	else if ( _logToFile )
	    o.setDBMng(_pTabMng->getDBMng());
	
	msg = Chain("Trigger ") + triggerName + Chain(" created");
	
	o.chainOut(msg);	
    }
    catch ( Exception e )
    {
	if ( _pTrigger )
	    delete _pTrigger;
	
	_pTabMng->getDBMng()->unuseObject(tabSetId, triggerName, CegoObject::TRIGGER);
	throw Exception(EXLOC, Chain("Cannot create trigger"), e);
    }

    _pTabMng->getDBMng()->unuseObject(tabSetId, triggerName, CegoObject::TRIGGER);
}

void CegoAction::execTriggerLoad()
{
    CegoOutput o;
    if ( _pDbHandle )
    {
	o.setDbHandle(_pDbHandle);	
	Chain msg = Chain("Trigger loaded (Note : This statement is for internal use only)");
	o.chainOut(msg);
    }
}

void CegoAction::execTriggerDrop()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain triggerName;
    Chain tableSet;
    
    _objNameStack.Pop(triggerName);
    _objTableSetStack.Pop(tableSet);

    bool doDrop=true;

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
    
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->objectExists(tabSetId, triggerName, CegoObject::TRIGGER) == false )
	    doDrop=false;
    }

    Chain msg;
    
    if ( doDrop )
    {
	
	_pTabMng->getDBMng()->useObject(tabSetId, triggerName, CegoObject::TRIGGER, CegoDatabaseManager::EXCLUSIVE_WRITE, _pTabMng);
	
	try
	{	  
	    _pTabMng->dropQueryObject(triggerName, tableSet, CegoObject::TRIGGER);
	    
	    if ( _pDbPool )
	    {
		_pDbPool->invalidateObject(tabSetId, triggerName, CegoObject::TRIGGER);
	    }
	    else
	    {
		_pTabMng->removeCompTrigger(tabSetId, triggerName);
	    }
	    msg = Chain("Trigger ") + triggerName + Chain(" dropped");
	}
	catch ( Exception e)
	{
	    _pTabMng->getDBMng()->unuseObject(tabSetId, triggerName, CegoObject::TRIGGER);
	    throw Exception(EXLOC, Chain("Cannot drop trigger"), e);
	}

	_pTabMng->getDBMng()->unuseObject(tabSetId, triggerName, CegoObject::TRIGGER);	
    }
    else
    {
	msg = Chain("Trigger ") + triggerName + Chain(" does not exist");
    }

    CegoOutput o;    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());

    o.chainOut(msg);
}

void CegoAction::execProcCreate()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain procName;
    unsigned tabSetId;

    if ( _pProc )
    {
	procName = _pProc->getName();
	tabSetId = _pTabMng->getDBMng()->getTabSetId(_procTableSet);

	Chain procText = _pProc->toChain(tabSetId) + Chain(";");
	
	Chain procEscText;
	
	if ( __quoteEscapeFlag )
	{
	    // nothing to do
	    procEscText = procText;
	}
	else
	{
	    procText.replaceAll(Chain("\\"), Chain("\\\\"), procEscText);
	}
	
	_pTabMng->createQueryProc(_procTableSet, _pProc->getName(), procEscText);
    }
    else
    {
	Chain msg = Chain("Cannot create procedure ") + procName;
	throw Exception(EXLOC, msg);
    }

    _pTabMng->getDBMng()->useObject(tabSetId, procName, CegoObject::PROCEDURE, CegoDatabaseManager::EXCLUSIVE_WRITE, _pTabMng);

    try 
    {
	if ( _pDbPool ) 
	{
	    // object is invalidated for recompilation by each db thread
	    _pDbPool->invalidateObject(tabSetId, _pProc->getName(), CegoObject::PROCEDURE);
	    delete _pProc;
	    _pProc = 0;
	}
	else
	{
	    // in grace mode, we have to recompile procedure, if all objects are available
	    if ( _isGrace == false )
	    {
		_pTabMng->addCompProcedure(tabSetId, _pProc);
	    }
	    else
	    {
		delete _pProc;
	    }
	    _pProc = 0;
	}
	
	Chain msg;
	CegoOutput o;
	
	if ( _pDbHandle )
	    o.setDbHandle(_pDbHandle);
	else if ( _logToFile )
	    o.setDBMng(_pTabMng->getDBMng());

	msg = Chain("Procedure ") + procName + Chain(" created");
	
	o.chainOut(msg);	
    }
    catch ( Exception e )
    {
	if ( _pProc )
	    delete _pProc;
	
	_pTabMng->getDBMng()->unuseObject(tabSetId, procName, CegoObject::PROCEDURE);	
	throw Exception(EXLOC, Chain("Cannot create procedure"), e);
    }

    _pTabMng->getDBMng()->unuseObject(tabSetId, procName, CegoObject::PROCEDURE);
}

void CegoAction::execProcLoad()
{
    CegoOutput o;
    if ( _pDbHandle )
    {
	o.setDbHandle(_pDbHandle);	
	Chain msg = Chain("Procedure loaded (Note : This statement is for internal use only)");
	o.chainOut(msg);
    }
}

void CegoAction::execProcCall()
{
    
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");
    
    Chain procName;
    Chain tableSet;
    
    ListT<CegoExpr*> exprList;
    
    _objNameStack.Pop(procName);
    _objTableSetStack.Pop(tableSet);
    _exprListStack.Pop(exprList);
    
    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
    
    _pTabMng->getDBMng()->useObject(tabSetId, procName, CegoObject::PROCEDURE, CegoDatabaseManager::SHARED, _pTabMng);
    
    ListT<CegoFieldValue> clobRefList;
    
    CegoProcedure* pProc = 0;
    
    try 
    {
	pProc = _pTabMng->getProcedure(tabSetId, procName);

	pProc->setMasterBlock(_pMasterBlock);
	
	ListT<CegoProcVar> argList;
	pProc->getArgList(argList);

	ListT<CegoFieldValue> fvl;
	
	CegoProcVar *pVar = argList.First();
	CegoExpr **pExpr = exprList.First();

	unsigned pos=1;
	while ( pVar && pExpr ) 
	{	    	    
	    if ( pVar->getVarType() == CegoProcVar::OUTVAR )
	    {
		Chain outVar;
		(*pExpr)->checkVar(outVar);
		
		CegoProcVar *pCheckVar = _pMasterBlock->getVarList().Find(CegoProcVar(outVar));
		if ( pCheckVar == 0 )
		{
		    CegoFieldValue nullVal;
		    _pMasterBlock->getVarList().Insert(CegoProcVar(outVar, CegoProcVar::BLOCKVAR, NULL_TYPE, 0, 0, nullVal));
		}

		// we use fv value to store variable name
		fvl.Insert( CegoFieldValue(VARCHAR_TYPE, outVar) );
	    }
	    else // INVAR
	    {
		CegoFieldValue fv = (*pExpr)->evalFieldValue(0, _pMasterBlock);

		if ( fv.getType() == NULL_TYPE )
		{
		    // nothing to to
		}
		else if ( pVar->getType() != fv.getType() )		
		{
		    bool clobCastDone=false;
		    if ( pVar->getType() == CLOB_TYPE )
		    {
			if ( CegoQueryHelper::string2Clob(fv, _pTabMng, tabSetId) )
			{
			    clobRefList.Insert(fv);
			    clobCastDone=true;
			}
		    }
		    if ( clobCastDone == false )
		    {
			if ( fv.castTo(pVar->getType(), pVar->getDim()) == false )
			{
			    throw Exception(EXLOC, Chain("Mismatched datatype <") 
					    + CEGO_TYPE_MAP[(unsigned)fv.getType()] 
					+ Chain("> in value list for argument ") + Chain(pos) 
					    + " ( expected " 
					    + CEGO_TYPE_MAP[(unsigned)pVar->getType()] + " )");
			}
		    }
		}

		fvl.Insert(fv);
	    }

	    pExpr = exprList.Next();
	    pVar = argList.Next();
	    pos++;
	}

	if ( pVar || pExpr )
	{	
	    Chain msg = Chain("Mismatched parameter count for procedure ") + procName;
	    throw Exception(EXLOC, msg);
	}

	CegoOutput o;
	
	if ( _pDbHandle )	    
	    o.setDbHandle(_pDbHandle);    	
	else if ( _logToFile )
	    o.setDBMng(_pTabMng->getDBMng());

	pProc->execute(fvl);
	
	pExpr = exprList.First();
	while ( pExpr )
	{
	    delete *pExpr;
	    pExpr = exprList.Next();
	}
	exprList.Empty();	

	Chain msg;
	msg = Chain("Procedure ") + pProc->getName() + Chain(" executed");
	o.procResultOut(msg, pProc->getOutParamList(), 0);

	pProc->cleanUp();	
	_pTabMng->getDBMng()->unuseObject(tabSetId, procName, CegoObject::PROCEDURE);
    }
    catch ( Exception e)
    {
	if ( pProc )
	    pProc->cleanUp();
	
	CegoFieldValue *pClobRef = clobRefList.First();
	while ( pClobRef )
	{
	    if ( pClobRef->getType() == CLOB_TYPE && pClobRef->getValue() != 0 )
	    {
		PageIdType pageId;
		memcpy(&pageId, pClobRef->getValue(), sizeof(PageIdType));

		_pTabMng->decreaseClobRef(tabSetId, pageId);
	    }
	    pClobRef = clobRefList.Next();
	}
	
	CegoExpr** pExpr = exprList.First();
	while ( pExpr )
	{
	    delete *pExpr;
	    pExpr = exprList.Next();
	}
	exprList.Empty();
	
	_pTabMng->getDBMng()->unuseObject(tabSetId, procName, CegoObject::PROCEDURE);    
	throw Exception(EXLOC, "Cannot execute procedure", e);
    }
}

void CegoAction::execFuncCall()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain functionName;
    Chain tableSet;
    ListT<CegoExpr*> exprList;

    _objNameStack.Pop(functionName);
    _objTableSetStack.Pop(tableSet);
    _exprListStack.Pop(exprList);

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);

    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    pS = getTokenList().Next();
        
    Chain retVar;

    if ( pS )
    {
	retVar = pS->cutTrailing(Chain(":"));
    }
    else
    {
	throw Exception(EXLOC, "No return variable specified");
    }
    
    _pTabMng->getDBMng()->useObject(tabSetId, functionName, CegoObject::PROCEDURE, CegoDatabaseManager::SHARED, _pTabMng);

    ListT<CegoFieldValue> clobRefList;

    CegoProcedure* pProc = 0;
    
    try
    {	
	CegoProcVar *pRetVar = _pMasterBlock->getVarList().Find(CegoProcVar(retVar));
	if ( pRetVar == 0 )
	{
	    CegoFieldValue nullVal;
	    _pMasterBlock->getVarList().Insert(CegoProcVar(retVar, CegoProcVar::BLOCKVAR, NULL_TYPE, 0, 0, nullVal));
	}
	
	pProc = _pTabMng->getProcedure(tabSetId, functionName);

	if ( pProc->getProcType() != CegoProcedure::FUNCTION )
	    throw Exception(EXLOC, "Procedure does not return value");

	pProc->setMasterBlock(_pMasterBlock);
	
	ListT<CegoProcVar> argList;
	pProc->getArgList(argList);

	ListT<CegoFieldValue> fvl;
		
	CegoProcVar *pVar = argList.First();
	CegoExpr **pExpr = exprList.First();
	unsigned pos=1;
	while ( pVar && pExpr ) 
	{	    
	    if ( pVar->getVarType() == CegoProcVar::OUTVAR )
	    {
		Chain outVar;
		(*pExpr)->checkVar(outVar);
		
		CegoProcVar *pCheckVar = _pMasterBlock->getVarList().Find(CegoProcVar(outVar));
		if ( pCheckVar == 0 )
		{
		    CegoFieldValue nullVal;
		    _pMasterBlock->getVarList().Insert(CegoProcVar(outVar, CegoProcVar::BLOCKVAR, NULL_TYPE, 0, 0, nullVal));
		}

		// we use fv value to store variable name
		fvl.Insert( CegoFieldValue(VARCHAR_TYPE, outVar) );
	    }
	    else // INVAR
	    {
		CegoFieldValue fv = (*pExpr)->evalFieldValue(0, _pMasterBlock);

		if ( fv.getType() == NULL_TYPE )
		{
		    // nothing to to
		}
		else if ( pVar->getType() != fv.getType() )		
		{
		    bool clobCastDone=false;
		    if ( pVar->getType() == CLOB_TYPE )
		    {
			if ( CegoQueryHelper::string2Clob(fv, _pTabMng, tabSetId) )
			{
			    clobRefList.Insert(fv);
			    clobCastDone=true;
			}
		    }
		    if ( clobCastDone == false )
		    {
			if ( fv.castTo(pVar->getType(), pVar->getDim()) == false )
			{
			    throw Exception(EXLOC, Chain("Mismatched datatype <") 
					    + CEGO_TYPE_MAP[(unsigned)fv.getType()] 
					+ Chain("> in value list for argument ") + Chain(pos) 
					    + " ( expected " 
					    + CEGO_TYPE_MAP[(unsigned)pVar->getType()] + " )");
			}
		    }
		}

		fvl.Insert(fv);
	    }
	    
	    pExpr = exprList.Next();
	    pVar = argList.Next();
	    pos++;
	}

	if ( pVar || pExpr )
	{	
	    Chain msg = Chain("Mismatched parameter count for function ") + functionName;
	    throw Exception(EXLOC, msg);
	}

	CegoOutput o;
	
	if ( _pDbHandle )	
	    o.setDbHandle(_pDbHandle);	
	else if ( _logToFile )
	    o.setDBMng(_pTabMng->getDBMng());	

	pProc->execute(fvl);

	CegoFieldValue retVal = pProc->getRetVal();
	
	_pMasterBlock->setValue(retVar, pProc->getRetVal());

	Chain msg;
	msg = Chain("Function ") + pProc->getName() + Chain(" executed");
	
	o.procResultOut(msg, pProc->getOutParamList(), &retVal);
	
	pExpr = exprList.First();
	while ( pExpr )
	{
	    delete *pExpr;
	    pExpr = exprList.Next();
	}
	exprList.Empty();

	pProc->cleanUp();

	_pTabMng->getDBMng()->unuseObject(tabSetId, functionName, CegoObject::PROCEDURE);	
    }
    catch ( Exception e)
    {	

	if ( pProc )
	    pProc->cleanUp();
	
	CegoFieldValue *pClobRef = clobRefList.First();
	while ( pClobRef )
	{
	    if ( pClobRef->getType() == CLOB_TYPE && pClobRef->getValue() != 0 )
	    {
		PageIdType pageId;
		memcpy(&pageId, pClobRef->getValue(), sizeof(PageIdType));

		_pTabMng->decreaseClobRef(tabSetId, pageId);
	    }
	    pClobRef = clobRefList.Next();
	}
	
	CegoExpr** pExpr = exprList.First();
	while ( pExpr )
	{
	    delete *pExpr;
	    pExpr = exprList.Next();
	}
	exprList.Empty();	
	_pTabMng->getDBMng()->unuseObject(tabSetId, functionName, CegoObject::PROCEDURE);
	Chain funcError;
	e.pop(funcError);
	Chain msg = Chain("Cannot execute function ") + functionName + Chain(": ") + funcError;
	throw Exception(EXLOC, msg);
    }	
}

void CegoAction::execUserTableCreate() 
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    
    _pTabMng->createQueryTable(tableSet, tableName, _fieldList, _idxList);
    
    Chain msg;
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    msg = Chain("Table ") + tableName + Chain(" created");
    
    o.chainOut(msg);   
}

void CegoAction::execPrimaryIndexCreate() 
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");
    
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
    
    Chain indexName;

    CegoObject::ObjectType idxType;
    
    if ( _isBTree )
    {
	indexName = tableName + Chain(TABMNG_PBTREE_SUFFIX);
	idxType = CegoObject::PBTREE;

	Chain checkIndex = tableName + Chain(TABMNG_PIDX_SUFFIX);
	if ( _pTabMng->objectExists(tabSetId, checkIndex, CegoObject::PAVLTREE) )
	{
	    throw Exception(EXLOC, Chain("Primary index already exists")); 
	}
    }
    else
    {
	indexName = tableName + Chain(TABMNG_PIDX_SUFFIX);
	idxType = CegoObject::PAVLTREE;

	Chain checkIndex = tableName + Chain(TABMNG_PBTREE_SUFFIX);
	if ( _pTabMng->objectExists(tabSetId, checkIndex, CegoObject::PBTREE) )
	{
	    throw Exception(EXLOC, Chain("Primary btree already exists")); 
	}
    }
    
    ListT<CegoField> fieldList;
    _fieldListStack.Pop(fieldList);
    _pTabMng->createQueryIndex(tableSet, indexName, tableName, fieldList, idxType, _isCached);
    
    Chain msg;
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    if ( idxType == CegoObject::PAVLTREE )
	msg = Chain("Primary index ") + indexName+ Chain(" created");
    else
	msg = Chain("Primary btree ") + indexName+ Chain(" created");
    
    o.chainOut(msg);
}

void CegoAction::execIndexCreate() 
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain indexName;
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    
    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    
    if (pS)
    {
	indexName = *pS;
    }
    else
    {
	throw Exception(EXLOC, Chain("Cannot get token value"));
    }
    
    CegoObject::ObjectType idxType;

    if ( _isBTree )
    {
	if ( _isUnique )
	    idxType = CegoObject::UBTREE;
	else
	    idxType = CegoObject::BTREE;
    }
    else
    {
	if ( _isUnique )
	    idxType = CegoObject::UAVLTREE;
	else
	    idxType = CegoObject::AVLTREE;
    }

    ListT<CegoField> fieldList;
    _fieldListStack.Pop(fieldList);
    _pTabMng->createQueryIndex(tableSet, indexName, tableName, fieldList, idxType, _isCached);
       
    Chain msg;
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    if ( _isBTree )
    {    
	msg = Chain("Btree ") + indexName + Chain(" created");
    }
    else
    {
	msg = Chain("Index ") + indexName + Chain(" created");
    }

    o.chainOut(msg);
}

void CegoAction::execTableDrop()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
	
    bool doDrop=true;
    
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->objectExists(tabSetId, tableName, CegoObject::TABLE) == false )
	    doDrop=false;
    }
    
    Chain msg;
    
    if ( doDrop )
    {
	_pTabMng->dropQueryObject(tableName, tableSet, CegoObject::TABLE);
	msg = Chain("Table ") + tableName + Chain(" dropped");
    }
    else
    {
	msg = Chain("Table ") + tableName + Chain(" does not exist");
    }
    
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    o.chainOut(msg);    
}

void CegoAction::execTableTruncate()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);

    _pTabMng->truncateQueryTable(tableName, tableSet);
    Chain msg = Chain("Table ") + tableName + Chain(" truncated");
        
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    o.chainOut(msg);       
}

void CegoAction::execIndexDrop()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain indexName;
    Chain tableSet;
    
    _objNameStack.Pop(indexName);
    _objTableSetStack.Pop(tableSet);

    bool doDrop=true;

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
	
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->objectExists(tabSetId, indexName, CegoObject::AVLTREE) == false )
	{
	    doDrop=false;
	}
    }
    
    Chain msg;
    
    if ( doDrop )
    {    
	_pTabMng->dropQueryObject(indexName, tableSet, CegoObject::AVLTREE);
	msg = Chain("Index ") + indexName + Chain(" dropped");
    }
    else
    {
	msg = Chain("Index ") + indexName + Chain(" does not exist");
    }
    
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    o.chainOut(msg);    
}

void CegoAction::execProcDrop()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain procName;
    Chain tableSet;
    
    _objNameStack.Pop(procName);
    _objTableSetStack.Pop(tableSet);

    bool doDrop=true;

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
	
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->objectExists(tabSetId, procName, CegoObject::PROCEDURE) == false )
	    doDrop=false;
    }

    Chain msg;
    
    if ( doDrop )
    {
	unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
	
	_pTabMng->dropQueryObject(procName, tableSet, CegoObject::PROCEDURE);

	if ( _pDbPool )
	{
	    _pDbPool->invalidateObject(tabSetId, procName, CegoObject::PROCEDURE);
	}
	else
	{
	    _pTabMng->removeCompProcedure(tabSetId, procName);
	}
	msg = Chain("Procedure ") + procName + Chain(" dropped");
		
	// invalidate query cache
	// this is done now in CegoDistManager ( same for views ) 
	// _pTabMng->getDBMng()->cleanCache( tabSetId, CegoObject::PROCEDURE, procName);	
    }
    else
    {
	msg = Chain("Procedure ") + procName + Chain(" does not exist");
    }

    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    o.chainOut(msg);
}

void CegoAction::execFKeyDrop()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain keyName;
    Chain tableSet;
    
    _objNameStack.Pop(keyName);
    _objTableSetStack.Pop(tableSet);

    bool doDrop=true;

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
	
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->objectExists(tabSetId, keyName, CegoObject::FKEY) == false )
	    doDrop=false;
    }

    Chain msg;

    if ( doDrop )
    {
	_pTabMng->dropQueryObject(keyName, tableSet, CegoObject::FKEY);
	msg = Chain("Foreign key ") + keyName + Chain(" dropped");
    }
    else
    {
	msg = Chain("Foreign key ") + keyName + Chain(" not exists");
    }
    
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    o.chainOut(msg);    
}

void CegoAction::execCheckDrop()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain checkName;
    Chain tableSet;
    
    _objNameStack.Pop(checkName);
    _objTableSetStack.Pop(tableSet);

    bool doDrop=true;

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
	
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->objectExists(tabSetId, checkName, CegoObject::CHECK) == false )
	    doDrop=false;
    }
    
    Chain msg;

    if ( doDrop )
    {    
	_pTabMng->dropQueryObject(checkName, tableSet, CegoObject::CHECK);
	msg = Chain("Check ") + checkName + Chain(" dropped");
    }
    else
    {
	msg = Chain("Check ") + checkName + Chain(" does not exist");
    }

    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    o.chainOut(msg);
}

void CegoAction::execAliasDrop()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain aliasName;
    Chain tableSet;
    
    _objNameStack.Pop(aliasName);
    _objTableSetStack.Pop(tableSet);

    bool doDrop=true;

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
    
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->objectExists(tabSetId, aliasName, CegoObject::ALIAS) == false )
	    doDrop=false;
    }
    
    Chain msg;

    if ( doDrop )
    {    
	_pTabMng->dropQueryObject(aliasName, tableSet, CegoObject::ALIAS);
	msg = Chain("Alias ") + aliasName + Chain(" dropped");
    }
    else
    {
	msg = Chain("Alias ") + aliasName + Chain(" does not exist");
    }

    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    o.chainOut(msg);    
}

void CegoAction::execBTreeDrop()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain btreeName;
    Chain tableSet;
    
    _objNameStack.Pop(btreeName);
    _objTableSetStack.Pop(tableSet);

    bool doDrop=true;

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
	
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->objectExists(tabSetId, btreeName, CegoObject::BTREE) == false )
	    doDrop=false;
    }
    
    Chain msg;

    if ( doDrop )
    {    
	_pTabMng->dropQueryObject(btreeName, tableSet, CegoObject::BTREE);
	msg = Chain("Btree ") + btreeName + Chain(" dropped");
    }
    else
    {
	msg = Chain("Btree ") + btreeName + Chain(" does not exist");
    }

    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    o.chainOut(msg);    
}

void CegoAction::dropOpt1()
{
    _ifExistsOpt=false;
}

void CegoAction::dropOpt2()
{
    _ifExistsOpt=true;
}

void CegoAction::execForeignKeyCreate() 
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain refTable, fkey;
    
    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    
    if (pS)
    {
	refTable = *pS;
    }
    else
    {
	throw Exception(EXLOC, Chain("Cannot get token value"));
    }
    
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    
    if (pS)
    {
	fkey = *pS;
    }
    else
    {
	throw Exception(EXLOC, Chain("Cannot get token value"));
    }
    
    ListT<CegoField> keyList;
    ListT<CegoField> refList;
    
    _fieldListStack.Pop(refList);
    _fieldListStack.Pop(keyList);
    
    // cout << "Creating foreign key (" << _tableSet << "," << fkey << "," << tableName << "," << refTable << ")" << endl; 
    
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    
    _pTabMng->createQueryForeignKey(tableSet, fkey, tableName, keyList, refTable, refList);
       
    Chain msg;
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    msg = Chain("Foreign Key ") + fkey + Chain(" created");
    
    o.chainOut(msg);
}

void CegoAction::execCheckCreate() 
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    CegoCondition *pCondDesc = 0;
    CegoPredicate *pPredDesc = 0;

    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    Chain checkName = *pS;

    _condDescStack.Pop(pCondDesc);

    if ( pCondDesc->getCondType() == CegoCondition::PRED  )
    {
	pPredDesc = pCondDesc->Left();
	pCondDesc->setLeft(0);
	delete pCondDesc;
    }
    else
    {
	pPredDesc = new CegoPredicate(pCondDesc);
    }
   
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);

    ListT<CegoSelect*> queryList;
    pPredDesc->getSelectQueryList(queryList);
    if ( queryList.Size() > 0 )
	throw Exception(EXLOC, "Sub select in check condition not supported");
    
    _pTabMng->createQueryCheck(tableSet, checkName, tableName, pPredDesc);
    
    Chain msg;
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    msg = Chain("Check ") + checkName + Chain(" created");
    
    o.chainOut(msg);    
}

void CegoAction::execAliasCreate() 
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    pS = getTokenList().Next();

    Chain aliasName;
    
    if (pS)
    {
	aliasName = *pS;
    }
    else
    {
	throw Exception(EXLOC, Chain("Cannot get token value"));
    }

    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);

    // cout << "Creating alias " << aliasName << " on table " << tableName << " with attrnum " << _aliasList.Size() << endl;
    
    _pTabMng->createQueryAlias(tableSet, aliasName, tableName, _aliasList);
    
    _aliasList.Empty();
    
    Chain msg;
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    msg = Chain("Alias ") + aliasName + Chain(" created");
    
    o.chainOut(msg);    
}

void CegoAction::execAssignStatement()
{
    Chain *pS;
    pS = getTokenList().First();
    pS = getTokenList().Next();
    
    if ( pS )
    {       
	CegoExpr *pExpr = 0;
	
	_exprStack.Pop(pExpr);    		

	CegoProcVar *pVar = _pMasterBlock->getVarList().Find(CegoProcVar(*pS));
	if ( pVar )
	{
	    pVar->setValue ( pExpr->evalFieldValue(0, _pMasterBlock) );
	}
	else
	{
	    CegoFieldValue fv = pExpr->evalFieldValue(0, _pMasterBlock);
	    _pMasterBlock->getVarList().Insert(CegoProcVar(*pS, 
							   CegoProcVar::BLOCKVAR, 
							   fv.getType(),
							   fv.getLength(),
							   fv.getDim(),
							   fv));
	}

	Chain msg;
	CegoOutput o;
	
	if ( _pDbHandle )
	    o.setDbHandle(_pDbHandle);
	else if ( _logToFile )
	    o.setDBMng(_pTabMng->getDBMng());	

	msg = Chain("Value assigned");
	
	o.chainOut(msg);	
    }
    else
    {
	throw Exception(EXLOC, Chain("Cannot get token value"));
    }
}

void CegoAction::execPrint()
{
    CegoExpr *pExpr = 0;
    
    _exprStack.Pop(pExpr);    

    CegoFieldValue fv = pExpr->evalFieldValue(0, _pMasterBlock);

    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    o.chainOut(fv.valAsChain());
}

void CegoAction::execIndexCheck()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    Chain* pS = getTokenList().First();
    if ( pS )
    {	
	Chain idxName = *pS;
	
	CegoObject::ObjectType type;

	unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
		
	if ( _pTabMng->objectExists(tabSetId, idxName, CegoObject::AVLTREE))
	{
	    type = CegoObject::AVLTREE;
	}
	else
	{
	    throw Exception(EXLOC, Chain("Index ") + idxName + Chain(" does not exist"));	    
	}
	
	CegoOutput o;
	if ( _pDbHandle )
	    o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
	else if ( _logToFile )
	    o.setDBMng(_pTabMng->getDBMng());	

	CegoAVLIndexManager idxMng(_pTabMng);
	
	char h = idxMng.checkIndex(tabSetId, idxName, type);

	if ( h >= 0 )
	{
	    o.chainOut( Chain("Index ok ( Height = ") + Chain((unsigned)h) + Chain(" )"));
	}
	else
	{
	    o.chainOut(Chain("Index corrupted"));		
	}
    }
}

void CegoAction::execCreateCounter()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
    
    CegoLogRecord lr;
    lr.setLSN(_pTabMng->getDBMng()->nextLSN(tabSetId));
    
    unsigned long long initValue = 0;
    _pTabMng->getDBMng()->addCounter(tabSetId, _counterName, initValue);
    
    lr.setAction(CegoLogRecord::LOGREC_ADDCOUNTER);
    lr.setData(_counterName);
    lr.setDataLen(_counterName.length() + 1);
    _pTabMng->getDBMng()->logIt(tabSetId, lr, _pTabMng->getLockHandle());
    
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    Chain msg = Chain("Counter ") + _counterName + Chain(" created");
    o.chainOut(msg);
}

void CegoAction::execDropCounter()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    bool doDrop=true;
    
    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
    
    if ( _ifExistsOpt )
    {	
	ListT<Chain> counterNameList;
	_pTabMng->getDBMng()->getCounterList(tabSetId, counterNameList);    
	
	if ( counterNameList.Find(_counterName) == 0 )
	    doDrop=false;		
    }
    
    Chain msg;
    
    if ( doDrop )
    {
	CegoLogRecord lr;
	lr.setLSN(_pTabMng->getDBMng()->nextLSN(tabSetId));

	_pTabMng->getDBMng()->removeCounter(tabSetId, _counterName);
	
	lr.setAction(CegoLogRecord::LOGREC_DELCOUNTER);
	lr.setData(_counterName);
	lr.setDataLen(_counterName.length() + 1);

	_pTabMng->getDBMng()->logIt(tabSetId, lr, _pTabMng->getLockHandle());
	
	msg = Chain("Counter ") + _counterName + Chain(" dropped");
    }
    else	    
    {
	msg = Chain("Counter ") + _counterName + Chain(" does not exist");
    }
    
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    o.chainOut(msg);
}

void CegoAction::execSetCounter()
{
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
    
    CegoExpr *pExpr = 0;
    
    _exprStack.Pop(pExpr);    
    CegoFieldValue fv = pExpr->evalFieldValue(0, _pMasterBlock);
    
    if ( fv.getType() != LONG_TYPE )
    {
	if ( fv.castTo(LONG_TYPE) == false )
	    throw Exception(EXLOC, Chain("Invalid value for counter"));
    }

    long long *pVal = (long long*)fv.getValue();

    if ( pVal != 0 )
	_pTabMng->getDBMng()->setCounterValue(tabSetId, _counterName, *pVal);    
    else
	_pTabMng->getDBMng()->setCounterValue(tabSetId, _counterName, 0l);
    
    Chain msg = Chain("Counter ") + _counterName + Chain(" set");
    
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT, NETMNG_MAXBYTECOUNT);
    else if ( _logToFile )
	o.setDBMng(_pTabMng->getDBMng());	

    o.chainOut(msg);    
}

void CegoAction::setCounterId()
{
    Chain *pS;
    pS = getTokenList().First();
    if ( pS )
    {
	_counterName = *pS;
    }
}

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////// trigger semantic actions ////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

void CegoAction::triggerHead()
{
    _pBlock = new CegoProcBlock(0);
    _pBlock->setVarList(_procArgList);
    _triggerTable = *(_objNameStack.getTop());    
}

void CegoAction::triggerStore()
{    
    CegoProcBlock *pBlock = 0;
    _blockStack.Pop(pBlock);   

    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);

    Chain triggerName;
    Chain triggerTableSet;
    
    _objNameStack.Pop(triggerName);
    _objTableSetStack.Pop(triggerTableSet);
    
    _pTrigger = new CegoTrigger(triggerName, _isTriggerBefore, _isTriggerOnInsert, _isTriggerOnUpdate, _isTriggerOnDelete, tableName, pBlock);	

    _isTriggerBefore = false;
    _isTriggerOnInsert = false;
    _isTriggerOnUpdate = false;
    _isTriggerOnDelete = false;
    
    _triggerTableSet = triggerTableSet;
    _triggerTable = Chain();
}

void CegoAction::setTriggerBefore()
{
    _isTriggerBefore = true;
}

void CegoAction::setTriggerAfter()
{
    _isTriggerBefore = false;
}

void CegoAction::addInsertTrigger()
{
    _isTriggerOnInsert = true;
}

void CegoAction::addUpdateTrigger()
{
    _isTriggerOnUpdate = true;
}

void CegoAction::addDeleteTrigger()
{
    _isTriggerOnDelete = true;
}

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////// proc semantic actions  //////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

void CegoAction::procHead()
{
    Chain *pS;
    pS = getTokenList().First();
    pS = getTokenList().Next();
    pS = getTokenList().Next();

    if ( pS )
    {
	_pBlock = new CegoProcBlock(0);
	_pBlock->setVarList(_procArgList);
    }
}

void CegoAction::procStore()
{
    CegoProcBlock *pBlock = 0;
    _blockStack.Pop(pBlock);   
    
    Chain procName;
    Chain tableSet;
    
    _objNameStack.Pop(procName);
    _objTableSetStack.Pop(tableSet);
    
    if ( _procType == CegoProcedure::PROCEDURE )
    {
	_pProc = new CegoProcedure(procName, pBlock);	
    }
    else
    {
	_pProc = new CegoProcedure(procName, pBlock, _returnType, _returnTypeLen, _returnTypeDim);
    }

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
    _pProc->enableProcCache(_pTabMng->getDBMng()->getProcCacheEnabled(tabSetId));
    
    // set to default
    _procType = CegoProcedure::PROCEDURE;
    _procArgList.Empty();
    _procTableSet = tableSet;
}

void CegoAction::procReturnOpt()
{
    _returnType = _dataType;
    _returnTypeLen = _dataLen;
    _returnTypeDim = _dataDim;
    _procType = CegoProcedure::FUNCTION;
}

void CegoAction::procArg1()
{
    Chain *pS;
    pS = getTokenList().First();
    pS = getTokenList().Next();
   
    if ( pS )
    {
	if ( _procArgList.Find(CegoProcVar(*pS)) )
	{
	    Chain msg = Chain("Procedure parameter " ) + *pS + Chain(" already defined");
	    throw Exception(EXLOC, msg);
	}
	CegoFieldValue fv;
	_procArgList.Insert( CegoProcVar(*pS, CegoProcVar::INVAR, _dataType, _dataLen, _dataDim, fv ));
    } 
}

void CegoAction::procArg2()
{
    Chain *pS;
    pS = getTokenList().First();
    pS = getTokenList().Next();
   
    if ( pS )
    {
	if ( _procArgList.Find(CegoProcVar(*pS)) )
	{
	    Chain msg = Chain("Procedure parameter " ) + *pS + Chain(" already defined");
	    throw Exception(EXLOC, msg);
	}
	CegoFieldValue fv;
	_procArgList.Insert( CegoProcVar(*pS, CegoProcVar::OUTVAR, _dataType, _dataLen, _dataDim, fv ));
    }
}

void CegoAction::procStoreBlock()
{
    _blockStack.Push(_pBlock);
}

void CegoAction::procVarStatement()
{
    Chain *pS;
    pS = getTokenList().First();
    
    if ( pS )
    {	
	CegoFieldValue fv;
	if ( _pBlock->getVarList().Find(CegoProcVar(*pS)) )
	{
	    Chain msg = Chain("Procedure variable " ) + *pS + Chain(" already defined");
	    throw Exception(EXLOC, msg);
	}	    
	_pBlock->getVarList().Insert(CegoProcVar(*pS, CegoProcVar::BLOCKVAR, _dataType, _dataLen, _dataDim, fv));
    }

    if ( _initialAssignment )
    {
	CegoExpr *pExpr = 0;
	_exprStack.Pop(pExpr);	
	_pBlock->addStatement( new CegoProcAssignStmt(*pS, pExpr, _pBlock) );
    }
}

void CegoAction::procCursorCreateStatement()
{
    Chain *pS;
    pS = getTokenList().First();
    pS = getTokenList().Next();

    if ( pS )
    {	
	_pBlock->addStatement( new CegoProcCursorCreateStmt(*pS, _pSelect, _pBlock) );
	_pBlock->addCursor(*pS, _pSelect);
	_pSelect = 0;
    }
}

void CegoAction::procCursorCloseStatement()
{
    Chain *pS;
    pS = getTokenList().First();
    
    if ( pS )
    {	
	CegoProcCursor *pCur = _pBlock->getCursor(*pS);
	_pBlock->addStatement( new CegoProcCursorCloseStmt(pCur, _pBlock) );
    }
}

void CegoAction::procAssignStatement()
{
    Chain *pS;
    pS = getTokenList().First();
    pS = getTokenList().Next();
    
    if ( pS )
    {	
	CegoExpr *pExpr= 0;	
	_exprStack.Pop(pExpr);	
	_pBlock->addStatement( new CegoProcAssignStmt(pS->cutTrailing(Chain(":")), pExpr, _pBlock) );
    }
}

void CegoAction::procAssign2NullStatement()
{
    CegoExpr *pExpr = 0;    
    _exprStack.Pop(pExpr);        
    _pBlock->addStatement( new CegoProcAssignStmt(pExpr, _pBlock) );    
}

void CegoAction::procInitialAssignment1()
{
    _initialAssignment = true;
}

void CegoAction::procInitialAssignment2()
{
    _initialAssignment = false;
}

void CegoAction::procNoopStatement()
{
    _pBlock->addStatement( new CegoProcNoopStmt(_pBlock) );
}

void CegoAction::procThrowStatement()
{
    CegoExpr *pExpr = 0;    
    _exprStack.Pop(pExpr);        
    _pBlock->addStatement( new CegoProcThrowStmt(pExpr, _pBlock) );    
}

void CegoAction::procIfStatement()
{
    _pBlock->addStatement(new CegoProcIfStmt(*_pPredList, *_pIfBlockList, _pBlock));    
    
    delete _pPredList;
    delete _pIfBlockList;

    _predListStack.Pop(_pPredList);
    _ifBlockListStack.Pop(_pIfBlockList);   
}

void CegoAction::procStoreIfBlock()
{
    CegoProcBlock *pIfBlock = 0;
    CegoPredicate *pPred = 0;
    _blockStack.Pop(pIfBlock);
    _predDescStack.Pop(pPred);

    _pPredList->Insert(pPred);
    _pIfBlockList->Insert(pIfBlock);

    _blockStack.Pop(_pBlock);
}

void CegoAction::procStoreElseBlock()
{
    CegoProcBlock *pElseBlock = 0, *parentBlock = 0;
    _blockStack.Pop(pElseBlock);
    _pIfBlockList->Insert(pElseBlock);
    _blockStack.Pop(parentBlock);
    _pBlock = parentBlock;
}

void CegoAction::procElsePart()
{
    CegoProcBlock* pParent = _pBlock;
    _blockStack.Push(_pBlock);
    _pBlock = new CegoProcBlock(pParent);
}

void CegoAction::procIfCondition()
{
    CegoProcBlock* pParent = _pBlock;
    _blockStack.Push(_pBlock);
    _pBlock = new CegoProcBlock(pParent);

    _ifBlockListStack.Push(_pIfBlockList);
    _pIfBlockList = new ListT<CegoProcBlock*>;

    _predListStack.Push(_pPredList);
       
    CegoCondition *pCondDesc = 0;
    _condDescStack.Pop(pCondDesc);
    
    if ( pCondDesc->getCondType() == CegoCondition::PRED )
    {
	_predDescStack.Push(pCondDesc->Left());
	pCondDesc->setLeft(0);
	delete pCondDesc;
    }
    else
    {
	_predDescStack.Push(new CegoPredicate(pCondDesc));
    }

    _pPredList = new ListT<CegoPredicate*>;
}

void CegoAction::procElsIfCondition()
{
    CegoProcBlock* pParent = _pBlock;
    _blockStack.Push(_pBlock);
    _pBlock = new CegoProcBlock(pParent);

    CegoCondition *pCondDesc = 0;
    _condDescStack.Pop(pCondDesc);
    
    if ( pCondDesc->getCondType() == CegoCondition::PRED )
    {
	_predDescStack.Push(pCondDesc->Left());
	pCondDesc->setLeft(0);
	delete pCondDesc;
    }
    else
    {
	_predDescStack.Push(new CegoPredicate(pCondDesc));
    }


}

void CegoAction::procWhileStatement()
{
    CegoProcBlock *pWhileBlock = 0;
    _blockStack.Pop(pWhileBlock);
    _blockStack.Pop(_pBlock);
    
    CegoPredicate *pPredDesc = 0;
    _predDescStack.Pop(pPredDesc);

    _pBlock->addStatement(new CegoProcWhileStmt(_pTabMng, pPredDesc, pWhileBlock, _pBlock));
}

void CegoAction::procWhileCondition()
{
    CegoProcBlock* pParent = _pBlock;
    _blockStack.Push(_pBlock);
    _pBlock = new CegoProcBlock(pParent);

    CegoCondition *pCondDesc = 0;
    _condDescStack.Pop(pCondDesc);

    if ( pCondDesc->getCondType() == CegoCondition::PRED )
    {
	_predDescStack.Push(pCondDesc->Left());
	pCondDesc->setLeft(0);
	delete pCondDesc;
    }
    else
    {
	_predDescStack.Push(new CegoPredicate(pCondDesc));
    }
}

void CegoAction::procExceptionStatement()
{
    CegoProcBlock *pExceptionBlock = 0;
    _blockStack.Pop(pExceptionBlock);
    _blockStack.Pop(_pBlock);
    _pBlock->addException(new CegoProcException(_exception, pExceptionBlock, _pBlock));
}

void CegoAction::procExceptionCondition()
{
    Chain *pS;
    pS = getTokenList().First();
    
    if ( pS )
    {
	if ( *pS == Chain(COREOP_EXCEP_ID) )
	{
	    _exception = COREOP_EXCEP;
	}
	else if ( *pS == Chain(ANY_EXCEP_ID) )
	{
	    _exception = ANY_EXCEP;
	}
	else if ( *pS == Chain(OTHER_EXCEP_ID) )
	{
	    _exception = OTHER_EXCEP;
	}
	else
	{
	    throw Exception(EXLOC, Chain("Invalid exception ") + *pS);   
	}
	    
	CegoProcBlock* pParent = _pBlock;
	_blockStack.Push(_pBlock);
	_pBlock = new CegoProcBlock(pParent);
    }
}


void CegoAction::procExpr1()
{
    CegoExpr *pExpr = 0;
    CegoTerm *pTerm = 0;

    _exprStack.Pop(pExpr);    
    _termStack.Pop(pTerm);

    _exprStack.Push(new CegoExpr(pExpr, pTerm, CegoExpr::ADD));
}

void CegoAction::procExpr2()
{
    CegoExpr *pExpr = 0;
    CegoTerm *pTerm = 0;

    _exprStack.Pop(pExpr);    
    _termStack.Pop(pTerm);
    _exprStack.Push(new CegoExpr(pExpr, pTerm, CegoExpr::SUB));
}

void CegoAction::procExpr3()
{
    CegoTerm *pTerm = 0;
    _termStack.Pop(pTerm);
    _exprStack.Push(new CegoExpr(pTerm));
}

void CegoAction::procExpr4()
{
    CegoExpr *pExpr = 0;
    CegoTerm *pTerm = 0;
    
    _exprStack.Pop(pExpr);    
    _termStack.Pop(pTerm);
    _exprStack.Push(new CegoExpr(pExpr, pTerm, CegoExpr::CONCAT));
}

void CegoAction::procTerm1()
{
    CegoTerm *pTerm = 0;
    CegoFactor *pFactor = 0;
    
    _termStack.Pop(pTerm);
    _factorStack.Pop(pFactor);
    _termStack.Push(new CegoTerm(pTerm, pFactor, CegoTerm::MUL));
}

void CegoAction::procTerm2()
{
    CegoTerm *pTerm = 0;
    CegoFactor *pFactor = 0;
    
    _termStack.Pop(pTerm);
    _factorStack.Pop(pFactor);
    _termStack.Push(new CegoTerm(pTerm, pFactor, CegoTerm::DIV));
}

void CegoAction::procTerm3()
{
    CegoFactor *pFactor = 0;
    _factorStack.Pop(pFactor);
    _termStack.Push(new CegoTerm(pFactor));
}

void CegoAction::procFactor1()
{
    Chain* pS = getTokenList().First();

    if ( pS )
    {
	_factorStack.Push(new CegoFactor(pS->cutTrailing(Chain(":"))));
    }
}

void CegoAction::procFactor2()
{
    _factorStack.Push(new CegoFactor(_fieldValue));   
}

void CegoAction::procFactor3()
{
    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    pS = getTokenList().Next();

    if ( pS )
    {
	CegoProcCursor *pCur = _pBlock->getCursor(*pS);
	_factorStack.Push(new CegoFactor( new CegoProcFetch(pCur, _fetchList)));
    }   
}

void CegoAction::procFactor4()
{
    CegoAttrDesc* pAttrDesc = 0;
    _attrDescStack.Pop(pAttrDesc);
    CegoFactor * pFac = new CegoFactor(pAttrDesc);
    _factorStack.Push(pFac);
}

void CegoAction::procFactor5()
{
    CegoFunction *pFunc = 0;
    _functionStack.Pop(pFunc);
    _factorStack.Push(new CegoFactor(pFunc));   
}

void CegoAction::procFactor6()
{
    CegoCondition* pCondDesc = 0;
    _condDescStack.Pop(pCondDesc);
    _factorStack.Push(new CegoFactor(pCondDesc));   
}

void CegoAction::procFactor7()
{
    _factorStack.Push(new CegoFactor(_pSelect));
    _pSelect = 0;
}

void CegoAction::procFactor8()
{
    CegoCaseCond* pCaseCond = 0;
    _caseCondStack.Pop(pCaseCond);
    _factorStack.Push(new CegoFactor(pCaseCond));
}

void CegoAction::procFactor9()
{
    bool isDistinct = false;
    _distinctStack.Pop(isDistinct);
    
    _factorStack.Push(new CegoFactor(new CegoAggregation(isDistinct)));
    
    _distinctStack.Push(isDistinct);
}

void CegoAction::procFactor10()
{
    CegoExpr* pExpr = 0;
    _exprStack.Pop(pExpr);

    bool isDistinct = false;
    _distinctStack.Pop(isDistinct);

    _factorStack.Push(new CegoFactor(new CegoAggregation( CegoAggregation::SUM, pExpr, isDistinct)));

    _distinctStack.Push(isDistinct);
}

void CegoAction::procFactor11()
{
    CegoExpr* pExpr = 0;
    _exprStack.Pop(pExpr);

    // distinct opt not needed
    _factorStack.Push(new CegoFactor(new CegoAggregation( CegoAggregation::AVG, pExpr)));
}

void CegoAction::procFactor12()
{
    CegoExpr* pExpr = 0;
    _exprStack.Pop(pExpr);

    bool isDistinct = false;
    _distinctStack.Pop(isDistinct);
    
    _factorStack.Push(new CegoFactor(new CegoAggregation( CegoAggregation::COUNT, pExpr, isDistinct)));

    _distinctStack.Push(isDistinct);
}

void CegoAction::procFactor13()
{
    CegoExpr* pExpr = 0;
    _exprStack.Pop(pExpr);

    // distinct opt not needed
    _factorStack.Push(new CegoFactor(new CegoAggregation( CegoAggregation::MIN, pExpr)));
}

void CegoAction::procFactor14()
{
    CegoExpr* pExpr = 0;
    _exprStack.Pop(pExpr);
    
    // distinct opt not needed
    _factorStack.Push(new CegoFactor(new CegoAggregation( CegoAggregation::MAX, pExpr)));
}

void CegoAction::caseClause()
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);

    CegoCaseCond* pCaseCond = 0;
    _caseCondStack.Pop(pCaseCond);
    
    pCaseCond->setElseExpr(pExpr);
    _caseCondStack.Push(pCaseCond);
}

void CegoAction::caseConditionList1()
{
    // nothing to do
}

void CegoAction::caseConditionList2()
{
    // nothing to do
}

void CegoAction::caseCondition()
{
    CegoCondition *pCondDesc = 0;
    CegoPredicate *pPredDesc = 0;
    CegoExpr *pExpr = 0;

    _condDescStack.Pop(pCondDesc);

    if ( pCondDesc->getCondType() == CegoCondition::PRED  )
    {
	pPredDesc = pCondDesc->Left();
	pCondDesc->setLeft(0);
	delete pCondDesc;
    }
    else
    {
	pPredDesc = new CegoPredicate(pCondDesc);
    }

    _exprStack.Pop(pExpr);

    CegoCaseCond* pCaseCond = 0;
    _caseCondStack.Pop(pCaseCond);
    
    pCaseCond->addPred(pPredDesc, pExpr);
    _caseCondStack.Push(pCaseCond);
}

void CegoAction::casePrepare()
{
    CegoCaseCond* pCaseCond = new CegoCaseCond();
    _caseCondStack.Push(pCaseCond);
}

void CegoAction::procStoreFetchArg1()
{    
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	_fetchList.Insert(pS->truncLeft(Chain(":")));
    }
}

void CegoAction::procStoreFetchArg2()
{    
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	_fetchList.Empty();
	_fetchList.Insert(pS->truncLeft(Chain(":")));
    }
}

void CegoAction::procQueryStatement()
{    
    _pBlock->addStatement(new CegoProcQueryStmt(_pQuery, _pBlock));
    // we have to set _pQuery to zero, since the query pointer is now managed by the proc statement
    _pQuery=0;
    _tableSet = _defTableSet;
}

void CegoAction::procReturnStatement1()
{
    if ( _procType != CegoProcedure::PROCEDURE )
    {
	throw Exception(EXLOC, Chain("Function must return value"));   
    }
    _pBlock->addStatement(new CegoProcReturnStmt(_pBlock));
}

void CegoAction::procReturnStatement2()
{
    if ( _procType != CegoProcedure::FUNCTION )
    {
	throw Exception(EXLOC, Chain("Procedure cannot return value"));   
    }

    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);

    _pBlock->addStatement(new CegoProcReturnStmt(pExpr, _pBlock));   
}

void CegoAction::procBlockStart()
{
    CegoProcBlock* pParent = _pBlock;
    _blockStack.Push(_pBlock);
    _pBlock = new CegoProcBlock(pParent);
}

void CegoAction::procBlockStatement()
{
    CegoProcBlock *pStmtBlock = 0;
    _blockStack.Pop(pStmtBlock);
    _blockStack.Pop(_pBlock);

    _pBlock->addStatement(new CegoProcBlockStmt(pStmtBlock, _pBlock));
}

void CegoAction::procValueSpec() 
{
    _exprListStack.Push(_exprList);
    _exprList.Empty();
}    

void CegoAction::procExprValue() 
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);    
    _exprList.Insert(pExpr);    
}    

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////// other semantic actions //////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

void CegoAction::setUniqueIndex()
{
    _isUnique = true;
}

void CegoAction::setCachedOption()
{
    _isCached = true;
}

void CegoAction::setAVLIndex()
{
    _isBTree = false;
}

void CegoAction::setBTreeIndex()
{
    _isBTree = true;
}

void CegoAction::setAliasAttr()
{
    Chain attrName;
    Chain aliasName;
    
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	aliasName = *pS;
    }
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    if ( pS )
    {
	attrName = *pS;
    }

    _aliasList.Insert(CegoAttrAlias(attrName, aliasName));
}

void CegoAction::setPrimaryColumn() 
{
    if ( _defaultValue.castTo(_dataType, _dataDim) == false )
	throw Exception(EXLOC, Chain("Cannot cast from <") 
			+ CEGO_TYPE_MAP[_defaultValue.getType()]
			+ Chain("> to <")
			+ CEGO_TYPE_MAP[_dataType]
			+ Chain(">"));
     
    _fieldList.Insert(CegoField(Chain(), Chain(), _fieldName, _dataType, _dataLen, _dataDim, _defaultValue, _isNullable));
    _idxList.Insert(CegoField(Chain(), Chain(), _fieldName, _dataType, _dataLen, _dataDim));
}

void CegoAction::setOrdinaryColumn() 
{
    if ( _defaultValue.castTo(_dataType, _dataDim) == false )
	throw Exception(EXLOC, Chain("Cannot cast from <") 
			+ CEGO_TYPE_MAP[_defaultValue.getType()]
			+ Chain("> to <")
			+ CEGO_TYPE_MAP[_dataType]
			+ Chain(">"));

    _fieldList.Insert(CegoField(Chain(), Chain(), _fieldName, _dataType, _dataLen, _dataDim, _defaultValue, _isNullable));
}    

void CegoAction::setColumnDesc() 
{
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	_fieldName = *pS;
    }
}

void CegoAction::setNullOpt()
{
    _isNullable = true;
}

void CegoAction::setNotNullOpt()
{
    _isNullable = false;
}

void CegoAction::defaultOpt()
{
    _defaultValue = _fieldValue;
}

void CegoAction::defaultNullOpt()
{
    _defaultValue = CegoFieldValue();
}

void CegoAction::createSimpleAttrList()
{    
    _fieldListStack.Push(_fieldList);
    _fieldList.Empty();
}

void CegoAction::createSimpleAttr()
{
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	if ( _fieldList.Find(CegoField(Chain(), *pS)))
	{
	    Chain msg = Chain("Duplicate attribute " ) + *pS;
	    throw Exception(EXLOC, msg);	    
	}
	     
	_fieldList.Insert(CegoField(Chain(), *pS));
    }    
}

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////// insert semantic actions /////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

void CegoAction::startStore() 
{
    _pQuery = new CegoQuery(_pTabMng, _tableSet, CegoQuery::START);	
}

void CegoAction::commitStore() 
{
    _pQuery = new CegoQuery(_pTabMng, _tableSet, CegoQuery::COMMIT);
}

void CegoAction::rollbackStore() 
{
    _pQuery = new CegoQuery(_pTabMng, _tableSet, CegoQuery::ROLLBACK);
}

void CegoAction::lockStore() 
{
    Chain tableName;
    Chain tableSet;
        
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);

    _pQuery = new CegoQuery(_pTabMng, tableSet, tableName,  true);
}

void CegoAction::unlockStore() 
{
    Chain tableName;
    Chain tableSet;
        
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);

    _pQuery = new CegoQuery(_pTabMng, tableSet, tableName,  false);
}

void CegoAction::insertStore() 
{
    Chain tableName;
    Chain tableSet;
        
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);


    if ( (_isTriggerOnInsert || _isTriggerOnUpdate || _isTriggerOnDelete )
	 && _triggerTable == tableName )
    {
	Chain msg = Chain("Trigger statement cannot contain trigger table " ) + _triggerTable;
	throw Exception(EXLOC, msg);
    }
    
    _pQuery = new CegoQuery(_pTabMng, tableSet, tableName, _fal, _exprListArray);
    
    _fal.Empty();
    _exprListArray.Empty();
}

void CegoAction::insertPrepare() 
{
    // nothing to do
}

void CegoAction::insertBySelectStore() 
{
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);

    _pQuery = new CegoQuery(_pTabMng, tableSet, tableName, _fal, _pSelect);
    _pSelect = 0;
    _fal.Empty();
}

void CegoAction::insertArg() 
{   
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	if ( _fal.Find(CegoField(Chain(), *pS)))
	{
	    Chain msg = Chain("Duplicate attribute " ) + *pS;
	    throw Exception(EXLOC, msg);	    
	}
       	
	CegoField f;
	f.setAttrName(*pS);
	_fal.Insert(f);
    }
}    

void CegoAction::insertValueSpecStore() 
{
    _exprListArray.Insert(_exprList);
    _exprList.Empty();	
}    

void CegoAction::insertExprValue() 
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);
    _exprList.Insert(pExpr);
}    

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////// select semantic actions /////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

void CegoAction::unionAllStore()
{
    _unionStack.Push(_pSelect);
    _pSelect = 0;
}

void CegoAction::selectStore()
{
    ListT<CegoExpr*> exprList;
    _exprListStack.Pop(exprList);
 
    ListT<CegoContentObject*> coList;
    _coListStack.Pop(coList);
 
    ListT<CegoAttrDesc*>* pGroupList = 0;
    _groupClauseStack.Pop(pGroupList);

    CegoPredicate *pHavingPred = 0;
    if ( pGroupList )
	_predDescStack.Pop(pHavingPred);
    
    CegoPredicate *pPredDesc = 0;
    _predDescStack.Pop(pPredDesc);

    ListT<CegoExpr*>* pOrderingList = 0;
    _orderingClauseStack.Pop(pOrderingList);
 
    ListT<CegoOrderNode::Ordering>* pOrderingOptList = 0;
    _orderingOptStack.Pop(pOrderingOptList);
     
    bool isDistinct = false;
    _distinctStack.Pop(isDistinct);
    
    unsigned rowLimit = 0;
    _limitStack.Pop(rowLimit);
    
    _pSelect = new CegoSelect(coList, exprList, pPredDesc, pGroupList, pHavingPred,  pOrderingList, pOrderingOptList, isDistinct, rowLimit, _pTabMng);
    
    if ( _pTabMng )
    {
	unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
	_pSelect->setTabSetId(tabSetId);
    }
    
    CegoSelect *pUnion = 0;
    if ( _unionStack.isEmpty() == false )
    {
	_unionStack.Pop(pUnion);
	_pSelect->setUnionSelect(pUnion);
    }
}

void CegoAction::noFromOption()
{
    // we have to push limit value
    _limitStack.Push( 0 );
    _coListStack.Push(_coList);
}

void CegoAction::selectSelectionStore1() 
{
    // nothing to do
}

void CegoAction::selectSelectionStore2()
{
    // for select * case, we put an empty expression list
    ListT<CegoExpr*> exprList;
    _exprListStack.Push(exprList);

    // in case of select *, we have to provide distinct option false
    _distinctStack.Push(false);
}

void CegoAction::selectItem() 
{
    // nothing to do
}

void CegoAction::selectionList1()
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);

    ListT<CegoExpr*> exprList;
    _exprListStack.Pop(exprList);

    if ( pExpr->getAlias() != Chain() )
    {
	// check unique alias definitions here
	CegoExpr **pCheckExpr = exprList.First();
	while ( pCheckExpr )
	{
	    if ( (*pCheckExpr)->getAlias() == pExpr->getAlias() )
	    {
		Chain msg = Chain("Alias " ) + pExpr->getAlias() + Chain(" not unique");
		throw Exception(EXLOC, msg);
	    }
	    pCheckExpr = exprList.Next();
	}
    }
    exprList.Insert(pExpr);
    _exprListStack.Push(exprList);  
}

void CegoAction::selectionList2()
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);
    ListT<CegoExpr*> exprList;
    exprList.Insert(pExpr);
    _exprListStack.Push(exprList);
}

void CegoAction::selectTableListStore() 
{
    _coListStack.Push(_coList);
    _coList.Empty();
}

void CegoAction::selectJoinSpecStore()
{
    _coListStack.Push(_coList);
    _coList.Empty();
}
 
void CegoAction::selectInnerJoinStore1() 
{
    _coListStack.Pop(_coList);

    CegoContentObject **pCO1 = _coList.First();
    CegoContentObject **pCO2 = _coList.Next();
    
    CegoJoinObject *pJCO = new CegoJoinObject(CegoJoinObject::INNER, *pCO1, *pCO2);

    _coList.Empty();
    _coList.Insert(pJCO);
}

void CegoAction::selectInnerJoinStore2() 
{
    _coListStack.Pop(_coList);

    CegoCondition *pCondDesc = 0;
    _condDescStack.Pop(pCondDesc);

    CegoPredicate *pPred = 0;
    if ( pCondDesc->getCondType() == CegoCondition::PRED )
    {
	pPred = pCondDesc->Left();
	pCondDesc->setLeft(0);
	delete pCondDesc;
    }
    else
    {
	pPred = new CegoPredicate(pCondDesc);
    }
    
    CegoContentObject **pCO1 = _coList.First();
    CegoContentObject **pCO2 = _coList.Next();

    if ( pPred )
	pPred->liftCondition();   
    
    CegoJoinObject *pJCO = new CegoJoinObject(CegoJoinObject::INNER, *pCO1, *pCO2, pPred);

    _coList.Empty();
    _coList.Insert(pJCO);    
}

void CegoAction::selectLeftOuterJoinStore1() 
{    
    _coListStack.Pop(_coList);

    CegoContentObject **pCO1 = _coList.First();
    CegoContentObject **pCO2 = _coList.Next();

    CegoJoinObject *pJCO = new CegoJoinObject(CegoJoinObject::LEFTOUTER, *pCO1, *pCO2);

    _coList.Empty();
    _coList.Insert(pJCO);
}

void CegoAction::selectLeftOuterJoinStore2() 
{
    _coListStack.Pop(_coList);

    CegoCondition *pCondDesc = 0;
    _condDescStack.Pop(pCondDesc);

    CegoPredicate *pPred = 0;
    if ( pCondDesc->getCondType() == CegoCondition::PRED )
    {
	pPred = pCondDesc->Left();
	pCondDesc->setLeft(0);
	delete pCondDesc;
    }
    else
    {
	pPred = new CegoPredicate(pCondDesc);
    }
    
    CegoContentObject **pCO1 = _coList.First();
    CegoContentObject **pCO2 = _coList.Next();

    if ( pPred )
	pPred->liftCondition();
    
    CegoJoinObject *pJCO = new CegoJoinObject(CegoJoinObject::LEFTOUTER, *pCO1, *pCO2, pPred);

    // cout << "JoinObject : " << pJCO->toChain() << endl;

    _coList.Empty();
    _coList.Insert(pJCO);
}

void CegoAction::selectRightOuterJoinStore1() 
{
    _coListStack.Pop(_coList);
    
    CegoContentObject **pCO1 = _coList.First();
    CegoContentObject **pCO2 = _coList.Next();

    CegoJoinObject *pJCO = new CegoJoinObject(CegoJoinObject::RIGHTOUTER, *pCO1, *pCO2);

    _coList.Empty();
    _coList.Insert(pJCO);
}

void CegoAction::selectRightOuterJoinStore2() 
{
    _coListStack.Pop(_coList);

    CegoCondition *pCondDesc = 0;
    _condDescStack.Pop(pCondDesc);

    CegoPredicate *pPred = 0;
    if ( pCondDesc->getCondType() == CegoCondition::PRED )
    {
	pPred = pCondDesc->Left();
	pCondDesc->setLeft(0);
	delete pCondDesc;
    }
    else
    {
	pPred = new CegoPredicate(pCondDesc);
    }
    
    CegoContentObject **pCO1 = _coList.First();
    CegoContentObject **pCO2 = _coList.Next();

    if ( pPred )
	pPred->liftCondition();

    CegoJoinObject *pJCO = new CegoJoinObject(CegoJoinObject::RIGHTOUTER, *pCO1, *pCO2, pPred);

    // cout << "JoinObject : " << pJCO->toChain() << endl;

    _coList.Empty();
    _coList.Insert(pJCO);
}

void CegoAction::selectTable1() 
{    
    Chain tableName;
    Chain tableSet;

    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);

    // if no table manager is defined, we habe no chance to analyse given table object
    // in this case, we just store as a view
    if ( _pTabMng == 0 )
    {
	CegoViewObject *pDV = new CegoViewObject(tableName, 0);
	pDV->setTableSet(tableSet);
	_coList.Insert(pDV);
	return;
    }

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
    
    Chain tableAlias = tableName;
    
    CegoContentObject **pCO = _coList.First();
    while ( pCO )
    {
	if ( (Chain)(*pCO)->getTabName() == (Chain)tableName && (Chain)(*pCO)->getName() == (Chain)tableAlias )
	{
	    Chain msg = Chain("Table " ) + tableName + Chain(" not used uniquely");
	    throw Exception(EXLOC, msg);	    
	}
	pCO = _coList.Next();
    }

    if ( tableName[0] == SYSTAB_PREFIX )
    {	  
	Chain sysTable = tableName.truncLeft(Chain(SYSTAB_PREFIX));	    
	
	CegoTableObject *pTO = new CegoTableObject();
	_pTabMng->getQueryObject(tableSet, sysTable, CegoObject::SYSTEM, *pTO);    
	
	pTO->setName(sysTable);		
	_coList.Insert(pTO);
	
    }
    else if ( _pTabMng->objectExists(tabSetId, tableName, CegoObject::VIEW) )
    {
	// if view exists, make sure view is compiled
	
	_pTabMng->getDBMng()->useObject(tabSetId, tableName, CegoObject::VIEW, CegoDatabaseManager::SHARED, _pTabMng);
	try
	{
	    // view is just loaded, no need of view pointer
	    _pTabMng->getView(tabSetId, tableName);
	}
	catch ( Exception e )
	{
	    _pTabMng->getDBMng()->unuseObject(tabSetId, tableName, CegoObject::VIEW);	    
	    throw Exception(EXLOC, Chain("Cannot get view ") + tableName, e);
	}
	_pTabMng->getDBMng()->unuseObject(tabSetId, tableName, CegoObject::VIEW);
	
	CegoViewObject *pVO = new CegoViewObject();
	_pTabMng->getQueryObject(tableSet, tableName, CegoObject::VIEW, *pVO);    

	pVO->setName(tableAlias);
	_coList.Insert(pVO);
    }
    else if ( _pTabMng->objectExists(tabSetId, tableName, CegoObject::ALIAS) )
    {
	CegoAliasObject *pAO = new CegoAliasObject();
	_pTabMng->getQueryObject(tableSet, tableName, CegoObject::ALIAS, *pAO);
	pAO->setName(tableName);
	pAO->setTabAlias(tableAlias);
	
	// get schema for alias object
	CegoTableObject to;
	_pTabMng->getQueryObject(tableSet, pAO->getTabName(), CegoObject::TABLE, to);

	// cout << "Alias Schema size = " << to.getSchema().Size() << endl;
	pAO->setSchema(to.getSchema());

	// modify schema with alias definitons
	pAO->mapSchema();
	
	// cout << "Resulting schema .." << pAO->getSchema().Size() << endl;
	
	_coList.Insert(pAO);
    }
    else if ( _pTabMng->objectExists(tabSetId, tableName, CegoObject::TABLE) )
    {
	CegoTableObject *pTO = new CegoTableObject();
	_pTabMng->getQueryObject(tableSet, tableName, CegoObject::TABLE, *pTO);
	pTO->setName(tableAlias);
	_coList.Insert(pTO);
    }
    else
    {
	if ( _isGrace == false )
	{
	    Chain msg = Chain("Invalid object ") + tableAlias + Chain(" (") + tableName + Chain(")");
	    throw Exception(EXLOC, msg);
	}
	else
	{
	    // create dummy object

	    CegoViewObject *pDV = new CegoViewObject(tableName, tabSetId);
	    pDV->setTableSet(tableSet);
	    _coList.Insert(pDV);	    
	}
    }
}

void CegoAction::selectTable2() 
{    
    Chain tableAlias;
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
   
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	tableAlias = *pS;
    }

    // if no table manager is defined, we habe no chance to analyse given table object
    // in this case, we just store as a view
    if ( _pTabMng == 0 )
    {
	CegoViewObject *pDV = new CegoViewObject(tableAlias, 0);
	pDV->setTableSet(tableSet);
	_coList.Insert(pDV);
	return;
    }

    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
	
    CegoContentObject **pCO = _coList.First();
    while ( pCO )
    {
	if ( (Chain)(*pCO)->getTabName() == (Chain)tableName && (Chain)(*pCO)->getName() == (Chain)tableAlias )
	{
	    Chain msg = Chain("Table " ) + tableName + Chain(" not used uniquely");
	    throw Exception(EXLOC, msg);	    
	}
	pCO = _coList.Next();
    }
	
    if ( tableName[0] == SYSTAB_PREFIX )
    {	  
	Chain sysTable = tableName.truncLeft(Chain(SYSTAB_PREFIX));	
	CegoTableObject *pTO = new CegoTableObject();
	_pTabMng->getQueryObject(tableSet, sysTable, CegoObject::SYSTEM, *pTO);    
	pTO->setTabAlias(tableAlias);
	pTO->setName(tableAlias);				
	_coList.Insert(pTO);       	
    }
    else if ( _pTabMng->objectExists(tabSetId, tableName, CegoObject::VIEW) )
    {
	// if view exists, make sure view is compiled

	_pTabMng->getDBMng()->useObject(tabSetId, tableName, CegoObject::VIEW, CegoDatabaseManager::SHARED, _pTabMng);
	
	try
	{
	    // view is just loaded, no need for view pointer
	    _pTabMng->getView(tabSetId, tableName);
	}
	catch ( Exception e )
	{
	    _pTabMng->getDBMng()->unuseObject(tabSetId, tableName, CegoObject::VIEW);
	    throw Exception(EXLOC, Chain("Cannot get view ") + tableName, e);
	}
	_pTabMng->getDBMng()->unuseObject(tabSetId, tableName, CegoObject::VIEW);
	
	CegoViewObject *pVO = new CegoViewObject();
	_pTabMng->getQueryObject(tableSet, tableName, CegoObject::VIEW, *pVO);    
	pVO->setTabAlias(tableAlias);
	pVO->setName(tableAlias);
	
	_coList.Insert(pVO);
    }
    else if ( _pTabMng->objectExists(tabSetId, tableName, CegoObject::ALIAS) )
    {
	CegoAliasObject *pAO = new CegoAliasObject();
	_pTabMng->getQueryObject(tableSet, tableName, CegoObject::ALIAS, *pAO);
	pAO->setName(tableName);
	pAO->setTabAlias(tableAlias);
	
	// get schema for alias object
	CegoTableObject to;
	_pTabMng->getQueryObject(tableSet, pAO->getTabName(), CegoObject::TABLE, to);
	pAO->setSchema(to.getSchema());

	// modify schema with alias definitons
	pAO->mapSchema();
		
	_coList.Insert(pAO);
    }
    else if ( _pTabMng->objectExists(tabSetId, tableName, CegoObject::TABLE) )
    {
	CegoTableObject *pTO = new CegoTableObject();
	_pTabMng->getQueryObject(tableSet, tableName, CegoObject::TABLE, *pTO);    
	pTO->setName(tableAlias);
	pTO->setTabAlias(tableAlias);
	_coList.Insert(pTO);
    }
    else
    {
	if ( _isGrace == false )
	{
	    Chain msg = Chain("Invalid object ") + tableAlias + Chain(" (") + tableName + Chain(")");
	    throw Exception(EXLOC, msg);	    
	}
	else
	{
	    // create dummy object
	    unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
	    CegoViewObject *pDV = new CegoViewObject(tableAlias, tabSetId);
	    pDV->setTableSet(tableSet);
	    _coList.Insert(pDV);
	}
    }
}

void CegoAction::selectStackJoinTable() 
{
    _coListStack.Push(_coList);
    _coList.Empty();
}

void CegoAction::aliasOpt()
{    
    Chain* pS = getTokenList().First();
    if ( pS )
    {	
	CegoExpr *pExpr = 0;
	_exprStack.Pop(pExpr);
	pExpr->setAlias(*pS);
	_exprStack.Push(pExpr);
    }    
}

void CegoAction::noAliasOpt()
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);
    
    CegoAttrDesc* pAttrDesc = pExpr->checkAttr();
    if ( pAttrDesc )
    {
	if ( pAttrDesc->getAttrName() != Chain(SELECTION_WILDCARD))
	{
	    pExpr->setAlias(pAttrDesc->getAttrName());
	}
	else
	{
	    // no alias needed 
	}
    }

    _exprStack.Push(pExpr);   
}

void CegoAction::selectGroupClause()
{
    _groupClauseStack.Push(_pGroupList);
    _pGroupList = 0;
}

void CegoAction::selectEmptyGroupClause() 
{
    _pGroupList = 0;
    _groupClauseStack.Push(_pGroupList);
}

void CegoAction::selectGroupList1()
{
    CegoAttrDesc* pAttrDesc = 0;
    _attrDescStack.Pop(pAttrDesc);
    _pGroupList->Insert(pAttrDesc);
}

void CegoAction::selectGroupList2()
{
    _pGroupList = new ListT<CegoAttrDesc*>;
    CegoAttrDesc* pAttrDesc = 0;
    _attrDescStack.Pop(pAttrDesc);
    _pGroupList->Insert(pAttrDesc);
}

void CegoAction::selectHavingClause()
{
    CegoCondition *pCondDesc = 0;
    _condDescStack.Pop(pCondDesc);

    if ( pCondDesc->getCondType() == CegoCondition::PRED )
    {
	_predDescStack.Push(pCondDesc->Left());
	pCondDesc->setLeft(0);
	delete pCondDesc;
    }
    else
    {
	_predDescStack.Push(new CegoPredicate(pCondDesc));
    }
}

void CegoAction::selectEmptyHavingClause()
{
    _predDescStack.Push(0);
}

void CegoAction::selectOrderingClause()
{
    _orderingClauseStack.Push(_pOrderingList);
    _orderingOptStack.Push(_pOrderingOptList);
    _pOrderingList = 0;
    _pOrderingOptList = 0;
}

void CegoAction::selectEmptyOrderingClause()
{    
    _pOrderingList = 0;
    _pOrderingOptList = 0;
    _orderingClauseStack.Push(_pOrderingList);
    _orderingOptStack.Push(_pOrderingOptList);
}

void CegoAction::selectOrderingList1()
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);
    _pOrderingList->Insert(pExpr);
    _pOrderingOptList->Insert(_orderingOpt);
}

void CegoAction::selectOrderingList2()
{
    _pOrderingList = new ListT<CegoExpr*>;
    _pOrderingOptList = new ListT<CegoOrderNode::Ordering>;

    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);
    _pOrderingList->Insert(pExpr);
    _pOrderingOptList->Insert(_orderingOpt);
}

void CegoAction::selectOrderingAsc()
{
    _orderingOpt = CegoOrderNode::ASC;
}

void CegoAction::selectOrderingDesc()
{
    _orderingOpt = CegoOrderNode::DESC;
}

void CegoAction::selectDistinctOpt()
{
    _distinctStack.Push(true);
}

void CegoAction::selectNoDistinctOpt()
{
    _distinctStack.Push(false);
}

void CegoAction::selectLimitOpt1()
{
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	_limitStack.Push( pS->asUnsigned() );
    }
}

void CegoAction::selectLimitOpt2()
{
    _limitStack.Push( 0 );
}

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////// update semantic actions /////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

void CegoAction::updateStore() 
{
    CegoPredicate *pPredDesc = 0;
    _predDescStack.Pop(pPredDesc);
    
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);

    if ( (_isTriggerOnInsert || _isTriggerOnUpdate || _isTriggerOnDelete )
	 && _triggerTable == tableName )
    {
	Chain msg = Chain("Trigger statement cannot contain trigger table " ) + _triggerTable;
	throw Exception(EXLOC, msg);
    }

    if ( _updDelAlias == Chain() )
	_updDelAlias = tableName;
    
    _pQuery = new CegoQuery(_pTabMng, tableSet, tableName, _updDelAlias, pPredDesc, _fal, _exprList, _returnVarList, _returnOnFirst);   

    _updDelAlias = Chain();
    _fal.Empty();
    _exprList.Empty();
    _returnVarList.Empty();
}

void CegoAction::updateAssignment() 
{   
    Chain* pS = getTokenList().First();

    pS = getTokenList().Next();
    if ( pS )
    {
	CegoField f (_fieldValue ); 
	f.setAttrName(*pS);
	_fal.Insert(f);
	
	CegoExpr *pExpr = 0;
	_exprStack.Pop(pExpr);
	_exprList.Insert(pExpr);
    } 
}    

void CegoAction::returnOnFirstTrue() 
{
    _returnOnFirst=true;
}    

void CegoAction::returnOnFirstFalse() 
{
    _returnOnFirst=false;
}    

void CegoAction::returnVarAssignment() 
{
    Chain* pS = getTokenList().First();

    pS = getTokenList().Next();
    if ( pS )
    {
	CegoExpr *pExpr = 0;
	_exprStack.Pop(pExpr);
	_returnVarList.Insert ( new CegoReturnVar(pS->cutTrailing(Chain(":")), pExpr ) );
   } 
}    

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////// delete semantic actions /////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

void CegoAction::deleteStore() 
{    
    CegoPredicate *pPredDesc = 0;
    _predDescStack.Pop(pPredDesc);
    
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);

    if ( (_isTriggerOnInsert || _isTriggerOnUpdate || _isTriggerOnDelete )
	 && _triggerTable == tableName )
    {
	Chain msg = Chain("Trigger statement cannot contain trigger table " ) + _triggerTable;
	throw Exception(EXLOC, msg);
    }
    
    if ( _updDelAlias == Chain() )
	_updDelAlias = tableName;

    _pQuery = new CegoQuery(_pTabMng, tableSet, tableName, _updDelAlias,  pPredDesc);   

    _updDelAlias = Chain();    
}

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////// alter semantic actions //////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

void CegoAction::alterStore()
{    
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    
    _pQuery = new CegoQuery(_pTabMng, tableSet, tableName, _alterList);   
    _alterList.Empty();
}

void CegoAction::alterAddCol()
{
    if ( _defaultValue.castTo(_dataType, _dataDim) == false )
	throw Exception(EXLOC, Chain("Cannot cast from <") 
			+ CEGO_TYPE_MAP[_defaultValue.getType()]
			+ Chain("> to <")
			+ CEGO_TYPE_MAP[_dataType]
			+ Chain(">"));
    
    Chain n;
    CegoField f(n, n, _fieldName, _dataType, _dataLen, _dataDim, _defaultValue, _isNullable);
    _alterList.Insert(CegoAlterDesc(CegoAlterDesc::ADD, f));		      
}

void CegoAction::alterDropCol()
{
    Chain* pS = getTokenList().First(); // Values token

    if ( pS )
    {    
	_alterList.Insert(CegoAlterDesc(CegoAlterDesc::DROP, *pS));
    }		      
}

void CegoAction::alterModCol()
{
    if ( _defaultValue.castTo(_dataType, _dataDim) == false )
	throw Exception(EXLOC, Chain("Cannot cast from <") 
			+ CEGO_TYPE_MAP[_defaultValue.getType()]
			+ Chain("> to <")
			+ CEGO_TYPE_MAP[_dataType]
			+ Chain(">"));

    Chain n;
    CegoField f(n, n, _fieldName, _dataType, _dataLen, _dataDim, _defaultValue, _isNullable);
    _alterList.Insert(CegoAlterDesc(CegoAlterDesc::MODIFY_COLUMN, f));
}

void CegoAction::alterModDefault()
{
    Chain* pS = getTokenList().First(); // Values token
    pS = getTokenList().Next();

    if ( pS )
    {	
	Chain colName = *pS;

	// since we still have no type information, we have to type cast later on
	_alterList.Insert(CegoAlterDesc(colName, _fieldValue));
    }
}

void CegoAction::alterRenameCol()
{   
    Chain* pS = getTokenList().First(); // Values token

    Chain oldCol;    
    Chain newCol;

    if ( pS )
    {   
	newCol = *pS;
	pS = getTokenList().Next();
	pS = getTokenList().Next();
	oldCol = *pS;
	
	_alterList.Insert(CegoAlterDesc(oldCol, newCol));
    }    
}

void CegoAction::renameTable()
{
    Chain newTableName;

    Chain* pS = getTokenList().First(); // Values token
    if ( pS )
    {
	newTableName = *pS;
    }
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    
    _pQuery = new CegoQuery(_pTabMng, tableSet, tableName, CegoObject::TABLE, newTableName);
}

void CegoAction::renameIndex()
{
    Chain newIdxName;

    Chain* pS = getTokenList().First(); // Values token
    if ( pS )
    {
	newIdxName = *pS;
    }
    
    Chain idxName;
    Chain tableSet;
    
    _objNameStack.Pop(idxName);
    _objTableSetStack.Pop(tableSet);
    
    _pQuery = new CegoQuery(_pTabMng, tableSet, idxName, CegoObject::AVLTREE, newIdxName);
}

void CegoAction::renameBTree()
{
    Chain newBTreeName;

    Chain* pS = getTokenList().First(); // Values token
    if ( pS )
    {
	newBTreeName = *pS;
    }
        
    Chain btreeName;
    Chain tableSet;
    
    _objNameStack.Pop(btreeName);
    _objTableSetStack.Pop(tableSet);
    
    _pQuery = new CegoQuery(_pTabMng, tableSet, btreeName, CegoObject::BTREE, newBTreeName);
}

void CegoAction::renameKey()
{
    Chain newKeyName;

    Chain* pS = getTokenList().First(); // Values token
    if ( pS )
    {
	newKeyName = *pS;
    }
    
    Chain keyName;
    Chain tableSet;
    
    _objNameStack.Pop(keyName);
    _objTableSetStack.Pop(tableSet);
    
    _pQuery = new CegoQuery(_pTabMng, tableSet, keyName, CegoObject::FKEY, newKeyName);
}

void CegoAction::renameProcedure()
{
    Chain newProcName;

    Chain* pS = getTokenList().First(); // Values token
    if ( pS )
    {
	newProcName = *pS;
    }
    
    Chain procName;
    Chain tableSet;
    
    _objNameStack.Pop(procName);
    _objTableSetStack.Pop(tableSet);
    
    _pQuery = new CegoQuery(_pTabMng, tableSet, procName, CegoObject::PROCEDURE, newProcName);
}

void CegoAction::renameView()
{
    Chain newViewName;

    Chain* pS = getTokenList().First(); // Values token
    if ( pS )
    {
	newViewName = *pS;
    }
    
    Chain viewName;
    Chain tableSet;
    
    _objNameStack.Pop(viewName);
    _objTableSetStack.Pop(tableSet);
    
    _pQuery = new CegoQuery(_pTabMng, tableSet, viewName, CegoObject::VIEW, newViewName);
}

void CegoAction::renameCheck()
{
    Chain newCheckName;

    Chain* pS = getTokenList().First(); // Values token
    if ( pS )
    {
	newCheckName = *pS;
    }
    
    Chain checkName;
    Chain tableSet;
    
    _objNameStack.Pop(checkName);
    _objTableSetStack.Pop(tableSet);
    
    _pQuery = new CegoQuery(_pTabMng, tableSet, checkName, CegoObject::CHECK, newCheckName);
}

void CegoAction::renameTrigger()
{
    Chain newTriggerName;

    Chain* pS = getTokenList().First(); // Values token
    if ( pS )
    {
	newTriggerName = *pS;
    }
    
    Chain triggerName;
    Chain tableSet;
    
    _objNameStack.Pop(triggerName);
    _objTableSetStack.Pop(tableSet);
    
    _pQuery = new CegoQuery(_pTabMng, tableSet, triggerName, CegoObject::TRIGGER, newTriggerName);
}

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////// func semantic actions //////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

void CegoAction::functionNative() 
{
    Chain functionName;

    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    pS = getTokenList().Next();

    if ( pS )
    {
	functionName = *pS;
    }

    CegoFunction* pFunc = 0;

    if ( functionName.toLower() == Chain("int2asc") )
    {
	pFunc = new CegoFunction(CegoFunction::INT2ASC);	
    }
    else if ( functionName.toLower() == Chain("asc2int") )
    {
	pFunc = new CegoFunction(CegoFunction::ASC2INT);	
    }
    else if ( functionName.toLower() == Chain("trim") )
    {
	pFunc = new CegoFunction(CegoFunction::TRIM);	
    }
    else if ( functionName.toLower() == Chain("rtrim") )
    {
	pFunc = new CegoFunction(CegoFunction::RTRIM);	
    }
    else if ( functionName.toLower() == Chain("ltrim") )
    {
	pFunc = new CegoFunction(CegoFunction::LTRIM);	
    }
    else if ( functionName.toLower() == Chain("round") )
    {
	pFunc = new CegoFunction(CegoFunction::ROUND);	
    }
    else if ( functionName.toLower() == Chain("scandate") )
    {
	pFunc = new CegoFunction(CegoFunction::SCANDATE);	
    }
    else if ( functionName.toLower() == Chain("date2str") )
    {
	pFunc = new CegoFunction(CegoFunction::DATE2STR);	
    }
    else if ( functionName.toLower() == Chain("date2long") )
    {
	pFunc = new CegoFunction(CegoFunction::DATE2LONG);	
    }
    else if ( functionName.toLower() == Chain("long2date") )
    {
	pFunc = new CegoFunction(CegoFunction::LONG2DATE);	
    }
    else if ( functionName.toLower() == Chain("newdate") )
    {
	pFunc = new CegoFunction(CegoFunction::NEWDATE);	
    }
    else if ( functionName.toLower() == Chain("lower") )
    {
	pFunc = new CegoFunction(CegoFunction::LOWER);	
    }
    else if ( functionName.toLower() == Chain("upper") )
    {
	pFunc = new CegoFunction(CegoFunction::UPPER);	
    }
    else if ( functionName.toLower() == Chain("left") )
    {
	pFunc = new CegoFunction(CegoFunction::LEFT);	
    }
    else if ( functionName.toLower() == Chain("right") )
    {
	pFunc = new CegoFunction(CegoFunction::RIGHT);	
    }
    else if ( functionName.toLower() == Chain("getpos") )
    {
	pFunc = new CegoFunction(CegoFunction::GETPOS);	
    }
    else if ( functionName.toLower() == Chain("substr") )
    {
	pFunc = new CegoFunction(CegoFunction::SUBSTR);	
    }
    else if ( functionName.toLower() == Chain("replace") )
    {
	pFunc = new CegoFunction(CegoFunction::REPLACE);	
    }
    else if ( functionName.toLower() == Chain("regmatch") )
    {
	unsigned tabSetId = 0;
	if ( _pTabMng )
	    tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
	
	pFunc = new CegoFunction(_pTabMng, tabSetId, CegoFunction::REGMATCH);	
    }
    else if ( functionName.toLower() == Chain("length") )
    {
	pFunc = new CegoFunction(CegoFunction::LENGTH);	
    }
    else if ( functionName.toLower() == Chain("trunc") )
    {
	pFunc = new CegoFunction(CegoFunction::TRUNC);	
    }
    else if ( functionName.toLower() == Chain("str2int") )
    {
	pFunc = new CegoFunction(CegoFunction::STR2INT);	
    }
    else if ( functionName.toLower() == Chain("str2long") )
    {
	pFunc = new CegoFunction(CegoFunction::STR2LONG);	
    }
    else if ( functionName.toLower() == Chain("randstr") )
    {
	pFunc = new CegoFunction(CegoFunction::RANDSTR);	
    }
    else if ( functionName.toLower() == Chain("randint") )
    {
	pFunc = new CegoFunction(CegoFunction::RANDINT);	
    }
    else if ( functionName.toLower() == Chain("mod") )
    {
	pFunc = new CegoFunction(CegoFunction::MOD);	
    }
    else if ( functionName.toLower() == Chain("div") )
    {
	pFunc = new CegoFunction(CegoFunction::DIV);	
    }
    else if ( functionName.toLower() == Chain("lmod") )
    {
	pFunc = new CegoFunction(CegoFunction::LMOD);	
    }
    else if ( functionName.toLower() == Chain("ldiv") )
    {
	pFunc = new CegoFunction(CegoFunction::LDIV);	
    }
    else if ( functionName.toLower() == Chain("power") )
    {
	pFunc = new CegoFunction(CegoFunction::POWER);	
    }
    else if ( functionName.toLower() == Chain("bitand") )
    {
	pFunc = new CegoFunction(CegoFunction::BITAND);	
    }
    else if ( functionName.toLower() == Chain("bitor") )
    {
	pFunc = new CegoFunction(CegoFunction::BITOR);	
    }
    else if ( functionName.toLower() == Chain("bitxor") )
    {
	pFunc = new CegoFunction(CegoFunction::BITXOR);	
    }
    else if ( functionName.toLower() == Chain("blobsize") )
    {
	unsigned tabSetId = 0;
	if ( _pTabMng )
	    tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
	
	pFunc = new CegoFunction(_pTabMng, tabSetId, CegoFunction::BLOBSIZE);	
    }
    else if ( functionName.toLower() == Chain("blobref") )
    {
	unsigned tabSetId = 0;
	if ( _pTabMng )
	    tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
	
	pFunc = new CegoFunction(_pTabMng, tabSetId, CegoFunction::BLOBREF);	
    }

    else if ( functionName.toLower() == Chain("clobsize") )
    {
	unsigned tabSetId = 0;
	if ( _pTabMng )
	    tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
	
	pFunc = new CegoFunction(_pTabMng, tabSetId, CegoFunction::CLOBSIZE);	
    }
    else if ( functionName.toLower() == Chain("clobref") )
    {
	unsigned tabSetId = 0;
	if ( _pTabMng )
	    tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
	
	pFunc = new CegoFunction(_pTabMng, tabSetId, CegoFunction::CLOBREF);	
    }
    else if ( functionName.toLower() == Chain("clob2str") )
    {
	unsigned tabSetId = 0;
	if ( _pTabMng )
	    tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
	
	pFunc = new CegoFunction(_pTabMng, tabSetId, CegoFunction::CLOB2STR);	
    }
    else
    {
	Chain msg = Chain("Unknown function " ) + functionName;
	throw Exception(EXLOC, msg);
    }

    ListT<CegoExpr*> exprList;
    _exprListStack.Pop(exprList);

    pFunc->setExprList(exprList);
    
    _functionStack.Push(pFunc);
}

void CegoAction::functionNextCount() 
{    
    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    if ( pS )
    {
	CegoFunction* pFunc = 0;	

	unsigned tabSetId = 0;
	if ( _pTabMng )
	    tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);    
	pFunc = new CegoFunction(_pTabMng, tabSetId, CegoFunction::NEXTCOUNT);	

	pFunc->setCounterId(*pS);
        _functionStack.Push(pFunc);
    }
}

void CegoAction::functionSetCount() 
{
    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    if ( pS )
    {
	CegoFunction* pFunc = 0;	

	unsigned tabSetId = 0;
	if ( _pTabMng )
	    tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);    
	pFunc = new CegoFunction(_pTabMng, tabSetId, CegoFunction::SETCOUNT);	

        _functionStack.Push(pFunc);
	pFunc->setCounterId(*pS);

	CegoExpr *pExpr = 0;	
	_exprStack.Pop(pExpr);    

	pFunc->setCounterExpr(pExpr);
    }
}

void CegoAction::functionGetCount() 
{
    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    if ( pS )
    {
	CegoFunction* pFunc = 0;	

	unsigned tabSetId = 0;
	if ( _pTabMng )
	    tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);    
	pFunc = new CegoFunction(_pTabMng, tabSetId, CegoFunction::GETCOUNT);	

	pFunc->setCounterId(*pS);
        _functionStack.Push(pFunc);
    }
}

void CegoAction::functionUserDef1()
{
    Chain funcName;
    Chain tableSet;
    
    _objNameStack.Pop(funcName);
    _objTableSetStack.Pop(tableSet);

    unsigned tabSetId = 0;
    if ( _pTabMng )
	tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
    
    ListT<CegoExpr*> exprList;
    _exprListStack.Pop(exprList);
    
    CegoFunction* pFunc = new CegoFunction(_pTabMng, tabSetId,  funcName, exprList);    
    _functionStack.Push(pFunc);   
}

void CegoAction::functionUserDef2()
{
    Chain funcName;
    Chain tableSet;
    
    _objNameStack.Pop(funcName);
    _objTableSetStack.Pop(tableSet);

    unsigned tabSetId = 0;
    if ( _pTabMng )
	tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);

    // exprList stays empty
    ListT<CegoExpr*> exprList;
    
    CegoFunction* pFunc = new CegoFunction(_pTabMng, tabSetId,  funcName, exprList);    
    _functionStack.Push(pFunc);    
}

void CegoAction::storeExprList1()
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);

    ListT<CegoExpr*> exprList;
    _exprListStack.Pop(exprList);
    exprList.Insert(pExpr);
    _exprListStack.Push(exprList);
}

void CegoAction::storeExprList2()
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);
    ListT<CegoExpr*> exprList;
    exprList.Insert(pExpr);
    _exprListStack.Push(exprList);
}

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////// wc semantic actions /////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

void CegoAction::wcWhereClause() 
{
    CegoCondition *pCondDesc = 0;
    _condDescStack.Pop(pCondDesc);

    if ( pCondDesc->getCondType() == CegoCondition::PRED )
    {
	_predDescStack.Push(pCondDesc->Left());
	pCondDesc->setLeft(0);
	delete pCondDesc;
    }
    else
    {
	_predDescStack.Push(new CegoPredicate(pCondDesc));
    }
}

void CegoAction::wcEmptyClause() 
{
    CegoPredicate* pPredDesc = 0;
    _predDescStack.Push(pPredDesc);
}

void CegoAction::conditionAnd() 
{   
    CegoCondition* pAndCondDesc = new CegoCondition(CegoCondition::AND);

    CegoCondition *pCondDesc = 0;
    CegoPredicate *pPredDesc = 0;
    _condDescStack.Pop(pCondDesc);
    _predDescStack.Pop(pPredDesc);

    if ( pCondDesc->getCondType() == CegoCondition::PRED )
    {
	pAndCondDesc->setLeft(pCondDesc->Left());
	pCondDesc->setLeft(0);
	delete pCondDesc;
    }
    else
    {
	pAndCondDesc->setLeft(new CegoPredicate(pCondDesc));
    }
    pAndCondDesc->setRight(pPredDesc);

    _condDescStack.Push(pAndCondDesc);
}

void CegoAction::conditionOr() 
{
    CegoCondition* pOrCondDesc = new CegoCondition(CegoCondition::OR);

    CegoCondition *pCondLeft = 0;
    CegoCondition *pCondRight = 0;
    
    _condDescStack.Pop(pCondLeft);
    _condDescStack.Pop(pCondRight);

    CegoPredicate *pPredLeft = new CegoPredicate(pCondLeft);
    CegoPredicate *pPredRight = new CegoPredicate(pCondRight);
    
    pOrCondDesc->setLeft(pPredLeft);
    pOrCondDesc->setRight(pPredRight);

    _condDescStack.Push(pOrCondDesc);
}

void CegoAction::conditionPredicate() 
{
    CegoCondition* pCondDesc = new CegoCondition(CegoCondition::PRED);

    CegoPredicate *pPredDesc = 0;
    _predDescStack.Pop(pPredDesc);
    pCondDesc->setLeft(pPredDesc);
    pCondDesc->setRight(0);
    _condDescStack.Push(pCondDesc);    
}



void CegoAction::wcPredicateQueryExists() 
{
    CegoPredicate* pP = new CegoPredicate(_pSelect);
    _predDescStack.Push(pP);
    _pSelect = 0;
}

void CegoAction::wcPredicateIn() 
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);

    ListT<CegoExpr*> exprList;
    _exprListStack.Pop(exprList);

    CegoPredicate* pP = new CegoPredicate(pExpr, exprList, false);
    _predDescStack.Push(pP);
}

void CegoAction::wcPredicateNotIn() 
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);

    ListT<CegoExpr*> exprList;
    _exprListStack.Pop(exprList);

    CegoPredicate* pP = new CegoPredicate(pExpr, exprList, true);
    _predDescStack.Push(pP);
}

void CegoAction::wcPredicateQueryIn() 
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);
    	    
    CegoPredicate* pP = new CegoPredicate(pExpr, _pSelect, false);
    _predDescStack.Push(pP);
    _pSelect = 0;
}

void CegoAction::wcPredicateQueryNotIn()  
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);
    	    
    CegoPredicate* pP = new CegoPredicate(pExpr, _pSelect, true);
    _predDescStack.Push(pP);
    _pSelect = 0;
}

void CegoAction::wcPredicateExprComp() 
{
    CegoExpr *pExpr1 = 0;
    _exprStack.Pop(pExpr1);

    CegoExpr *pExpr2 = 0;
    _exprStack.Pop(pExpr2);

    CegoComparison comp;
    _compStack.Pop(comp);
    CegoPredicate* pP = new CegoPredicate(pExpr2, pExpr1, comp);

    _predDescStack.Push(pP);
}

void CegoAction::wcPredicateBetween() 
{
    CegoExpr *pExpr1 = 0;
    _exprStack.Pop(pExpr1);

    CegoExpr *pExpr2 = 0;
    _exprStack.Pop(pExpr2);

    CegoExpr *pExpr3 = 0;
    _exprStack.Pop(pExpr3);

    CegoPredicate* pP = new CegoPredicate(pExpr3, pExpr2, pExpr1);

    _predDescStack.Push(pP);
}

void CegoAction::wcPredicateNullComp() 
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);
    
    CegoPredicate* pP = new CegoPredicate(pExpr, true);

    _predDescStack.Push(pP);
}

void CegoAction::wcPredicateNotNullComp() 
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);
    CegoPredicate* pP = new CegoPredicate(pExpr, false);
    _predDescStack.Push(pP);
}

void CegoAction::wcPredicateLikeComp() 
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);   
    CegoPredicate* pP = new CegoPredicate(pExpr, Chain(_stringBuf), false, true);
    _predDescStack.Push(pP);   
}

void CegoAction::wcPredicateNotLikeComp() 
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);
    CegoPredicate* pP = new CegoPredicate(pExpr, Chain(_stringBuf), true, true);
    _predDescStack.Push(pP);
}

void CegoAction::wcPredicateNcLikeComp() 
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);   
    CegoPredicate* pP = new CegoPredicate(pExpr, Chain(_stringBuf), false, false);
    _predDescStack.Push(pP);   
}

void CegoAction::wcPredicateNotNcLikeComp() 
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);
    CegoPredicate* pP = new CegoPredicate(pExpr, Chain(_stringBuf), true, false);
    _predDescStack.Push(pP);
}


void CegoAction::wcPredicateExprOnly() 
{
    CegoExpr *pExpr = 0;
    _exprStack.Pop(pExpr);
    CegoPredicate* pP = new CegoPredicate(pExpr);
    _predDescStack.Push(pP);
}

void CegoAction::wcPredicateNotPredicate() 
{
    CegoPredicate *pPredDesc = 0;
    _predDescStack.Pop(pPredDesc);
    CegoPredicate* pNotPred = new CegoPredicate(pPredDesc);
    _predDescStack.Push(pNotPred);
}

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////// misc semantic actions //////////////////////////////
/////////////////////////////////////////////////////////////////////////////////

void CegoAction::miscIntType() 
{
    _dataType = INT_TYPE;
    _dataLen = sizeof(int);
    _dataDim = 0;
}

void CegoAction::miscLongType() 
{
    _dataType = LONG_TYPE;
    _dataLen = sizeof(long long);
    _dataDim = 0;
}

void CegoAction::miscStringType() 
{
    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    if ( pS )
    {    
	_dataType = VARCHAR_TYPE;
	_dataLen = pS->asUnsigned();
	if ( _dataLen <= 0 )
	{
	    Chain msg = Chain("Invalid type len for string" );
	    throw Exception(EXLOC, msg);
	}
	_dataDim = 0;
    }
}

void CegoAction::miscDateTimeType() 
{
    _dataType = DATETIME_TYPE;
    _dataLen = CegoTypeConverter::getTypeLen(_dataType);
    _dataDim = 0;
}

void CegoAction::miscBoolType() 
{
    _dataType = BOOL_TYPE;
    _dataLen = sizeof(char);
    _dataDim = 0;
}

void CegoAction::miscBigIntType()
{
    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    if ( pS )
    {    
	_dataType = BIGINT_TYPE;
	_dataLen = pS->asUnsigned();
	if ( _dataLen <= 0 )
	{
	    Chain msg = Chain("Invalid type len for bigint" );
	    throw Exception(EXLOC, msg);
	}
	_dataDim = 0;
    }
}

void CegoAction::miscFloatType()
{
    _dataType = FLOAT_TYPE;
    _dataLen = sizeof(float);
    _dataDim = 0;
}

void CegoAction::miscDoubleType()
{
    _dataType = DOUBLE_TYPE;
    _dataLen = sizeof(double);
    _dataDim = 0;
}

void CegoAction::miscSmallIntType()
{
    _dataType = SMALLINT_TYPE;
    _dataLen = sizeof(short);
    _dataDim = 0;
}

void CegoAction::miscTinyIntType()
{
    _dataType = TINYINT_TYPE;
    _dataLen = sizeof(char);
    _dataDim = 0;
}

void CegoAction::miscDecimalType()
{
    _dataType = DECIMAL_TYPE;
}

void CegoAction::miscBlobType()
{
    _dataType = BLOB_TYPE;
    _dataLen = sizeof(PageIdType);
    _dataDim = 0;
}

void CegoAction::miscClobType()
{
    _dataType = CLOB_TYPE;
    _dataLen = sizeof(PageIdType);
    _dataDim = 0;
}

void CegoAction::miscDecimalDim1()
{
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	_dataLen = RESERVED_BTREE_FLOATLEN;
	_dataDim = pS->asUnsigned();
	if ( _dataDim <= 0 || _dataDim > RESERVED_BTREE_FLOATLEN )
	{
	    Chain msg = Chain("Invalid dimension len for decimal" );
	    throw Exception(EXLOC, msg);
	}
    }
}

void CegoAction::miscDecimalDim2()
{
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	_dataDim = pS->asUnsigned();
    }
    pS = getTokenList().Next();
    pS = getTokenList().Next();
    if ( pS )
    {    
	_dataLen = pS->asUnsigned();
    }

    if ( _dataDim <= 0 || _dataLen <= 0 || _dataDim > _dataLen )
    {
	Chain msg = Chain("Invalid dimension or len for decimal(") + Chain(_dataLen) + Chain(",") + Chain(_dataDim) + Chain(")");
	throw Exception(EXLOC, msg);
    }
}

void CegoAction::miscEqualComp()
{
    _compStack.Push(EQUAL);
}

void CegoAction::miscNotEqualComp()
{
    _compStack.Push(NOT_EQUAL);
}

void CegoAction::miscLessComp()
{
    _compStack.Push(LESS_THAN);
}

void CegoAction::miscMoreComp()
{
    _compStack.Push(MORE_THAN);
}

void CegoAction::miscLessEqualComp()
{
    _compStack.Push(LESS_EQUAL_THAN);
}

void CegoAction::miscMoreEqualComp()
{
    _compStack.Push(MORE_EQUAL_THAN);
}

void CegoAction::miscAttribute1() 
{
    Chain *pS;	
    pS = getTokenList().First();
    
    if (pS)
    {	
	_attrDescStack.Push(new CegoAttrDesc(*pS));
    }
}

void CegoAction::miscAttribute2() 
{        
    Chain *pS;	
    pS = getTokenList().First();
    if (pS)
    {
	Tokenizer  tok(*pS, Chain("."));

	Chain tableName;
	Chain attrName;

	tok.nextToken(tableName);
	tok.nextToken(attrName);

	_attrDescStack.Push(new CegoAttrDesc(tableName, attrName));
    }
}

void CegoAction::miscAttribute3() 
{       
    Chain *pS;	
    pS = getTokenList().First();
    pS = getTokenList().Next();

    Chain tableName;
    Chain attrName(SELECTION_WILDCARD);
    
    if (pS)
    {
	tableName = pS->cutTrailing(".");
    }
    
    _attrDescStack.Push(new CegoAttrDesc(tableName, attrName));   
}

void CegoAction::miscIntString()
{
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	_intString = *pS;
    }
}

void CegoAction::miscNegatedIntString()
{
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	_intString = "-" + *pS;
    }
}

void CegoAction::miscFloatString()
{
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	_floatString = *pS;
    }
}

void CegoAction::miscNegatedFloatString()
{
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	_floatString = "-" + *pS;
    }
}

void CegoAction::miscIntValue()
{
    CegoFieldValue fv(INT_TYPE, _intString);
    _fieldValue = fv;	
}

void CegoAction::miscLongValue()
{
    CegoFieldValue fv(LONG_TYPE, _intString);
    _fieldValue = fv;
}

void CegoAction::miscBigIntValue()
{
    CegoFieldValue fv(BIGINT_TYPE, _intString);   
    _fieldValue = fv;
}

void CegoAction::miscSmallIntValue()
{
    CegoFieldValue fv(SMALLINT_TYPE, _intString);   
    _fieldValue = fv;
}

void CegoAction::miscTinyIntValue()
{
    CegoFieldValue fv(TINYINT_TYPE, _intString);   
    _fieldValue = fv;
}

void CegoAction::miscStringValue() 
{    
    CegoFieldValue fv(VARCHAR_TYPE, Chain(_stringBuf));   
    _fieldValue = fv;
}

void CegoAction::miscFloatValue()
{
    CegoFieldValue fv(FLOAT_TYPE, _floatString);   
    _fieldValue = fv;
}

void CegoAction::miscDoubleValue()
{
    CegoFieldValue fv(DOUBLE_TYPE, _floatString);   
    _fieldValue = fv;
}

void CegoAction::miscDecimalValue()
{
    CegoFieldValue fv(DECIMAL_TYPE, _floatString);   
    _fieldValue = fv;    
}

void CegoAction::miscDatetimeValue()
{
    CegoFieldValue fv(VARCHAR_TYPE, Chain(_stringBuf));
    if ( fv.castTo(DATETIME_TYPE) == false )
    {
	Chain msg = Chain("Cannot cast to datetime");
	throw Exception(EXLOC, msg);
    }
    _fieldValue = fv;
}

void CegoAction::miscNull()
{
    CegoFieldValue fv;
    _fieldValue = fv;
}

void CegoAction::miscSysDate()
{
    unsigned long long *pDV = new unsigned long long;

    // we have to store 0 to datetime value to indicate current sysdate
    // in this case, ths sysdate is calculated if FieldValue::valAsChain is called

    *pDV = 0; 

    CegoFieldValue fv(DATETIME_TYPE, pDV, sizeof(unsigned long long), true);

    _fieldValue = fv;
}

void CegoAction::miscTrueValue()
{
    char *pC = new (char);
    *pC = 1;
    CegoFieldValue fv(BOOL_TYPE, pC, 1, true);

    _fieldValue = fv;
}

void CegoAction::miscFalseValue()
{
    char *pC = new (char);
    *pC = 0;
    CegoFieldValue fv(BOOL_TYPE, pC, 1, true);

    _fieldValue = fv;
}

void CegoAction::miscBlobRef()
{
    Chain pstr;

    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    if ( pS )
    {
	pstr = *pS;
    }

    Chain blobRef = Chain("[") + pstr + Chain("]");
    CegoFieldValue fv(BLOB_TYPE, blobRef);
    _fieldValue = fv;	
}

void CegoAction::miscClobRef()
{
    Chain pstr;

    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    if ( pS )
    {
	pstr = *pS;
    }

    Chain clobRef = Chain("[") + pstr + Chain("]");
    CegoFieldValue fv(CLOB_TYPE, clobRef);
    _fieldValue = fv;	
}

void CegoAction::setObject1()
{
    Chain* pS = getTokenList().First();
    
    if ( pS->length() > MAX_OBJNAME_LEN )
    {		    
	Chain msg = Chain("Name to long for object" );
	throw Exception(EXLOC, msg);
    }
    _objNameStack.Push(*pS);
    _objTableSetStack.Push(_tableSet);
}

void CegoAction::setObject2()
{
    Chain* pS = getTokenList().First();
    Tokenizer t(*pS, '.');

    Chain objName;
    Chain tableSet;
    t.nextToken(tableSet);
    t.nextToken(objName);

    if ( (unsigned)objName.length() > MAX_OBJNAME_LEN )
    {		    
	Chain msg = Chain("Name to long for object" );
	throw Exception(EXLOC, msg);
    }
    _objNameStack.Push(objName);
    _objTableSetStack.Push(tableSet);
}

void CegoAction::setObject3()
{
    Chain* pS = getTokenList().First();
    Tokenizer t(*pS, '@');

    Chain objName;
    Chain tableSet;
    t.nextToken(objName);
    t.nextToken(tableSet);

    if ( (unsigned)objName.length() > MAX_OBJNAME_LEN )
    {		    
	Chain msg = Chain("Name to long for object" );
	throw Exception(EXLOC, msg);
    }

    _objNameStack.Push(objName);
    _objTableSetStack.Push(tableSet);    
}

void CegoAction::setUpdDelAlias()
{
    Chain* pS = getTokenList().First();
    _updDelAlias = *pS;
}

Chain CegoAction::getPlanString(Element *pPlan, const Chain& title, unsigned indent)
{
    Chain planString;

    for ( unsigned i=0; i<indent; i++ )
	planString += Chain(" ");
    
    planString += title + Chain("\n");

    for ( unsigned i=0; i<indent; i++ )
	planString += Chain(" ");

    for ( unsigned i=0; i< (unsigned)title.length(); i++ )
	planString += Chain("-");
    planString += Chain("\n");

    ListT<Element*> joinList = pPlan->getChildren(XML_JOIN_ELEMENT);
    
    Element **pJoinElement = joinList.First();
    unsigned i=2;
    while ( pJoinElement )
    {
	Chain tableName = (*pJoinElement)->getAttributeValue(XML_TABLENAME_ATTR);
	Chain aliasName = (*pJoinElement)->getAttributeValue(XML_NAME_ATTR);
	Chain tableType = (*pJoinElement)->getAttributeValue(XML_TABLETYPE_ATTR);

	planString += getJoinPlanString(*pJoinElement, Chain("Join plan for ") + aliasName, indent + i);

	i=i+2;
	pJoinElement = joinList.Next();
    }

    ListT<Element*> subList = pPlan->getChildren(XML_PLAN_ELEMENT);
    Element **pSubElement = subList.First();
    while ( pSubElement )
    {
	planString += getPlanString(*pSubElement, "Execution plan for subquery", indent + 2);
	pSubElement = subList.Next();	
    }


    ListT<Element*> predList = pPlan->getChildren(XML_PRED_ELEMENT);
    Element **pPredElement = predList.First();
    while ( pPredElement )
    {
        Chain masterPred = (*pPredElement)->getAttributeValue(XML_PRED_ATTR);
	for ( unsigned i=0; i<indent + 2; i++ )
	    planString += Chain(" ");
	
	planString += Chain("with query master predicate ") + masterPred + Chain("\n");
	pPredElement = predList.Next();	
    }

    return planString;
}

Chain CegoAction::getJoinPlanString(Element *pJoin, const Chain& title, unsigned indent)
{
    Chain planString;
    
    Chain tableName = pJoin->getAttributeValue(XML_TABLENAME_ATTR);
    Chain aliasName = pJoin->getAttributeValue(XML_NAME_ATTR);
    Chain tableType = pJoin->getAttributeValue(XML_TABLETYPE_ATTR);
    Chain joinStrat = pJoin->getAttributeValue(XML_JOINSTRAT_ATTR);
	
    if ( tableType == Chain(XML_TABLE_VALUE) )
    {
	for ( unsigned i=0; i<indent; i++ )
	    planString += Chain(" ");
	planString += Chain("Joining table ") + tableName + Chain(" (") + aliasName + Chain(") with\n");

	Tokenizer tok(joinStrat, Chain("\n"));
	Chain stratLine;
	while ( tok.nextToken(stratLine) )
	{	    
	    for ( unsigned i=0; i<indent; i++ )
		planString += Chain(" ");
	    planString += stratLine + Chain("\n");
	}
    }
    else if ( tableType == Chain(XML_ALIAS_VALUE) )
    {
	for ( unsigned i=0; i<indent; i++ )
	    planString += Chain(" ");
	planString += Chain("Joining alias ") + aliasName + Chain("\n");

	ListT<Element*> joinList = pJoin->getChildren(XML_JOIN_ELEMENT);
	Element** pJoin = joinList.First();
	while ( pJoin ) 
	{
	    planString += getJoinPlanString(*pJoin, Chain("Execution plan for alias ") + aliasName , indent + 2);
	    pJoin = joinList.Next();
	}
    }
    else if ( tableType == Chain(XML_VIEW_VALUE) )
    {
	for ( unsigned i=0; i<indent; i++ )
	    planString += Chain(" ");
	planString += Chain("Joining view ") + tableName + Chain(" (") + aliasName + Chain(")\n");
	
	ListT<Element*> planList = pJoin->getChildren(XML_PLAN_ELEMENT);
	Element** pPlan = planList.First();
	while ( pPlan ) 
	{
	    planString += getPlanString(*pPlan, Chain("Execution plan for ") + aliasName, indent + 2);
	    pPlan = planList.Next();
	}
    }
    else if ( tableType == Chain(XML_INNERJOIN_VALUE)
	      || tableType == Chain(XML_LEFTOUTERJOIN_VALUE)
	      || tableType == Chain(XML_RIGHTOUTERJOIN_VALUE) )
	      
    {
	for ( unsigned i=0; i<indent; i++ )
	    planString += Chain(" ");
	
	Chain joinType;
	if ( tableType == Chain(XML_INNERJOIN_VALUE) )
	    joinType = Chain("Inner");
	else if ( tableType == Chain(XML_LEFTOUTERJOIN_VALUE) )
	    joinType = Chain("Left outer");
	else if ( tableType == Chain(XML_RIGHTOUTERJOIN_VALUE) )
	    joinType = Chain("Right outer");

	planString += joinType + Chain(" ") + tableName + Chain(" (") + aliasName + Chain(") with\n");

	
	Tokenizer tok(joinStrat, Chain("\n"));
	Chain stratLine;
	while ( tok.nextToken(stratLine) )
	{	    
	    for ( unsigned i=0; i<indent; i++ )
		planString += Chain(" ");
	    planString += stratLine + Chain("\n");
	}
	
	ListT<Element*> planList = pJoin->getChildren(XML_JOIN_ELEMENT);
	Element** pPlan = planList.First();
	while ( pPlan ) 
	{
	    planString += getJoinPlanString(*pPlan, Chain("Join plan for ") + aliasName, indent + 2);
	    pPlan = planList.Next();
	}
    }	

    return planString;
}

void CegoAction::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)
{   
    if ( _pTabMng == 0 )
	throw Exception(EXLOC, "No valid table manager set up");

    unsigned maxNameLen = 0;
    ListT<CegoFieldValue> fv;
    
    fv.Insert(CegoFieldValue(VARCHAR_TYPE, tableName));	
    maxNameLen = (unsigned)tableName.length();
    
    fv.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("table")));

    if ( withSize )
    {
	unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);    
	unsigned pageCount = _pTabMng->getPageCount(tabSetId, tableName, CegoObject::TABLE);
	
	fv.Insert(CegoFieldValue(INT_TYPE, Chain(pageCount)));
	fv.Insert(CegoFieldValue(INT_TYPE, Chain(0)));
    }

    fa.Insert(fv);

    CegoTableObject *pOE = idxList.First();
    while ( pOE )
    {
	ListT<CegoFieldValue> fv1;
    
	fv1.Insert(CegoFieldValue(VARCHAR_TYPE, pOE->getName()));
	maxNameLen = MAX((unsigned)pOE->getName().length(), maxNameLen);
	
	switch ( pOE->getType() )
	{
	case CegoObject::AVLTREE:
	    fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("index")));
	    break;
	case CegoObject::UAVLTREE:
	    fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("unique index")));
	    break;
	case CegoObject::PAVLTREE:
	    fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("primary index")));
	    break;
	case CegoObject::SYSTEM:
	case CegoObject::TABLE:
	case CegoObject::VIEW:
	case CegoObject::RBSEG:
	case CegoObject::FKEY:
	case CegoObject::PROCEDURE:
	case CegoObject::CHECK:
	case CegoObject::JOIN:
	case CegoObject::PBTREE:
	case CegoObject::UBTREE:
	case CegoObject::BTREE:
	case CegoObject::TRIGGER:
	case CegoObject::ALIAS:
	case CegoObject::UNDEFINED:
	    Chain msg = Chain("Invalid object type for format" );
	    throw Exception(EXLOC, msg);	    
	}

	if ( withSize )
	{
	    if ( pOE->isValid() )
	    {
		unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);    
		unsigned pageCount = _pTabMng->getPageCount(tabSetId, pOE->getName(), pOE->getType());	
		fv1.Insert(CegoFieldValue(INT_TYPE, Chain(pageCount)));
	    }
	    else
	    {
		fv1.Insert(CegoFieldValue());
	    }
	    
	    // relevance not supported
	    fv1.Insert(CegoFieldValue(INT_TYPE, Chain(0)));
	}

	fa.Insert(fv1);

	pOE = idxList.Next();
    }

    CegoBTreeObject *pBTO = btreeList.First();
    while ( pBTO )
    {
	ListT<CegoFieldValue> fv1;
    
	fv1.Insert(CegoFieldValue(VARCHAR_TYPE, pBTO->getName()));
	maxNameLen = MAX((unsigned)pBTO->getName().length(), maxNameLen);
	
	switch ( pBTO->getType() )
	{
	case CegoObject::BTREE:
	    fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("btree")));
	    break;
	case CegoObject::UBTREE:
	    fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("unique btree")));
	    break;
	case CegoObject::PBTREE:
	    fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("primary btree")));
	    break;
	case CegoObject::SYSTEM:
	case CegoObject::TABLE:
	case CegoObject::VIEW:
	case CegoObject::RBSEG:
	case CegoObject::FKEY:
	case CegoObject::PROCEDURE:
	case CegoObject::CHECK:
	case CegoObject::JOIN:
	case CegoObject::PAVLTREE:
	case CegoObject::UAVLTREE:
	case CegoObject::AVLTREE:
	case CegoObject::TRIGGER:
	case CegoObject::ALIAS:
	case CegoObject::UNDEFINED:
	    Chain msg = Chain("Invalid object type for format" );
	    throw Exception(EXLOC, msg);	    
	}

	if ( withSize )
	{
	    if ( pBTO->isValid() )
	    {
		unsigned tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
		unsigned pageCount = _pTabMng->getPageCount(tabSetId, pBTO->getName(), pBTO->getType());	
		fv1.Insert(CegoFieldValue(INT_TYPE, Chain(pageCount)));
	    }
	    else
	    {
		fv1.Insert(CegoFieldValue());
	    }
	
	    // relevance 
	    fv1.Insert(CegoFieldValue(INT_TYPE, Chain(pBTO->getRelevance())));
	}
	
	fa.Insert(fv1);

	pBTO = btreeList.Next();
    }

    CegoCheckObject *pCE = checkList.First();
    while ( pCE )
    {
	ListT<CegoFieldValue> fv1;
    
	fv1.Insert(CegoFieldValue(VARCHAR_TYPE, pCE->getName()));
	maxNameLen = MAX((unsigned)pCE->getName().length(), maxNameLen);
	
	fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("check")));
	
	if ( withSize )
	{
	    fv1.Insert(CegoFieldValue(INT_TYPE, Chain(0)));
	    fv1.Insert(CegoFieldValue(INT_TYPE, Chain(0)));
	}
	
	fa.Insert(fv1);
	pCE = checkList.Next();
    }

    CegoKeyObject *pKE = keyList.First();
    while ( pKE )
    {    
	ListT<CegoFieldValue> fv1;
    
	fv1.Insert(CegoFieldValue(VARCHAR_TYPE, pKE->getName()));
	maxNameLen = MAX((unsigned)pKE->getName().length(), maxNameLen);
	
	fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("foreign key")));

	if ( withSize )
	{
	    fv1.Insert(CegoFieldValue(INT_TYPE, Chain(0)));
	    fv1.Insert(CegoFieldValue(INT_TYPE, Chain(0)));
	}
	
	fa.Insert(fv1);
	pKE = keyList.Next();
    }

    CegoTriggerObject *pTO = triggerList.First();
    while ( pTO )
    {    
	ListT<CegoFieldValue> fv1;
    
	fv1.Insert(CegoFieldValue(VARCHAR_TYPE, pTO->getName()));
	maxNameLen = MAX((unsigned)pTO->getName().length(), maxNameLen);
	
	fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("trigger")));

	if ( withSize )
	{
	    fv1.Insert(CegoFieldValue(INT_TYPE, Chain(0)));
	    fv1.Insert(CegoFieldValue(INT_TYPE, Chain(0)));
	}
	
	fa.Insert(fv1);
	pTO = triggerList.Next();
    }

    CegoAliasObject *pAO = aliasList.First();
    while ( pAO )
    {
	ListT<CegoFieldValue> fv1;
    
	fv1.Insert(CegoFieldValue(VARCHAR_TYPE, pAO->getName()));
	maxNameLen = MAX((unsigned)pAO->getName().length(), maxNameLen);
	
	fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("alias")));

	if ( withSize )
	{
	    fv1.Insert(CegoFieldValue(INT_TYPE, Chain(0)));
	    fv1.Insert(CegoFieldValue(INT_TYPE, Chain(0)));
	}
	
	fa.Insert(fv1);
	pAO = aliasList.Next();
    }

    ListT<CegoField> schema;
    schema.Insert(CegoField(Chain("TABLEINFO"), Chain("TABLEINFO"), Chain("NAME"), VARCHAR_TYPE, maxNameLen));
    schema.Insert(CegoField(Chain("TABLEINFO"), Chain("TABLEINFO"), Chain("TYPE"), VARCHAR_TYPE, 15));

    if ( withSize )
    {
	schema.Insert(CegoField(Chain("TABLEINFO"), Chain("TABLEINFO"), Chain("PAGES"), INT_TYPE, sizeof(unsigned)));
	schema.Insert(CegoField(Chain("TABLEINFO"), Chain("TABLEINFO"), Chain("RELEVANCE"), INT_TYPE, sizeof(unsigned)));
    }
    
    oe = CegoTableObject(0, CegoObject::SYSTEM, Chain("SYSINFO"), schema, Chain("SYSINFO"));
}

bool CegoAction::processBatchFile(const Chain& batchFileName, bool ignoreError, bool consoleOut, Chain& errorMsg)
{
    File batchFile(batchFileName);
    batchFile.open(File::READ);

    unsigned lineNo=0;

    Chain cmd;
    Chain line;

    bool disableDelimiter=false;

    CegoDatabaseManager *pDBMng = _pTabMng->getDBMng();
    
#ifdef CGDEBUG	
    pDBMng->log(_modId, Logger::DEBUG, Chain("Processing batchfile ") + batchFileName);
#endif
    
    while (batchFile.readLine(line, MAXCMDLEN))
    {
	lineNo++;

	line = CegoQueryHelper::skipComment(line);
	
	if ( line.truncRight(" \t") == Chain("@") )
	{
	    if ( disableDelimiter == false )
		disableDelimiter=true;
	    else
		disableDelimiter=false;
	}
	else
	{			
	    cmd = cmd + Chain(" ") + line;
	    // cmd = cmd.cutTrailing(" \t");
	}
		    
	if ( cmd.length() > 0 )
	{	    
	    if (cmd.subChain(cmd.length()-1, cmd.length()) == Chain(";") 
		&& disableDelimiter==false)
	    {	
		if ( consoleOut == false )			
		{
		    pDBMng->log(_modId, Logger::NOTICE, Chain("Processing batch command <<<") + cmd + Chain(">>>"));
		}
#ifdef CGDEBUG	
		pDBMng->log(_modId, Logger::DEBUG, Chain("Processing batch command <<<") + cmd + Chain(">>>"));
#endif
		cleanUp();
		setCommandChain(cmd);
		
		try
		{		    
		    Timer t(6,3);
		    t.start();			
		    parse();
		    execute();			
		    t.stop();
		    
		    if ( consoleOut )
			cout << "ok ( " << t << " s )" << endl;
		}
		catch ( Exception e)
		{
		    Chain msg;
		    Chain module;
		    unsigned line;
		    
		    Chain exep;
		    while ( e.pop(module, line, msg) )
		    {
			exep += Chain("\n\t") + module + Chain("(") +  Chain(line) + Chain(") : ") + msg;
		    }
		    
		    pDBMng->log(_modId, Logger::LOGERR, Chain("Batch Error : ") + exep);
		    
		    errorMsg=e.getBaseMsg();			
		    
		    if ( ignoreError )
		    {			
			if ( consoleOut )
			{
			    cerr << Chain("Error ignored at line number ") + Chain(lineNo) + " : ";
			    cerr << errorMsg << endl;
			}
		    }
		    else
		    {
			if ( consoleOut )
			{
			    cerr << Chain("Line Number ") + Chain(lineNo) + Chain(" : ");
			    cerr << errorMsg << endl;
			}			
			return false;			
		    }
		}		
		cmd = Chain();		
	    }
	}
    }
    cmd = cmd.cutTrailing(" \t");
    if ( cmd.length() > 1 && consoleOut)
    {
	if ( consoleOut )
	    cerr << "Incomplete command <<<" << cmd << ">>>" << endl;
    }
    
    batchFile.close();

    return true;    
}

CegoSelect* CegoAction::getSelect(bool setToNull)
{
    CegoSelect *pSelect = _pSelect;
    if ( setToNull )
	_pSelect = 0;
    return pSelect;
}

CegoProcedure* CegoAction::getProcedure(bool setToNull)
{
    CegoProcedure *pProc = _pProc;
    if ( setToNull )
	_pProc = 0;
    return pProc;
}

CegoTrigger* CegoAction::getTrigger(bool setToNull)
{
    CegoTrigger *pTrigger = _pTrigger;
    if ( setToNull )
	_pTrigger = 0;
    return pTrigger;
}

CegoCondition* CegoAction::getCondition(bool setToNull)
{
    CegoCondition *pCond = _pCond;
    if ( setToNull )
	_pCond = 0;
    return pCond;
}
