///////////////////////////////////////////////////////////////////////////////
//                                                         
// CegoAction.cc  
// -------------                                                        
// Cego semantic parser actions
//
// Design and Implementation by Bjoern Lemke
//     
// (C)opyright 2000-2012 Bjoern Lemke
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; see the file COPYING.  If not, write to
// the Free Software Foundation, 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
// IMPLEMENTATION MODULE
//
// Class: CegoAction
// 
// Description: see header file for detailed description
//
// Status: QG-2.13
//
///////////////////////////////////////////////////////////////////////////////

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

#include "CegoDefs.h"
#include "CegoOutput.h"
#include "CegoAction.h"
#include "CegoXMLdef.h"
#include "CegoSelect.h"
#include "CegoProcedure.h"
#include "CegoProcAssignStmt.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>

extern char __quoteEscapeFlag;
extern char __caseSensitiveFlag;

CegoAction::CegoAction(CegoDistManager* pTabMng, CegoDbThreadPool* pDbPool) 
{
    _pTabMng = pTabMng;
    _pMasterBlock = new CegoProcBlock(0);
    _i=0;
    _pC = 0;
    _pDbHandle = 0;
    _pQuery = 0;
    // _appendMode = true;
    _distinctOpt = false;
    _distinctAgg = false;

    _pDbPool = pDbPool;
    _procType = CegoProcedure::PROCEDURE;
    _pCondList = 0;
    _pIfBlockList = 0;
    _pGroupList = 0;
    _pOrderingList = 0;
    _pOrderingOptList = 0;

    _procContext = false;
    _queryCacheEnabled = true;

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

CegoAction::~CegoAction()  
{
    delete _pMasterBlock;
}

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

char CegoAction::nextChar() 
{   
    if ( _pC == 0 )
	return 0;
    
    if ( *_pC == '\'')
    {
	_pC++;
	readChain();
	return 0;
    }
 
    if ( *_pC == 0 ) 
    {
        return 0; 
    }
    
    char c = *_pC; 
    _pC++; 

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

void CegoAction::readChain()
{

    setReserved(STRINGVAL); 
    
    int i=0;    

    if ( __quoteEscapeFlag )
    {
	bool moreChar = true; 
	while ( moreChar )
	{	    
	    if ( *_pC == '\'') 
	    {
		_pC++;
		if ( *_pC == '\'')
		{
		    _stringBuf[i] = '\'';
		    i++;
		}
		else
		{
		    moreChar = false;
		}
	    }
	    else if ( *_pC == '\\') 
	    { 
		_pC++; 
		
		if ( *_pC == 'n') 
		{ 
		    _stringBuf[i] = '\n'; 
		} 
		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);
		}
		i++;
	    }
	    else
	    {
		_stringBuf[i] = *_pC; 		
		i++;
	    }
	  
	    if (i == MAXSTRINGLEN) 
	    { 
		Chain msg("Stringbuf exceeded"); 
		throw Exception(EXLOC, msg);
	    }
	    
	    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 == '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; 
	    } 
	    
	    i++; 
	    
	    if (i == MAXSTRINGLEN) 
	    { 
		Chain msg("Stringbuf exceeded"); 
		throw Exception(EXLOC, msg);
	    }
	    
	    _pC++;
	    
	    if ( *_pC == 0 )
	    {
		Chain msg("Unterminated string"); 
		throw Exception(EXLOC, msg);
	    }
	}

	_pC++; 

    }

    _stringBufLen = i+1;
    _stringBuf[i] = 0; 

    return; 
}

void CegoAction::backChar() 
{
    if ( _pC > 0 )
	_pC--;
}
    
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() 
{
    _stringBufLen = 0;

    _fal.Empty();
    _exprList.Empty();
    _fieldList.Empty();
    _idxList.Empty();
    _coList.Empty();
    _alterList.Empty();
    _jdbcArgList.Empty();

    if ( _pCondList )
    {
	_pCondList->Empty();
	delete _pCondList;
	_pCondList = 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();
    _havingDescStack.Empty();
    _caseCondStack.Empty();
    _coListStack.Empty();
    _exprListStack.Empty();
    _groupClauseStack.Empty();
    _objNameStack.Empty();
    _objTableSetStack.Empty();
    _condStack.Empty();
    _predStack.Empty();
    _termStack.Empty();
    _factorStack.Empty();
    _exprStack.Empty();
    _functionStack.Empty();
    _unionStack.Empty();
    _condListStack.Empty();  
    _orderingClauseStack.Empty();
    _orderingOptStack.Empty();

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

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

}

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

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

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

CegoSelect* CegoAction::getSelect()
{
    return _pSelect;
}

CegoProcedure* CegoAction::getProcedure()
{
    return _pProc;
}

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

void CegoAction::execSync() 
{
    _pTabMng->writeCheckPoint(_tableSet, true, true);
    
    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    msg = Chain("TableSet ") + _tableSet + Chain(" in sync");
    
    o.chainOut(msg);
}

void CegoAction::execListTableSet()
{
    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);
    
    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()
{
    
    ListT<Chain> objList;
    _pTabMng->getDistObjectList(_tableSet, 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);
    
    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()
{
    
    int tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);

    ListT<Chain> objList;
    _pTabMng->getDistObjectList(_tableSet, CegoObject::VIEW, objList);

    int viewLen=0;
    Chain *pS = objList.First();    
    while ( pS )
    {
	if (viewLen < pS->length() )
	    viewLen = 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);
    
    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()
{
    int tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);

    ListT<Chain> objList;
    _pTabMng->getDistObjectList(_tableSet, CegoObject::PROCEDURE, objList);

    int procLen=0;
    Chain *pS = objList.First();    
    while ( pS )
    {
	if (procLen < pS->length() )
	    procLen = 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);
    
    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()
{
    ListT<Chain> objList;
    _pTabMng->getDistObjectList(_tableSet, CegoObject::INDEX, 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);
    
    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()
{
    ListT<Chain> objList;
    _pTabMng->getDistObjectList(_tableSet, 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);
    
    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()
{
    
    ListT<Chain> objList;
    _pTabMng->getDistObjectList(_tableSet, 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);
    
    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()
{
    
    ListT<Chain> counterNameList;
    
    int tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
    _pTabMng->getDBMng()->getCounterList(tabSetId, counterNameList);    

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

    ListT<CegoField> schema;
    schema.Insert( CegoField("Counter", "Counter", "Name", VARCHAR_TYPE, maxCounterLen ));
    schema.Insert( CegoField("Counter", "Counter", "Value", VARCHAR_TYPE, 20 ));
    
    CegoOutput o(schema);
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT);
    
    o.headOut();
    
    pS = counterNameList.First();
    while ( pS )
    {
	ListT<CegoFieldValue> fa;
	fa.Insert( CegoFieldValue(VARCHAR_TYPE, *pS) );
	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()
{

    ListT<Chain> objList;
    _pTabMng->getDistObjectList(_tableSet, 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);
    
    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()
{

    ListT<Chain> objList;
    _pTabMng->getDistObjectList(_tableSet, 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);
    
    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()
{

    ListT<Chain> objList;
    _pTabMng->getDistObjectList(_tableSet, 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);
    
    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::jdbcInfo()
{
    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::setTableSetOpt()
{
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	_tableSet = *pS;
    }
}

void CegoAction::execTableInfo()
{
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    
    ListT<CegoTableObject> idxList;
    ListT<CegoBTreeObject> btreeList;
    ListT<CegoKeyObject> keyList;
    ListT<CegoCheckObject> checkList;
    
    bool ignoreInvalid = false;
    _pTabMng->getDistObjectByTableList(_tableSet, tableName, idxList, btreeList, keyList, checkList, ignoreInvalid);

    CegoTableObject oe;
    ListT< ListT < CegoFieldValue > > fa;
    
    formatTableInfo(tableSet, tableName, idxList, btreeList, keyList, checkList, oe, fa);
    
    CegoOutput o(oe.getSchema());
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT);
    
    o.tabOut(fa);   
}

void CegoAction::execShowPool() 
{

    CegoTableObject oe;
    ListT< ListT < CegoFieldValue > > fa;
    
    _pTabMng->getPoolInfo(oe, fa);
    
    CegoOutput o(oe.getSchema());
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT);
    o.tabOut(fa);
    
}

// TODO : make distribution ready
void CegoAction::execShowSystemSpace() 
{
    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);
    
    o.tabOut(fa);
} 

void CegoAction::execTableDesc()
{
    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);
    
    o.tabOut(fa);
    
}

void CegoAction::execIndexDesc()
{
    Chain idxName;
    Chain tableSet;
    
    _objNameStack.Pop(idxName);
    _objTableSetStack.Pop(tableSet);

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

    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT);

    o.tabOut(fa);
    
}


void CegoAction::execBTreeDesc()
{
    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);

    o.tabOut(fa);
    
}


void CegoAction::execKeyDesc()
{
    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);
    
    o.tabOut(fa);
    
}


void CegoAction::execCheckDesc()
{
    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);
    
    o.tabOut(fa);
    
}

void CegoAction::execViewDesc()
{
    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);
    
    o.tabOut(fa);
    
}

void CegoAction::execProcDesc()
{

    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);
    
    o.tabOut(fa);

}

void CegoAction::execViewShow()
{
    Chain viewName;
    Chain viewTableSet;
    
    _objNameStack.Pop(viewName);
    _objTableSetStack.Pop(viewTableSet);
    
    CegoViewObject vo;
    _pTabMng->getDistObject(viewTableSet, viewName,  CegoObject::VIEW, vo);

    int maxLen = 0;
    Tokenizer tok(vo.getViewStmt(), Chain("\n"));
    Chain l;
    while ( tok.nextToken(l) )
    {
	if ( maxLen < l.length() )
	    maxLen = 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);
    
    o.tabOut(fa);

}

void CegoAction::execCheckShow()
{
    Chain checkName;
    Chain checkTableSet;
    
    _objNameStack.Pop(checkName);
    _objTableSetStack.Pop(checkTableSet);
    
    CegoCheckObject co;
    _pTabMng->getDistObject(checkTableSet, checkName, CegoObject::CHECK, co);

    int maxLen = 0;
    Tokenizer tok(co.getPredDesc()->toChain(), Chain("\n"));
    Chain l;
    while ( tok.nextToken(l) )
    {
	if ( maxLen < l.length() )
	    maxLen = 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()));
    fa.Insert(fvl);

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

    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT);
    
    o.tabOut(fa);

}

void CegoAction::execProcShow()
{
    Chain procName;
    Chain procTableSet;
    
    _objNameStack.Pop(procName);
    _objTableSetStack.Pop(procTableSet);
    
    CegoProcObject po;
    _pTabMng->getDistObject(procTableSet, procName, CegoObject::PROCEDURE, po);

    int maxLen = 0;
    Tokenizer tok(po.getProcText(), Chain("\n"));
    Chain l;
    while ( tok.nextToken(l) )
    {
	if ( maxLen < l.length() )
	    maxLen = 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);
    
    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);
    
    msg = Chain("Tableset ") + tableSet + Chain(" set");
    
    o.chainOut(msg);

}

void CegoAction::execAuthUser()
{

    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);
    
    msg = Chain("User ") + user + Chain(" authorized for ") + tableSet;
    
    o.chainOut(msg);

}

void CegoAction::execEnableAppendMode()
{

    _pTabMng->setAppend(true);

    // _appendMode = true;
    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    msg = Chain("Append mode enabled");
    
    o.chainOut(msg);
}

void CegoAction::execDisableAppendMode()
{

    _pTabMng->setAppend(false);
    // _appendMode = false;

    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    msg = Chain("Append mode disabled");
    
    o.chainOut(msg);

}

void CegoAction::execEnableAutoCommit()
{
    _pTabMng->setAutoCommit(true);

    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    msg = Chain("AutoCommit enabled");
    
    o.chainOut(msg);
}

void CegoAction::execDisableAutoCommit()
{

    _pTabMng->setAutoCommit(false);
    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    msg = Chain("AutoCommit disabled");
    
    o.chainOut(msg);

}

// TODO : make distribution ready
void CegoAction::execSetIsolation()
{

    Chain level;
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	level = *pS;
    }
	
    if ( level == Chain("read_uncommitted") )
    {
	_pTabMng->setIsolationLevel(CegoTableManager::READ_UNCOMMITTED);
    }
    else if ( level == 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);
    
    msg = Chain("Isolation level set");
    
    o.chainOut(msg);

}

void CegoAction::execEnableQueryCache()
{
    _queryCacheEnabled = true;

    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    msg = Chain("Query cache enabled");
    
    o.chainOut(msg);

}

void CegoAction::execDisableQueryCache()
{
    _queryCacheEnabled = false;
    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    msg = Chain("Query cache disabled");
    
    o.chainOut(msg);

}

void CegoAction::execTableReorganize()
{


    Chain objName;
    Chain tableSet;
    
    _objNameStack.Pop(objName);
    _objTableSetStack.Pop(tableSet);
    
    _pTabMng->reorgDistObject(tableSet, objName, CegoObject::TABLE);
    
    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    msg = Chain("Table ") + objName + Chain(" reorganized");
    
    o.chainOut(msg);
    
}

void CegoAction::execIndexReorganize()
{


    Chain objName;
    Chain tableSet;
    
    _objNameStack.Pop(objName);
    _objTableSetStack.Pop(tableSet);
    
    _pTabMng->reorgDistObject(tableSet, objName, CegoObject::INDEX);
    
    CegoOutput o;	
    Chain msg;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    msg = Chain("Index ") + objName + Chain(" reorganized");
    
    o.chainOut(msg);
    
}

void CegoAction::execSelect()
{

    if ( _pSelect )
    {

	try {

	    ListT<CegoField> schema;

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

	    
	    _pSelect->setProcBlock(_pMasterBlock);
	    _pSelect->setTabSetId(tabSetId);
	    _pSelect->prepare();
	    _pSelect->setParentJoinBuf();
	    	    
	    _pSelect->checkValidRef();

	    ListT<CegoField> fl;
	    bool moreTuple = _pSelect->nextTuple(fl);

	    _pSelect->getSchema(schema);
	    CegoOutput output(schema);
	    
	    if ( _pDbHandle )
		output.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT);
	    
	    output.headOut();
	    
	    while ( moreTuple )
	    {

		output.rowOut(fl);

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

		try 
		{		    
		    moreTuple = _pSelect->nextTuple(fl);
		}
		catch ( Exception e )
		{
		    moreTuple=false;
		    output.abort(e.getBaseMsg());
		    delete _pSelect;
		    return;
		}

	    }
	    
	    output.tailOut();
	    delete _pSelect;
	}
	catch ( Exception e )
	{
	    delete _pSelect;	    
	    throw Exception(EXLOC, Chain("Select execution error"), e);
	}
    }
    else
    {
	throw Exception(EXLOC, "No valid select handle");
    }
    
}

void CegoAction::execSelectPlan()
{
    if ( _pSelect )
    {
	try {

	    int tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
	    
	    _pSelect->setTabSetId(tabSetId);
	    _pSelect->prepare();

	    _pSelect->checkValidRef();
	    
	    Chain planString;
	    planString = getPlanString(_pSelect->getPlan(), Chain("Execution plan"));
	    
	    int maxLen = 0;
	    Tokenizer tok(planString, Chain("\n"));
	    Chain l;
	    while ( tok.nextToken(l) )
	    {
		if ( maxLen < l.length() )
		    maxLen = 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);

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

void CegoAction::execQuery()
{

    Chain msg;
    CegoOutput o;

    try 
    {
	msg = _pQuery->execute(_pMasterBlock);
	long affCount = _pQuery->getAffectedCount();
	
	if ( _pDbHandle )
	    o.setDbHandle(_pDbHandle);
	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() 
{

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

    int tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
    ListT<CegoField> schema;

    bool doCompile=true;

    try
    {
	_pSelect->setTabSetId(tabSetId);
	_pSelect->prepare();
	_pSelect->getSchema(schema);
    }
    catch ( Exception e )
    {	
	doCompile=false;
	_pTabMng->getDBMng()->log(_modId, Logger::NOTICE, Chain("View ") + viewName + Chain(" can not be compiled"));
    }
    
    Chain viewStmt = Chain("view ") + viewName + Chain(" as\n") + _pSelect->toChain() + Chain(";");
    _pTabMng->createDistView(tableSet, viewName, schema, viewStmt);

    if ( doCompile )
    {
	_pTabMng->getDBMng()->useObject(tabSetId, viewName, CegoObject::VIEW, CegoDatabaseManager::EXCLUSIVE, _pTabMng->getThreadId());
	
	try 
	{	    	    
	    if ( _pDbPool ) 
	    {
		// object is invalidated for recompilation by  each db thread
		_pDbPool->invalidateObject(tabSetId, viewName, CegoObject::VIEW);
		delete _pSelect;
	    }
	    else
	    {
		CegoView *pView = new CegoView(viewName, _pSelect);
		_pTabMng->addCompView(tabSetId, pView);
	    }	    
	}
	catch ( Exception e )
	{
	    _pTabMng->getDBMng()->unuseObject(tabSetId, viewName, CegoObject::VIEW, CegoDatabaseManager::EXCLUSIVE);
	    Chain msg = Chain("Compile error for view ") + viewName;
	    throw Exception(EXLOC, msg, e );
	}
	_pTabMng->getDBMng()->unuseObject(tabSetId, viewName, CegoObject::VIEW, CegoDatabaseManager::EXCLUSIVE);
    }
    else
    {
	delete _pSelect;
    }
    
    Chain msg;
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    msg = Chain("View ") + viewName + Chain(" created");
    
    o.chainOut(msg);
    
}

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

void CegoAction::execViewDrop() 
{

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


    bool doDrop=true;
    
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->distObjectExists(tableSet, viewName, CegoObject::VIEW) == false )
	    doDrop=false;
    }

    Chain msg;
    
    if ( doDrop )
    {
    
	int tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);   

	_pTabMng->getDBMng()->useObject(tabSetId, viewName, CegoObject::VIEW, CegoDatabaseManager::EXCLUSIVE, _pTabMng->getThreadId());

	try 
	{
	    _pTabMng->dropDistObject(viewName, tableSet, CegoObject::VIEW);
	    
	    if ( _pDbPool )
		_pDbPool->invalidateObject(tabSetId, viewName, CegoObject::VIEW);
	    else
		_pTabMng->removeCompView(tabSetId, viewName);

	    msg = Chain("View ") + viewName + Chain(" dropped");

	}
	catch ( Exception e )
	{
	    _pTabMng->getDBMng()->unuseObject(tabSetId, viewName, CegoObject::VIEW, CegoDatabaseManager::EXCLUSIVE);
	    throw Exception(EXLOC, "Cannot drop view", e);
	}
    }
    else
    {
	msg = Chain("View ") + viewName + Chain(" does not exist");
    }
    
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    o.chainOut(msg);
}

void CegoAction::execProcCreate()
{
    
    Chain procName;
    int tabSetId;

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

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

    try 
    {

	if ( _pDbPool ) 
	{
	    // object is invalidated for recompilation by  each db thread
	    _pDbPool->invalidateObject(tabSetId, _pProc->getName(), CegoObject::PROCEDURE);
	    delete _pProc;
	    _pProc = 0;
	}
	else
	{
	    _pTabMng->addCompProcedure(tabSetId, _pProc);
	    _pProc = 0;
	}
	
	Chain msg;
	CegoOutput o;
	
	if ( _pDbHandle )
	    o.setDbHandle(_pDbHandle);
	
	msg = Chain("Procedure ") + procName + Chain(" created");
	
	o.chainOut(msg);

	_pTabMng->getDBMng()->unuseObject(tabSetId, procName, CegoObject::PROCEDURE, CegoDatabaseManager::EXCLUSIVE);
	
    }
    catch ( Exception e )
    {
	if ( _pProc )
	    delete _pProc;
	
	_pTabMng->getDBMng()->unuseObject(tabSetId, procName, CegoObject::PROCEDURE, CegoDatabaseManager::EXCLUSIVE);	
	throw Exception(EXLOC, "Cannot create procedure", e);
    }

}

void CegoAction::execProcLoad()
{
    // nothing to do for now
}

void CegoAction::execProcCall()
{

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

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

    int tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
    
    _pTabMng->getDBMng()->useObject(tabSetId, procName, CegoObject::PROCEDURE, CegoDatabaseManager::SHARED, _pTabMng->getThreadId());
    
    try 
    {
	CegoProcedure* pProc = _pTabMng->getProcedure(tabSetId, procName);

	pProc->setMasterBlock(_pMasterBlock);
	
	ListT<CegoProcVar> argList;
	pProc->getArgList(argList);
	
	CegoProcVar *pVar = argList.First();
	CegoExpr **pExpr = exprList.First();
	while ( pVar && pExpr ) 
	{
	    
	    (*pExpr)->setBlock(_pMasterBlock);
	    
	    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, nullVal));
		}		       
	    }
	    pExpr = exprList.Next();
	    pVar = argList.Next();
	}
        
	CegoOutput o;
	
	if ( _pDbHandle )
	{
	    o.setDbHandle(_pDbHandle);    
	}
		
	pProc->execute(exprList);
	
	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);
    }
    catch ( Exception e)
    {	
	CegoExpr** pExpr = exprList.First();
	while ( pExpr )
	{
	    delete *pExpr;
	    pExpr = exprList.Next();
	}
	exprList.Empty();

	_pTabMng->getDBMng()->unuseObject(tabSetId, procName, CegoObject::PROCEDURE, CegoDatabaseManager::SHARED);    
	throw Exception(EXLOC, "Cannot execute procedure", e);
    }
    _pTabMng->getDBMng()->unuseObject(tabSetId, procName, CegoObject::PROCEDURE, CegoDatabaseManager::SHARED);    
}

void CegoAction::execFuncCall()
{

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

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

    int 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->getThreadId());

    try
    {
	
	CegoProcVar *pRetVar = _pMasterBlock->getVarList().Find(CegoProcVar(retVar));
	if ( pRetVar == 0 )
	{
	    CegoFieldValue nullVal;
	    _pMasterBlock->getVarList().Insert(CegoProcVar(retVar, CegoProcVar::BLOCKVAR, NULL_TYPE, 0, nullVal));
	}
	
	CegoProcedure* 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);
	
	CegoProcVar *pVar = argList.First();
	CegoExpr **pExpr = exprList.First();
	while ( pVar && pExpr ) 
	{
	    
	    (*pExpr)->setBlock(_pMasterBlock);
	    
	    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, nullVal));
		}		       
	    }
	    pExpr = exprList.Next();
	    pVar = argList.Next();
	}
	
	CegoOutput o;
	
	if ( _pDbHandle )
	{
	    o.setDbHandle(_pDbHandle);    
	}
	
	pProc->execute(exprList);
	
	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();	
    }
    catch ( Exception e)
    {

	CegoExpr** pExpr = exprList.First();
	while ( pExpr )
	{
	    delete *pExpr;
	    pExpr = exprList.Next();
	}
	exprList.Empty();	
	_pTabMng->getDBMng()->unuseObject(tabSetId, functionName, CegoObject::PROCEDURE, CegoDatabaseManager::SHARED);
	throw Exception(EXLOC, "Cannot execute function", e);
    }
    _pTabMng->getDBMng()->unuseObject(tabSetId, functionName, CegoObject::PROCEDURE, CegoDatabaseManager::SHARED);    
	
}

void CegoAction::execUserTableCreate() 
{
    	
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    
    _pTabMng->createDistDataTable(tableSet, tableName, CegoObject::TABLE, _fieldList, _idxList);
    
    Chain msg;
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    msg = Chain("Table ") + tableName + Chain(" created");
    
    o.chainOut(msg);
    
}

void CegoAction::execPrimaryIndexCreate() 
{
    
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(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->distObjectExists(tableSet, checkIndex, CegoObject::PINDEX) )
	{
	    throw Exception(EXLOC, Chain("Primary index already exists")); 
	}
    }
    else
    {
	indexName = tableName + Chain(TABMNG_PIDX_SUFFIX);
	idxType = CegoObject::PINDEX;

	Chain checkIndex = tableName + Chain(TABMNG_PBTREE_SUFFIX);
	if ( _pTabMng->distObjectExists(tableSet, checkIndex, CegoObject::PBTREE) )
	{
	    throw Exception(EXLOC, Chain("Primary btree already exists")); 
	}
    }
    
    ListT<CegoField> fieldList;
    _fieldListStack.Pop(fieldList);
    _pTabMng->createDistIndexTable(tableSet, indexName, tableName, fieldList, idxType);
    
    Chain msg;
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    msg = Chain("Primary index ") + indexName+ Chain(" created");
    
    o.chainOut(msg);
    
}

void CegoAction::execIndexCreate() 
{
    
    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::UINDEX;
	else
	    idxType = CegoObject::INDEX;
    }

    ListT<CegoField> fieldList;
    _fieldListStack.Pop(fieldList);
    _pTabMng->createDistIndexTable(tableSet, indexName, tableName, fieldList, idxType);
    
    
    Chain msg;
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);

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

    o.chainOut(msg);
    
}

void CegoAction::execTableDrop()
{

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


    bool doDrop=true;
    
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->distObjectExists(tableSet, tableName, CegoObject::TABLE) == false )
	    doDrop=false;
    }
    
    Chain msg;
    
    if ( doDrop )
    {
	_pTabMng->dropDistObject(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);
    
    o.chainOut(msg);
        
}

void CegoAction::execIndexDrop()
{

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


    bool doDrop=true;
    
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->distObjectExists(tableSet, indexName, CegoObject::INDEX) == false )
	{
	    doDrop=false;
	}
    }
    
    Chain msg;
    
    if ( doDrop )
    {    
	_pTabMng->dropDistObject(indexName, tableSet, CegoObject::INDEX);
	msg = Chain("Index ") + indexName + Chain(" dropped");
    }
    else
    {
	msg = Chain("Index ") + indexName + Chain(" does not exist");
    }
    
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    o.chainOut(msg);
    
}

void CegoAction::execProcDrop()
{
    
    Chain procName;
    Chain tableSet;
    
    _objNameStack.Pop(procName);
    _objTableSetStack.Pop(tableSet);

    bool doDrop=true;
    
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->distObjectExists(tableSet, procName, CegoObject::PROCEDURE) == false )
	    doDrop=false;
    }

    Chain msg;
    
    if ( doDrop )
    {
	int tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);
	
	_pTabMng->getDBMng()->useObject(tabSetId, procName, CegoObject::PROCEDURE, CegoDatabaseManager::EXCLUSIVE, _pTabMng->getThreadId());
	
	try
	{
	    
	    _pTabMng->dropDistObject(procName, tableSet, CegoObject::PROCEDURE);
	    
	    if ( _pDbPool )
	    {
		_pDbPool->invalidateObject(tabSetId, procName, CegoObject::PROCEDURE);
	    }
	    else
	    {
		_pTabMng->removeCompProcedure(tabSetId, procName);
	    }
	    msg = Chain("Procedure ") + procName + Chain(" dropped");

	}
	catch ( Exception e)
	{
	    _pTabMng->getDBMng()->unuseObject(tabSetId, procName, CegoObject::PROCEDURE, CegoDatabaseManager::EXCLUSIVE);
	    throw Exception(EXLOC, "Cannot drop procedure", e);
	}	
    }
    else
    {
	msg = Chain("Procedure ") + procName + Chain(" does not exist");
    }

    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    o.chainOut(msg);
    
}

void CegoAction::execFKeyDrop()
{

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


    bool doDrop=true;
    
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->distObjectExists(tableSet, keyName, CegoObject::FKEY) == false )
	    doDrop=false;
    }

    Chain msg;

    if ( doDrop )
    {
	_pTabMng->dropDistObject(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);
    
    o.chainOut(msg);
    
}

void CegoAction::execCheckDrop()
{

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


    bool doDrop=true;
    
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->distObjectExists(tableSet, checkName, CegoObject::CHECK) == false )
	    doDrop=false;
    }
    
    Chain msg;

    if ( doDrop )
    {    
	_pTabMng->dropDistObject(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);

    o.chainOut(msg);
    
}

void CegoAction::execBTreeDrop()
{

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


    bool doDrop=true;
    
    if ( _ifExistsOpt )
    {
	if ( _pTabMng->distObjectExists(tableSet, btreeName, CegoObject::BTREE) == false )
	    doDrop=false;
    }
    
    Chain msg;

    if ( doDrop )
    {    
	_pTabMng->dropDistObject(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);

    o.chainOut(msg);
    
}

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

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

void CegoAction::execForeignKeyCreate() 
{

    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->createDistForeignKey(tableSet, fkey, tableName, keyList, refTable, refList);
    
    
    Chain msg;
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    msg = Chain("Foreign Key ") + fkey + Chain(" created");
    
    o.chainOut(msg);
    
}

void CegoAction::execCheckCreate() 
{

    CegoCondDesc *pCondDesc;
    CegoPredDesc *pPredDesc;

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

    _condDescStack.Pop(pCondDesc);

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

    
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    
    _pTabMng->createDistCheck(tableSet, checkName, tableName, pPredDesc);
    
    Chain msg;
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle);
    
    msg = Chain("Check ") + checkName + Chain(" created");
    
    o.chainOut(msg);
    
}

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

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

	Chain msg;
	CegoOutput o;
	
	if ( _pDbHandle )
	    o.setDbHandle(_pDbHandle);
	
	msg = Chain("Value assigned");
	
	o.chainOut(msg);
	
    }
}

void CegoAction::execPrint()
{

    CegoExpr *pExpr;
    
    _exprStack.Pop(pExpr);    

    pExpr->setBlock(_pMasterBlock);
    CegoFieldValue fv = pExpr->evalFieldValue();

    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT);
    
    o.chainOut(fv.valAsChain());

}

// TODO : make distribution ready
void CegoAction::execIndexCheck()
{
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	
	Chain dump;
	Chain idxName = *pS;
	
	CegoObject::ObjectType type;
	
	if ( _pTabMng->distObjectExists(_tableSet, idxName, CegoObject::UINDEX))
	{
	    type = CegoObject::UINDEX;
	}
	else if ( _pTabMng->distObjectExists(_tableSet, idxName, CegoObject::PINDEX))
	{
	    type = CegoObject::PINDEX;
	}
	else if ( _pTabMng->distObjectExists(_tableSet, idxName, CegoObject::INDEX))
	{
	    type = CegoObject::INDEX;
	}
	else
	{
	    throw Exception(EXLOC, Chain("Index ") + idxName + Chain(" does not exist"));	    
	}
	
	CegoOutput o;
	if ( _pDbHandle )
	    o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT);
	
	CegoAVLIndexManager idxMng(_pTabMng);
	
	int tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);

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

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

// TODO : make distribution ready
void CegoAction::execCreateCounter()
{
    
    int tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
    long initValue = 0;
    _pTabMng->getDBMng()->addCounter(tabSetId, _counterName, initValue);
    
    CegoLogRecord lr;
    lr.setAction(CegoLogRecord::LOGREC_ADDCOUNTER);
    lr.setData(_counterName);
    lr.setDataLen(_counterName.length() + 1);
    _pTabMng->logIt(tabSetId, lr);
    
    
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT);
    
    Chain msg = Chain("Counter ") + _counterName + Chain(" created");
    o.chainOut(msg);

}

// TODO : make distribution ready
void CegoAction::execDropCounter()
{
    bool doDrop=true;
    
    int 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 )
    {
	_pTabMng->getDBMng()->removeCounter(tabSetId, _counterName);
	
	CegoLogRecord lr;
	lr.setAction(CegoLogRecord::LOGREC_DELCOUNTER);
	lr.setData(_counterName);
	lr.setDataLen(_counterName.length() + 1);
	_pTabMng->logIt(tabSetId, lr);
	
	msg = Chain("Counter ") + _counterName + Chain(" dropped");
    }
    else	    
    {
	msg = Chain("Counter ") + _counterName + Chain(" does not exist");
    }
    
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT);
    
    o.chainOut(msg);
    
}

// TODO : make distribution ready
void CegoAction::execSetCounter()
{

    int tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
    
    CegoExpr *pExpr;
    
    _exprStack.Pop(pExpr);    		
    pExpr->setBlock(_pMasterBlock);
    
    CegoFieldValue fv = pExpr->evalFieldValue();
    
    if ( fv.getType() != LONG_TYPE )
    {
	if ( fv.castTo(LONG_TYPE) == false )
	    throw Exception(EXLOC, Chain("Invalid value for counter"));
    }
    
    long *pVal = (long*)fv.getValue();
    
    _pTabMng->getDBMng()->setCounterValue(tabSetId, _counterName, *pVal);    
    
    Chain msg = Chain("Counter ") + _counterName + Chain(" set");
    
    CegoOutput o;
    
    if ( _pDbHandle )
	o.setDbHandle(_pDbHandle, NETMNG_MAXTUPLECOUNT);
    
    o.chainOut(msg);
    
}

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

/////////////////////////////////////////////////////////////////////////////////
/////////////////////////// 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);
    }
    _procContext = true;

}

void CegoAction::procStore()
{
    
    CegoProcBlock *pBlock;
    _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);
    }

    // set to default
    _procType = CegoProcedure::PROCEDURE;
    _procArgList.Empty();
    _procName = procName;
    _procTableSet = tableSet;
    
    _procContext = false;
}

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

void CegoAction::procArg1()
{
    Chain *pS;
    pS = getTokenList().First();
    pS = getTokenList().Next();
   
    if ( pS )
    {
	CegoFieldValue fv;
	_procArgList.Insert( CegoProcVar(*pS, CegoProcVar::INVAR, _dataType, _dataLen, fv ));
    } 
}

void CegoAction::procArg2()
{
    Chain *pS;
    pS = getTokenList().First();
    pS = getTokenList().Next();
   
    if ( pS )
    {
	CegoFieldValue fv;
	_procArgList.Insert( CegoProcVar(*pS, CegoProcVar::OUTVAR, _dataType, _dataLen, fv ));
    } 

}

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

void CegoAction::procVarStatement()
{

    Chain *pS;
    pS = getTokenList().First();
    
    if ( pS )
    {	
	CegoFieldValue fv;
	_pBlock->getVarList().Insert(CegoProcVar(*pS, CegoProcVar::BLOCKVAR, _dataType, _dataLen, fv));
    }

    if ( _initialAssignment )
    {
	CegoExpr *pExpr;
	_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);
    }
}

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;
	
	_exprStack.Pop(pExpr);    
	
	_pBlock->addStatement( new CegoProcAssignStmt(pS->cutTrailing(Chain(":")), pExpr, _pBlock) );
    }
}


void CegoAction::procAssign2NullStatement()
{
    CegoExpr *pExpr;    
    _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::procIfStatement()
{
    _pBlock->addStatement(new CegoProcIfStmt(*_pCondList, *_pIfBlockList, _pBlock));    
    
    delete _pCondList;
    delete _pIfBlockList;

    _condListStack.Pop(_pCondList);
    _ifBlockListStack.Pop(_pIfBlockList);   
}

void CegoAction::procStoreIfBlock()
{
    CegoProcBlock *pIfBlock;
    CegoProcCond *pCond;
    _blockStack.Pop(pIfBlock);
    _condStack.Pop(pCond);

    _pCondList->Insert(pCond);
    _pIfBlockList->Insert(pIfBlock);

    _blockStack.Pop(_pBlock);

}

void CegoAction::procStoreElseBlock()
{

    CegoProcBlock *pElseBlock, *parentBlock;
    _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*>;

    _condListStack.Push(_pCondList);
    _pCondList = new ListT<CegoProcCond*>;

}

void CegoAction::procElsIfCondition()
{

    CegoProcBlock* pParent = _pBlock;
    _blockStack.Push(_pBlock);
    _pBlock = new CegoProcBlock(pParent);

}

void CegoAction::procWhileStatement()
{
    
    CegoProcBlock *pWhileBlock;
    CegoProcCond *pCond;
    _blockStack.Pop(pWhileBlock);
    _condStack.Pop(pCond);

    _blockStack.Pop(_pBlock);

    _pBlock->addStatement(new CegoProcWhileStmt(pCond, pWhileBlock, _pBlock));

}

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


void CegoAction::procExceptionStatement()
{
    CegoProcBlock *pExceptionBlock;
    _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(INVALID_OBJECT_EXCEP_ID) )
	{
	    _exception = INVALID_OBJECT_EXCEP;
	}
	else if ( *pS == Chain(INVALID_ATTRIBUTE_EXCEP_ID) )
	{
	    _exception = INVALID_ATTRIBUTE_EXCEP;
	} 
	else if ( *pS == Chain(COREOP_EXCEP_ID) )
	{
	    _exception = COREOP_EXCEP;
	}
	else if ( *pS == Chain(ANY_EXCEP_ID) )
	{
	    _exception = ANY_EXCEP;
	}
	else
	{
	    _exception = OTHER_EXCEP;
	}
	    
	CegoProcBlock* pParent = _pBlock;
	_blockStack.Push(_pBlock);
	_pBlock = new CegoProcBlock(pParent);
    }
}


void CegoAction::procCondition1()
{
    CegoProcPred *pPred;
    _predStack.Pop(pPred);

    CegoProcCond *pCond;
    _condStack.Pop(pCond);

    CegoProcCond *pNewCond = new CegoProcCond(pCond, pPred, CegoProcCond::OR);
    _condStack.Push(pNewCond);

}

void CegoAction::procCondition2()
{
    CegoProcPred *pPred;
    _predStack.Pop(pPred);

    CegoProcCond *pCond;
    _condStack.Pop(pCond);

    CegoProcCond *pNewCond = new CegoProcCond(pCond, pPred, CegoProcCond::AND);
    _condStack.Push(pNewCond);

}

void CegoAction::procCondition3()
{
    CegoProcPred *pPred;
    _predStack.Pop(pPred);
    CegoProcCond *pCond = new CegoProcCond(pPred);
    _condStack.Push(pCond);

}

void CegoAction::procPredicate1()
{
    CegoProcCond *pCond;
    _condStack.Pop(pCond);

    _predStack.Push(new CegoProcPred(pCond));    

}

void CegoAction::procPredicate2()
{
    CegoExpr *pExpr2;
    _exprStack.Pop(pExpr2);

    CegoExpr *pExpr1;
    _exprStack.Pop(pExpr1);

    CegoComparison comp;
    _compStack.Pop(comp);

    _predStack.Push(new CegoProcPred(pExpr1, pExpr2, comp));

}

void CegoAction::procPredicate3()
{
    CegoExpr *pExpr1;
    _exprStack.Pop(pExpr1);
    _predStack.Push(new CegoProcPred(pExpr1, false));
}

void CegoAction::procPredicate4()
{
    CegoExpr *pExpr1;
    _exprStack.Pop(pExpr1);
    _predStack.Push(new CegoProcPred(pExpr1, true));
}

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

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

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

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

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

}

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

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

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

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

}

void CegoAction::procTerm3()
{
    CegoFactor *pFactor;
    _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;
    _attrDescStack.Pop(pAttrDesc);
    CegoFactor * pFac = new CegoFactor(pAttrDesc);
    _factorStack.Push(pFac);
}

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

void CegoAction::procFactor6()
{
    CegoExpr *pExpr;
    _exprStack.Pop(pExpr);
    _factorStack.Push(new CegoFactor(pExpr));   
}

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

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

void CegoAction::procFactor9()
{
    _factorStack.Push(new CegoFactor(new CegoAggregation()));
}

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

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

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

    _factorStack.Push(new CegoFactor(new CegoAggregation( CegoAggregation::AVG, pExpr)));
}

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

    _factorStack.Push(new CegoFactor(new CegoAggregation( CegoAggregation::COUNT, pExpr, _distinctOpt)));

    if ( _distinctOpt )
    {
	_pOrderingList = new ListT<CegoExpr*>;
	_pOrderingOptList = new ListT<CegoOrderNode::Ordering>;
	_pOrderingList->Insert(pExpr->clone());

	_pOrderingOptList->Insert(CegoOrderNode::ASC);

	_distinctAgg = true;
	_distinctStack.Push(true);
	_orderingClauseStack.Push(_pOrderingList);
	_orderingOptStack.Push(_pOrderingOptList);

	_pOrderingList = 0;
	_pOrderingOptList = 0;

    }
}

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

    _factorStack.Push(new CegoFactor(new CegoAggregation( CegoAggregation::MIN, pExpr)));
}

void CegoAction::procFactor14()
{
    CegoExpr* pExpr;
    _exprStack.Pop(pExpr);

    _factorStack.Push(new CegoFactor(new CegoAggregation( CegoAggregation::MAX, pExpr)));
}


void CegoAction::caseClause()
{
    CegoExpr *pExpr;
    _exprStack.Pop(pExpr);
    
    _pCaseCond->setElseExpr(pExpr);
    _caseCondStack.Push(_pCaseCond);
}

void CegoAction::caseConditionList1()
{
}

void CegoAction::caseConditionList2()
{
}

void CegoAction::caseCondition()
{
    CegoCondDesc *pCondDesc;
    CegoPredDesc *pPredDesc;
    CegoExpr *pExpr;

    _condDescStack.Pop(pCondDesc);

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

    _exprStack.Pop(pExpr);
    
    _pCaseCond->addPred(pPredDesc, pExpr);
}

void CegoAction::casePrepare()
{
    _pCaseCond = new CegoCaseCond();
}

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;
    _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;
    _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;
    _exprStack.Pop(pExpr);    
    _exprList.Insert(pExpr);    
}    


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

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

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

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

void CegoAction::setPrimaryColumn() 
{

    if ( _defaultValue.castTo(_dataType) == 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, _defaultValue, _isNullable));
    _idxList.Insert(CegoField(Chain(), Chain(), _fieldName, _dataType, _dataLen));
}

void CegoAction::setOrdinaryColumn() 
{
    if ( _defaultValue.castTo(_dataType) == 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, _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::insertStore() 
{

    Chain tableName;
    Chain tableSet;
        
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    // _exprListStack.Pop(exprList);

    if ( _procContext == true )
    {
	_pQuery = new CegoQuery(_pTabMng, tableName, tableSet, _fal, _exprListArray);
	_fal.Empty();
	_exprListArray.Empty();
    }
}

void CegoAction::insertPrepare() 
{
}

void CegoAction::insertBySelectStore() 
{

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

    _pQuery = new CegoQuery(_pTabMng, tableName, tableSet, _fal, _pSelect);
    _fal.Empty();
    _pSelect = 0;
    
    if ( _procContext == false )
    {
	execQuery();
    }
}

void CegoAction::insertArg() 
{
    
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	CegoField f;
	f.setAttrName(*pS);
	_fal.Insert(f);
    }
}    

void CegoAction::insertValueSpecStoreExecute() 
{

    _exprListArray.Insert(_exprList);
    _exprList.Empty();
	
    if ( _procContext == false )
    {

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

	_pQuery = new CegoQuery(_pTabMng, tableName, tableSet, _fal, _exprListArray);
	_fal.Empty();
	_exprListArray.Empty();

	execQuery();

	// provide object info for next call
	_objNameStack.Push(tableName);
	_objTableSetStack.Push(tableSet);
	
    }
}    

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


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

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

void CegoAction::selectStore()
{
    CegoPredDesc *pPredDesc; 
    _predDescStack.Pop(pPredDesc);
    
    ListT<CegoExpr*> exprList;
    _exprListStack.Pop(exprList);
    
    ListT<CegoContentObject*> coList;
    _coListStack.Pop(coList);
    
    ListT<CegoAttrDesc*>* pGroupList;
    _groupClauseStack.Pop(pGroupList);
    
    ListT<CegoExpr*>* pOrderingList;
    _orderingClauseStack.Pop(pOrderingList);

    ListT<CegoOrderNode::Ordering>* pOrderingOptList;
    _orderingOptStack.Pop(pOrderingOptList);

    CegoHavingDesc *pHavingDesc;
    _havingDescStack.Pop(pHavingDesc);
    
    bool isDistinct;
    _distinctStack.Pop(isDistinct);
        
    int rowLimit;
    _limitStack.Pop(rowLimit);
    
    _pSelect = new CegoSelect(coList, exprList, pPredDesc, pGroupList, pHavingDesc,  pOrderingList, pOrderingOptList, isDistinct, rowLimit, _pTabMng);

    int tabSetId = _pTabMng->getDBMng()->getTabSetId(_tableSet);
    _pSelect->setTabSetId(tabSetId);

    _distinctAgg = false;

    CegoSelect *pUnion = 0;
    if ( _unionStack.isEmpty() == false )
    {
	_unionStack.Pop(pUnion);
	_pSelect->setUnionSelect(pUnion);
    }

}

void CegoAction::selectSelectionStore1() 
{
    if ( _distinctOpt ) 
	_distinctStack.Push(true);
    else
	_distinctStack.Push(false);
    _distinctOpt = false;

}

void CegoAction::selectSelectionStore2()
{
    _distinctStack.Push(false);

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

}

void CegoAction::selectItem() 
{

}

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

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

void CegoAction::selectionList2()
{
    CegoExpr *pExpr;
    _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::selectInnerJoinStore() 
{

    _coListStack.Pop(_coList);

    CegoCondDesc *pCondDesc;
    _condDescStack.Pop(pCondDesc);

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

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

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

    
}

void CegoAction::selectLeftOuterJoinStore() 
{

    _coListStack.Pop(_coList);

    CegoCondDesc *pCondDesc;
    _condDescStack.Pop(pCondDesc);

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

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

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

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


}

void CegoAction::selectRightOuterJoinStore() 
{

    _coListStack.Pop(_coList);

    CegoCondDesc *pCondDesc;
    _condDescStack.Pop(pCondDesc);

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

    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);

    _aliasCount++;
    Chain tableAlias = tableName; //  + Chain("_") + Chain(_aliasCount);
    
    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->getDistObject(tableSet, sysTable, CegoObject::SYSTEM, *pTO);    
	
	pTO->setName(sysTable);		
	_coList.Insert(pTO);
       	
    }
    else if ( _pTabMng->distObjectExists(tableSet, tableName, CegoObject::VIEW) )
    {
	// if view exists, make sure view is compiled
	int tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet); 
	
	try
	{
	    _pTabMng->getDBMng()->useObject(tabSetId, tableName, CegoObject::VIEW, CegoDatabaseManager::SHARED, _pTabMng->getThreadId());
	    CegoView* pView = _pTabMng->getView(tabSetId, tableName);
	}
	catch ( Exception e )
	{
	    _pTabMng->getDBMng()->unuseObject(tabSetId, tableName, CegoObject::VIEW, CegoDatabaseManager::SHARED);
	    throw e;
	}
	_pTabMng->getDBMng()->unuseObject(tabSetId, tableName, CegoObject::VIEW, CegoDatabaseManager::SHARED);

	CegoViewObject *pVO = new CegoViewObject();
	_pTabMng->getDistObject(tableSet, tableName, CegoObject::VIEW, *pVO);    

	pVO->setName(tableAlias);
	_coList.Insert(pVO);
    }
    else if ( _pTabMng->distObjectExists(tableSet, tableName, CegoObject::TABLE) )
    {
	CegoTableObject *pTO = new CegoTableObject();
	_pTabMng->getDistObject(tableSet, tableName, CegoObject::TABLE, *pTO);
	pTO->setName(tableAlias);
	_coList.Insert(pTO);
    }
    else
    {	
	// we create a dummy table object. This is useful for view creation with 
	// still undefined sub objects
	CegoTableObject *pCO = new CegoTableObject();
	pCO->setType(CegoObject::UNDEFINED);
	pCO->setTabName(tableName);
	pCO->setTableSet(tableSet);
	pCO->setName(tableAlias);
	pCO->setTabAlias(tableAlias);
	_coList.Insert(pCO);
    }
}

void CegoAction::selectTable2() 
{
        
    Chain tableAlias;
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    
    Chain* pS = getTokenList().First();
    if ( pS )
    {
	tableAlias = *pS;
    }
    
    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->getDistObject(tableSet, sysTable, CegoObject::SYSTEM, *pTO);    
	pTO->setTabAlias(tableAlias);
	pTO->setName(tableAlias);				
	_coList.Insert(pTO);       	
    }
    else if ( _pTabMng->distObjectExists(tableSet, tableName, CegoObject::VIEW) )
    {
	// if view exists, make sure view is compiled
	int tabSetId = _pTabMng->getDBMng()->getTabSetId(tableSet);

	try
	{
	    _pTabMng->getDBMng()->useObject(tabSetId, tableName, CegoObject::VIEW, CegoDatabaseManager::SHARED, _pTabMng->getThreadId());
	    CegoView* pView = _pTabMng->getView(tabSetId, tableName);
	}
	catch ( Exception e )
	{
	    _pTabMng->getDBMng()->unuseObject(tabSetId, tableName, CegoObject::VIEW, CegoDatabaseManager::SHARED);
	    throw e;
	}
	_pTabMng->getDBMng()->unuseObject(tabSetId, tableName, CegoObject::VIEW, CegoDatabaseManager::SHARED);

	CegoViewObject *pVO = new CegoViewObject();
	_pTabMng->getDistObject(tableSet, tableName, CegoObject::VIEW, *pVO);    
	pVO->setTabAlias(tableAlias);
	pVO->setName(tableAlias);
	_coList.Insert(pVO);
    }
    else if ( _pTabMng->distObjectExists(tableSet, tableName, CegoObject::TABLE) )
    {
	CegoTableObject *pTO = new CegoTableObject();
	_pTabMng->getDistObject(tableSet, tableName, CegoObject::TABLE, *pTO);    
	pTO->setName(tableAlias);
	pTO->setTabAlias(tableAlias);
	_coList.Insert(pTO);
    }
    else
    {	
	// we create a dummy table object. This is useful for view creation with 
	// still undefined sub objects

	CegoTableObject *pCO = new CegoTableObject();
	pCO->setType(CegoObject::UNDEFINED);
	pCO->setTabName(tableName);
	pCO->setTableSet(tableSet);
	pCO->setName(tableAlias);
	pCO->setTabAlias(tableAlias);
	_coList.Insert(pCO);
    }    
}

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


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

void CegoAction::noAliasOpt()
{
    CegoExpr *pExpr;
    _exprStack.Pop(pExpr);
    
    CegoAttrDesc* pAttrDesc = pExpr->checkAttr();
    if ( pAttrDesc )
    {
	if ( pAttrDesc->getAttrName() != Chain(SELECTION_WILDCARD))
	{
	    // cout << "Setting alias " << f.getAttrName() << endl;
	    pExpr->setAlias(pAttrDesc->getAttrName());
	}
    }
    _exprStack.Push(pExpr);   
}

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

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

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

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

void CegoAction::selectHavingClause()
{
    
    CegoExpr* pExpr;
    CegoExpr* pAggExpr;

    _exprStack.Pop(pExpr);
    _exprStack.Pop(pAggExpr);
    
    CegoComparison comp;
    _compStack.Pop(comp);
    CegoHavingDesc* pP = new CegoHavingDesc(pAggExpr, pExpr, comp);

    _havingDescStack.Push(pP);

}

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

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

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

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

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

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

    // at default, ordering is asc 
}

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

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

void CegoAction::selectDistinctOpt()
{
    _distinctOpt = true;
}

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

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

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

void CegoAction::updateStore() 
{

    CegoPredDesc *pPredDesc;
    _predDescStack.Pop(pPredDesc);
    
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    
    if ( _updDelAlias == Chain() )
	_updDelAlias = tableName;
    
    _pQuery = new CegoQuery(_pTabMng, tableName, _updDelAlias, tableSet, pPredDesc, _fal, _exprList, _returnVarList);   

    _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;
	_exprStack.Pop(pExpr);
	_exprList.Insert(pExpr);    
 
   } 
}    

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

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


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

void CegoAction::deleteStore() 
{    

    CegoPredDesc *pPredDesc;
    _predDescStack.Pop(pPredDesc);
    
    Chain tableName;
    Chain tableSet;
    
    _objNameStack.Pop(tableName);
    _objTableSetStack.Pop(tableSet);
    
    if ( _updDelAlias == Chain() )
	_updDelAlias = tableName;

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

    _updDelAlias = Chain();
    
}

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

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

void CegoAction::alterAddCol()
{
    Chain n;
    CegoField f(n, n, _fieldName, _dataType, _dataLen, _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()
{
    Chain n;
    CegoField f(n, n, _fieldName, _dataType, _dataLen, _defaultValue, _isNullable);
    _alterList.Insert(CegoAlterDesc(CegoAlterDesc::MODIFY, f));		      

}

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::INDEX, newIdxName);
}

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);
}




/////////////////////////////////////////////////////////////////////////////////
/////////////////////////// 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("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("date2str") )
    {
	pFunc = new CegoFunction(CegoFunction::DATE2STR);	
    }
    else if ( functionName.toLower() == Chain("date2int") )
    {
	pFunc = new CegoFunction(CegoFunction::DATE2INT);	
    }
    else if ( functionName.toLower() == Chain("int2date") )
    {
	pFunc = new CegoFunction(CegoFunction::INT2DATE);	
    }
    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("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("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
    {
	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;	

	int 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;	

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

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

	CegoExpr *pExpr;	
	_exprStack.Pop(pExpr);    

	pFunc->setCounterExpr(pExpr);
    }
    
}

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

    int 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);

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

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

void CegoAction::functionExprList1()
{
    CegoExpr *pExpr;
    _exprStack.Pop(pExpr);

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

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


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

void CegoAction::wcWhereClause() 
{

    CegoCondDesc *pCondDesc;
    _condDescStack.Pop(pCondDesc);

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

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

void CegoAction::wcConditionAnd() 
{
    
    CegoCondDesc* pAndCondDesc = new CegoCondDesc(CegoCondDesc::AND);

    CegoCondDesc *pCondDesc;
    CegoPredDesc *pPredDesc;
    _condDescStack.Pop(pCondDesc);
    _predDescStack.Pop(pPredDesc);

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

    _condDescStack.Push(pAndCondDesc);

}

void CegoAction::wcConditionOr() 
{

    CegoCondDesc* pOrCondDesc = new CegoCondDesc(CegoCondDesc::OR);

    CegoCondDesc *pCondDesc;
    CegoPredDesc *pPredDesc;
    _condDescStack.Pop(pCondDesc);
    _predDescStack.Pop(pPredDesc);
    
    if ( pCondDesc->getCondType() == CegoCondDesc::PRED )
    {
	pOrCondDesc->setLeft(pCondDesc->Left());
	pCondDesc->setLeft(0);
	delete pCondDesc;
    }
    else
    {
	pOrCondDesc->setLeft(new CegoPredDesc(pCondDesc));
    }
    pOrCondDesc->setRight(pPredDesc);

    _condDescStack.Push(pOrCondDesc);
}

void CegoAction::wcConditionPredicate() 
{
    CegoCondDesc* pCondDesc = new CegoCondDesc(CegoCondDesc::PRED);

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


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

    CegoExpr *pExpr;
    _exprStack.Pop(pExpr);
    
    if ( _queryCacheEnabled )
	_pSelect->enableCache();
    else
	_pSelect->disableCache();
	    
    CegoPredDesc* pP = new CegoPredDesc(pExpr, _pSelect, true);
    _predDescStack.Push(pP);

}

void CegoAction::wcPredicateQueryNotIn()  
{
    CegoExpr *pExpr;
    _exprStack.Pop(pExpr);
    
    if ( _queryCacheEnabled )
	_pSelect->enableCache();
    else
	_pSelect->disableCache();
	    
    CegoPredDesc* pP = new CegoPredDesc(pExpr, _pSelect, false);
    _predDescStack.Push(pP);

}

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

    CegoExpr *pExpr2;
    _exprStack.Pop(pExpr2);

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

    _predDescStack.Push(pP);
}

void CegoAction::wcPredicateBetween() 
{

    CegoExpr *pExpr1;
    _exprStack.Pop(pExpr1);

    CegoExpr *pExpr2;
    _exprStack.Pop(pExpr2);

    CegoExpr *pExpr3;
    _exprStack.Pop(pExpr3);

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

    _predDescStack.Push(pP);
}

void CegoAction::wcPredicateNullComp() 
{

    CegoExpr *pExpr;
    _exprStack.Pop(pExpr);
    
    CegoPredDesc* pP = new CegoPredDesc(pExpr, true);

    _predDescStack.Push(pP);

}

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


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

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


void CegoAction::wcPredicateCondition() 
{
    CegoCondDesc* pCondDesc;
    _condDescStack.Pop(pCondDesc);
    if ( pCondDesc->getCondType() == CegoCondDesc::PRED )
    {
	_predDescStack.Push(pCondDesc->Left());
	pCondDesc->setLeft(0);
	delete pCondDesc;
    }
    else
    {
	CegoPredDesc* pP = new CegoPredDesc(pCondDesc);
	_predDescStack.Push(pP);
    }
}

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

}

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

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

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

void CegoAction::miscStringType() 
{
    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    if ( pS )
    {    
	_dataType = VARCHAR_TYPE;
	_dataLen = pS->asInteger();
    }
}

void CegoAction::miscDateTimeType() 
{
    _dataType = DATETIME_TYPE;
    _dataLen = sizeof(int);
}

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


void CegoAction::miscBigIntType()
{
    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    if ( pS )
    {    
	_dataType = BIGINT_TYPE;
	_dataLen = pS->asInteger();
    }
}

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

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

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

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

void CegoAction::miscDecimalType()
{
    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    if ( pS )
    {    
	_dataType = DECIMAL_TYPE;
	_dataLen = pS->asInteger();
    }
}

void CegoAction::miscFixedType()
{
    Chain* pS = getTokenList().First();
    pS = getTokenList().Next();
    if ( pS )
    {    
	_dataType = FIXED_TYPE;
	_dataLen = pS->asInteger();
    }
}

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

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("*");
    
    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::miscFixedValue()
{
    CegoFieldValue fv(FIXED_TYPE, _floatString);   
    _fieldValue = fv;    
}

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

void CegoAction::miscSysDate()
{
    int *pI = new (int);

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

    *pI = 0; 

    CegoFieldValue fv(DATETIME_TYPE, pI, sizeof(int), true);

    _fieldValue = fv;
}

void CegoAction::miscFormatDate()
{
    int *pI = new (int);

    Datetime dt(_dateValue, _dateFormat);
    *pI = dt.asInt();

    CegoFieldValue fv(DATETIME_TYPE, pI, sizeof(int), true);

    _fieldValue = fv;
}

void CegoAction::miscDateFormat()
{
    _dateFormat = Chain(_stringBuf);
}

void CegoAction::miscDateValue()
{
    _dateValue = Chain(_stringBuf);
}

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 fstr;
    Chain pstr;

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

    Chain blobRef = Chain("[") + fstr + Chain(",") + pstr + Chain("]");
    CegoFieldValue fv(BLOB_TYPE, blobRef);
    _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 ( 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 ( 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, int indent)
{

    /*
    XMLSuite xs;
    xs.setDocument(new Document(pPlan));

    Chain xml;
    xs.getXMLChain(xml);
    
    cout << xml << endl;
    */

    Chain planString;

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

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

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

    ListT<Element*> joinList = pPlan->getChildren(XML_JOIN_ELEMENT);
    
    Element **pJoinElement = joinList.First();
    while ( pJoinElement )
    {

	Chain tableName = (*pJoinElement)->getAttributeValue(XML_TABLENAME_ATTR);
	Chain aliasName = (*pJoinElement)->getAttributeValue(XML_NAME_ATTR);
	Chain tableType = (*pJoinElement)->getAttributeValue(XML_TABLETYPE_ATTR);

	/*
	for ( int i=0; i<indent; i++ )
	planString += " ";
	*/

	planString += getJoinPlanString(*pJoinElement, Chain("Join plan for ") + aliasName, indent + 2);
	
	pJoinElement = joinList.Next();

    }

    return planString;

}

Chain CegoAction::getJoinPlanString(Element *pJoin, const Chain& title, int indent)
{

    Chain planString;
    
    Chain tableName = pJoin->getAttributeValue(XML_TABLENAME_ATTR);
    Chain aliasName = pJoin->getAttributeValue(XML_NAME_ATTR);
    Chain tableType = pJoin->getAttributeValue(XML_TABLETYPE_ATTR);
    
    if ( tableType == Chain(XML_TABLE_VALUE) )
    {
	Chain joinStrat = pJoin->getAttributeValue(XML_JOINSTRAT_ATTR);
	for ( int i=0; i<indent; i++ )
	    planString += Chain(" ");
	planString += Chain("Joining table ") + tableName + Chain(" (") + aliasName + Chain(") with ") + joinStrat + Chain("\n");
    }
    else if ( tableType == Chain(XML_VIEW_VALUE) )
    {
	for ( int 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("View 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 ( int i=0; i<indent; i++ )
	    planString += Chain(" ");
	
	Chain joinType;
	if ( tableType == Chain(XML_INNERJOIN_VALUE) )
	    joinType = Chain("Inner join");
	else if ( tableType == Chain(XML_LEFTOUTERJOIN_VALUE) )
	    joinType = Chain("Left outer join");
	else if ( tableType == Chain(XML_RIGHTOUTERJOIN_VALUE) )
	    joinType = Chain("Right outer join");

	planString += joinType + Chain(" ") + tableName + Chain(" (") + aliasName + 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,
				 CegoTableObject& oe,
				 ListT< ListT<CegoFieldValue> > &fa)
{   

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

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

    ListT<CegoFieldValue> fv;
    
    fv.Insert(CegoFieldValue(VARCHAR_TYPE, tableName));	
    fv.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("table")));
       
    int pageCount = _pTabMng->getDistPageCount(tableSet, tableName, CegoObject::TABLE);
		
    fv.Insert(CegoFieldValue(INT_TYPE, Chain(pageCount)));
    fa.Insert(fv);

    CegoTableObject *pOE = idxList.First();
    while ( pOE )
    {
    
	ListT<CegoFieldValue> fv1;
    
	fv1.Insert(CegoFieldValue(VARCHAR_TYPE, pOE->getName()));
	
	switch ( pOE->getType() )
	{
	case CegoObject::INDEX:
	    fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("index")));
	    break;
	case CegoObject::UINDEX:
	    fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("unique index")));
	    break;
	case CegoObject::PINDEX:
	    fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("primary index")));
	    break;
	default:	    
	    Chain msg = Chain("Invalid object type for format" );
	    throw Exception(EXLOC, msg);	    
	}

	if ( pOE->isValid() )
	{
	    int pageCount = _pTabMng->getDistPageCount(tableSet, pOE->getName(), pOE->getType());	
	    fv1.Insert(CegoFieldValue(INT_TYPE, Chain(pageCount)));
	}
	else
	{
	    fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("INVALID")));
	}

	fa.Insert(fv1);

	pOE = idxList.Next();

    }

    CegoBTreeObject *pBTO = btreeList.First();
    while ( pBTO )
    {
    
	ListT<CegoFieldValue> fv1;
    
	fv1.Insert(CegoFieldValue(VARCHAR_TYPE, pBTO->getName()));
	
	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;
	default:	    
	    Chain msg = Chain("Invalid object type for format" );
	    throw Exception(EXLOC, msg);	    
	}

	if ( pBTO->isValid() )
	{
	    int pageCount = _pTabMng->getDistPageCount(tableSet, pBTO->getName(), pBTO->getType());	
	    fv1.Insert(CegoFieldValue(INT_TYPE, Chain(pageCount)));
	}
	else
	{
	    fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("INVALID")));
	}

	fa.Insert(fv1);

	pBTO = btreeList.Next();

    }


    CegoCheckObject *pCE = checkList.First();
    while ( pCE )
    {
    
	ListT<CegoFieldValue> fv1;
    
	fv1.Insert(CegoFieldValue(VARCHAR_TYPE, pCE->getName()));
	
	switch ( pCE->getType() )
	{
	case CegoObject::CHECK:
	    fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("check")));
	    break;
	default:
	    fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("unknwon")));
	    break;
	}
		
	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()));
	
	switch ( pKE->getType() )
	{
	case CegoObject::FKEY:
	    fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("foreign key")));
	    break;
	default:
	    fv1.Insert(CegoFieldValue(VARCHAR_TYPE, Chain("unknwon")));
	    break;
	}
		
	fv1.Insert(CegoFieldValue(INT_TYPE, Chain(0)));
	fa.Insert(fv1);
	pKE = keyList.Next();
    }
}
