Esempio n. 1
0
ConstantFilter::ConstantFilter(const SOP& op, ReturnedColumn* lhs, ReturnedColumn* rhs)
{
    SSFP ssfp(new SimpleFilter(op, lhs, rhs));
    fFilterList.push_back(ssfp);
    SimpleColumn* sc = dynamic_cast<SimpleColumn*>(lhs);
    fCol.reset(sc->clone());
}
Esempio n. 2
0
void SimpleFilter::replaceRealCol(CalpontSelectExecutionPlan::ReturnedColumnList& derivedColList)
{
	SimpleColumn *sc = NULL;
	if (fLhs)
	{
		sc = dynamic_cast<SimpleColumn*>(fLhs);
		if (sc)
		{
			ReturnedColumn* tmp = derivedColList[sc->colPosition()]->clone();
			delete fLhs;
			fLhs = tmp;
		}
		else
		{
			fLhs->replaceRealCol(derivedColList);
		}
	}
	if (fRhs)
	{
		sc = dynamic_cast<SimpleColumn*>(fRhs);
		if (sc)
		{
			ReturnedColumn* tmp = derivedColList[sc->colPosition()]->clone();
			delete fRhs;
			fRhs = tmp;
		}
		else
		{
			fRhs->replaceRealCol(derivedColList);
		}
	}
}
void FunctionColumn::setDerivedTable()
{
    if (hasAggregate())
    {
        fDerivedTable = "";
        return;
    }

    setSimpleColumnList();
    string derivedTableAlias = "";

    for (uint32_t i = 0; i < fSimpleColumnList.size(); i++)
    {
        SimpleColumn* sc = fSimpleColumnList[i];
        sc->setDerivedTable();

        if (sc->derivedTable() != derivedTableAlias)
        {
            if (derivedTableAlias == "")
            {
                derivedTableAlias = sc->tableName();
            }
            else
            {
                derivedTableAlias = "";
                break;
            }
        }
    }

    fDerivedTable = derivedTableAlias;
}
Esempio n. 4
0
SimpleColumn::SimpleColumn (const SimpleColumn& rhs,const uint32_t sessionID):
				ReturnedColumn(rhs, sessionID),
				fSchemaName (rhs.schemaName()),
				fTableName (rhs.tableName()),
				fColumnName (rhs.columnName()),
				fOid (rhs.oid()),
				fTableAlias (rhs.tableAlias()),
				fData (rhs.data()),
				fIndexName (rhs.indexName()),
				fViewName (rhs.viewName()),
				fIsInfiniDB (rhs.isInfiniDB())
{
}
Esempio n. 5
0
void SimpleColumn::setOID()
{
	boost::shared_ptr<CalpontSystemCatalog> csc = CalpontSystemCatalog::makeCalpontSystemCatalog(fSessionID);
	CalpontSystemCatalog::TableColName tcn;
	tcn = make_tcn(fSchemaName, fTableName, fColumnName);

	fOid = csc->lookupOID (tcn);
	if (fOid == -1)
	{
		// get colMap from CalpontSelectExecutionPlan
		// and try to map the schema and table name
		CalpontSelectExecutionPlan::ColumnMap::iterator iter;
		CalpontSelectExecutionPlan::ColumnMap colMap = CalpontSelectExecutionPlan::colMap();

		// if this is the only column name exist in the map, return it ??
		for (iter = colMap.find(fColumnName); iter != colMap.end(); ++iter)
		{
			SRCP srcp = iter->second;
			SimpleColumn* scp = dynamic_cast<SimpleColumn*>(srcp.get());
			if (colMap.count(fColumnName) == 1 ||
			    scp->tableName().compare(fTableName) == 0)
			{
				fOid = scp->oid();
				//@bug 221 fix
				fTableName = scp->tableName();
				fSchemaName = scp->schemaName();
				//@info assign tableAlias also. watch for other conflict
				fTableAlias = scp->tableAlias();
				fResultType = scp->resultType();
				return;
			}
		}
	}
	fResultType = csc->colType(fOid);
}
Esempio n. 6
0
void* ing_opentbl(void* qctx, const char* sn, const char* tn)
{
try {
	if (!qctx) return 0;
	if (!sn) return 0;
	if (!tn) return 0;
	if (strlen(sn) == 0) return 0;
	if (strlen(tn) == 0) return 0;

	IngQCtx* ingQctx = reinterpret_cast<IngQCtx*>(qctx);
	cpsm_conhdl_t* cal_conn_hndl = reinterpret_cast<cpsm_conhdl_t*>(ingQctx->dhcs_ses_ctx);
	IngTCtx* tctx = new IngTCtx();

	dhcs_tableid_t tableid = 0;
	//tableid = tbname2id(sn, tn, cal_conn_hndl);
	tableid = tbname2id("te", "f_trans", cal_conn_hndl);

	RequiredColOidSet requiredColOidSet;
	const CalpontSelectExecutionPlan::ColumnMap colMap = ingQctx->csep.columnMap();
	CalpontSelectExecutionPlan::ColumnMap::const_iterator colIter = colMap.begin();
	CalpontSelectExecutionPlan::ColumnMap::const_iterator colend = colMap.end();
	while (colIter != colend)
	{
		SRCP srcp = colIter->second;
		SimpleColumn* scp = dynamic_cast<SimpleColumn*>(srcp.get());
		if (scp)
			requiredColOidSet.insert(scp->oid());
		++colIter;
	}
	tctx->dhcs_tpl_ctx = new cpsm_tplh_t();
	dhcs_tpl_open(tableid, &tctx->dhcs_tpl_ctx, ingQctx->dhcs_ses_ctx, requiredColOidSet);
	tctx->dhcs_tpl_scan_ctx = new cpsm_tplsch_t();
	dhcs_tpl_scan_open(tableid, DHCS_TPL_FH_READ, &tctx->dhcs_tpl_scan_ctx, ingQctx->dhcs_ses_ctx);

	return tctx;
} catch (...) {
}
	return NULL;
}
Esempio n. 7
0
ParseTree* replaceRefCol(ParseTree*& n, CalpontSelectExecutionPlan::ReturnedColumnList& derivedColList)
{
	ParseTree *lhs = n->left();
	ParseTree *rhs = n->right();

	if (lhs)
		n->left(replaceRefCol(lhs, derivedColList));
	if (rhs)
		n->right(replaceRefCol(rhs, derivedColList));
	SimpleFilter *sf = dynamic_cast<SimpleFilter*>(n->data());
	ConstantFilter *cf = dynamic_cast<ConstantFilter*>(n->data());
	ReturnedColumn *rc = dynamic_cast<ReturnedColumn*>(n->data());
	if (sf)
	{
		sf->replaceRealCol(derivedColList);
	}
	else if (cf)
	{
		cf->replaceRealCol(derivedColList);
	}
	else if (rc)
	{
		SimpleColumn* sc = dynamic_cast<SimpleColumn*>(rc);
		if (sc)
		{
			ReturnedColumn* tmp = derivedColList[sc->colPosition()]->clone();
			delete sc;
			n->data(tmp);
		}
		else
		{
			rc->replaceRealCol(derivedColList);
		}
	}
	return n;
}
Esempio n. 8
0
SimpleFilter* createSimpleFilter
				(
				CalpontSystemCatalog*& csc,
				const CalpontSystemCatalog::TableColName& tcn,
				const string& opstr,
				ConstantColumn* cc
				)
{
	SimpleFilter* lsf = new SimpleFilter();

	Operator* op = new Operator();
	op->data(opstr);
	CalpontSystemCatalog::ColType ccct;
	ccct = op->resultType();
	ccct.colDataType = cc->resultType().colDataType;
	op->operationType(ccct);

	SOP sop(op);
	lsf->op(sop);

	CalpontSystemCatalog::OID oid = csc->lookupOID(tcn);
	CalpontSystemCatalog::ColType ct = csc->colType(oid);

	SimpleColumn* sc = new SimpleColumn();
	sc->schemaName(tcn.schema);
	sc->tableName(tcn.table);
	sc->tableAlias(tcn.table);
	sc->columnName(tcn.column);
	sc->oid(oid);
	sc->resultType(ct);
	sc->alias(tcn.toString());

	lsf->lhs(sc);
	lsf->rhs(cc);

	return lsf;
}
Esempio n. 9
0
	void verifyParseTree(const ParseTree* t)
	{
		const ParseTree *ct, *ct2;
		SimpleColumn *s;
		
		CPPUNIT_ASSERT(t != NULL);
		s = dynamic_cast<SimpleColumn*>(t->data());
		CPPUNIT_ASSERT(s != NULL);
		CPPUNIT_ASSERT(s->schemaName() == "Schema Name 0");
		ct = t->left();
		CPPUNIT_ASSERT(ct != NULL);
		s = dynamic_cast<SimpleColumn*>(ct->data());
		CPPUNIT_ASSERT(s != NULL);
		CPPUNIT_ASSERT(s->schemaName() == "Schema Name 1");
		ct2 = ct->left();
		CPPUNIT_ASSERT(ct2 != NULL);
		s = dynamic_cast<SimpleColumn*>(ct2->data());
		CPPUNIT_ASSERT(s != NULL);
		CPPUNIT_ASSERT(s->schemaName() == "Schema Name 3");
		CPPUNIT_ASSERT(ct->right() == NULL);
		CPPUNIT_ASSERT(ct2->left() == NULL);
		CPPUNIT_ASSERT(ct2->right() == NULL);
		ct = t->right();
		CPPUNIT_ASSERT(ct != NULL);
		s = dynamic_cast<SimpleColumn*>(ct->data());
		CPPUNIT_ASSERT(s != NULL);
		CPPUNIT_ASSERT(s->schemaName() == "Schema Name 2");
		ct2 = ct->right();
		CPPUNIT_ASSERT(ct2 != NULL);
		s = dynamic_cast<SimpleColumn*>(ct2->data());
		CPPUNIT_ASSERT(s != NULL);
		CPPUNIT_ASSERT(s->schemaName() == "Schema Name 4");
		CPPUNIT_ASSERT(ct->left() == NULL);
		CPPUNIT_ASSERT(ct2->left() == NULL);
		CPPUNIT_ASSERT(ct2->right() == NULL);
	}
execplan::ParseTree* ScalarSub::buildParseTree(PredicateOperator* op)
{
    idbassert(fColumn.get() && fSub && fFunc);

    vector<SRCP> cols;
    Filter* filter;
    RowColumn* rcol = dynamic_cast<RowColumn*>(fColumn.get());

    if (rcol)
    {
        // IDB only supports (c1,c2..) =/!= (subquery)
        if (fFunc->functype() != Item_func::EQ_FUNC && fFunc->functype() != Item_func::NE_FUNC)
        {
            fGwip.fatalParseError = true;
            fGwip.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_INVALID_OPERATOR_WITH_LIST);
            return NULL;
        }

        cols = rcol->columnVec();
    }
    else
        cols.push_back(fColumn);

    SCSEP csep(new CalpontSelectExecutionPlan());
    csep->sessionID(fGwip.sessionid);
    csep->location(CalpontSelectExecutionPlan::WHERE);
    csep->subType (CalpontSelectExecutionPlan::SINGLEROW_SUBS);

    // gwi for the sub query
    gp_walk_info gwi;
    gwi.thd = fGwip.thd;
    gwi.subQuery = this;

    // @4827 merge table list to gwi in case there is FROM sub to be referenced
    // in the FROM sub
    gwi.derivedTbCnt = fGwip.derivedTbList.size();
    uint32_t tbCnt = fGwip.tbList.size();

    gwi.tbList.insert(gwi.tbList.begin(), fGwip.tbList.begin(), fGwip.tbList.end());
    gwi.derivedTbList.insert(gwi.derivedTbList.begin(), fGwip.derivedTbList.begin(), fGwip.derivedTbList.end());

    if (getSelectPlan(gwi, *(fSub->get_select_lex()), csep) != 0)
    {
        //@todo more in error handling
        if (!gwi.fatalParseError)
        {
            fGwip.fatalParseError = true;
            fGwip.parseErrorText = "Error occured in ScalarSub::transform()";
        }
        else
        {
            fGwip.fatalParseError = gwi.fatalParseError;
            fGwip.parseErrorText = gwi.parseErrorText;
        }

        return NULL;
    }

    fGwip.subselectList.push_back(csep);

    // error out non-support case for now: comparison out of semi join tables.
    // only check for simplecolumn
    if (!gwi.correlatedTbNameVec.empty())
    {
        for (uint32_t i = 0; i < cols.size(); i++)
        {
            SimpleColumn* sc = dynamic_cast<SimpleColumn*>(cols[i].get());

            if (sc)
            {
                CalpontSystemCatalog::TableAliasName tan = make_aliastable(sc->schemaName(), sc->tableName(), sc->tableAlias());
                uint32_t j = 0;

                for (; j < gwi.correlatedTbNameVec.size(); j++)
                    if (tan == gwi.correlatedTbNameVec[j])
                        break;

                if (j == gwi.correlatedTbNameVec.size())
                {
                    fGwip.fatalParseError = true;
                    fGwip.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_SCALAR);
                    return NULL;
                }
            }
        }
    }

    // remove outer query tables
    CalpontSelectExecutionPlan::TableList tblist;

    if (csep->tableList().size() >= tbCnt)
        tblist.insert(tblist.begin(), csep->tableList().begin() + tbCnt, csep->tableList().end());

    CalpontSelectExecutionPlan::SelectList derivedTbList;

    if (csep->derivedTableList().size() >= gwi.derivedTbCnt)
        derivedTbList.insert(derivedTbList.begin(), csep->derivedTableList().begin() + gwi.derivedTbCnt, csep->derivedTableList().end());

    csep->tableList(tblist);
    csep->derivedTableList(derivedTbList);

//	if (fSub->is_correlated)
    if (fSub->unit->first_select()->master_unit()->uncacheable)
    {
        SelectFilter* subFilter = new SelectFilter();
        subFilter->correlated(true);
        subFilter->cols(cols);
        subFilter->sub(csep);
        subFilter->op(SOP(op));
        subFilter->returnedColPos(fReturnedColPos);
        filter = subFilter;
    }
    else
    {
        SimpleScalarFilter* subFilter = new SimpleScalarFilter();
        subFilter->cols(cols);
        subFilter->sub(csep);
        subFilter->op(SOP(op));
        filter = subFilter;
    }

    return new ParseTree(filter);

}
Esempio n. 11
0
void VirtualTable::addColumn(const SRCP& column)
{
	// As of bug3695, make sure varbinary is not used in subquery.
	if (column->resultType().colDataType == CalpontSystemCatalog::VARBINARY && !fVarBinOK)
		throw runtime_error ("VARBINARY in subquery is not supported.");

	AggregateColumn*      agc = NULL;
	ArithmeticColumn*     arc = NULL;
	ConstantColumn*       cc  = NULL;
	FunctionColumn*       fc  = NULL;
	SimpleColumn*         sc  = NULL;
	WindowFunctionColumn* wc  = NULL;

	string columnName;
	ostringstream oss;
	UniqId colId;
	if ((sc = dynamic_cast<SimpleColumn*>(column.get())) != NULL)
	{
		columnName = sc->columnName();
		colId = UniqId(sc);
	}
	else if ((agc = dynamic_cast<AggregateColumn*>(column.get())) != NULL)
	{
//		oss << agc->functionName() << "_" << agc->expressionId();
//		oss << "Aggregate_" << agc->expressionId();
		columnName = agc->data();
		colId = UniqId(agc->expressionId(), "", "", "");
	}
	else if ((wc = dynamic_cast<WindowFunctionColumn*>(column.get())) != NULL)
	{
//		oss << wc->functionName() << "_" << wc->expressionId();
//		oss << "Window_" << wc->expressionId();
		columnName = wc->data();
		colId = UniqId(wc->expressionId(), "", "", "");
	}
	else if ((arc = dynamic_cast<ArithmeticColumn*>(column.get())) != NULL)
	{
//		oss << "Arithmetic_" << arc->expressionId();
		columnName = arc->data();
		colId = UniqId(arc->expressionId(), "", "", "");
	}
	else if ((fc = dynamic_cast<FunctionColumn*>(column.get())) != NULL)
	{
//		oss << fc->functionName() << "_" << fc->expressionId();
		columnName = fc->data();
		colId = UniqId(fc->expressionId(), "", "", "");
	}
	else if ((cc = dynamic_cast<ConstantColumn*>(column.get())) != NULL)
	{
//		oss << "Constant_" << cc->expressionId();
		columnName = cc->data();
		colId = UniqId(cc->expressionId(), cc->alias(), "", fView);
	}
	else // new column type has added, but this code is not updated.
	{
		oss << "not supported column type: " << typeid(*(column.get())).name();
		throw runtime_error(oss.str());
	}

	if (columnName.empty())
		columnName = column->alias();

	SimpleColumn* vc = new SimpleColumn();
	vc->tableName(fName);
	vc->tableAlias(fAlias);
	vc->columnName(columnName);
	vc->alias(column->alias());
	vc->viewName(fView);

	uint32_t index = fColumns.size();
	vc->colPosition(index);
	vc->oid(fTableOid+index+1);
	vc->resultType(column->resultType());

	SSC ssc(vc);
	fColumns.push_back(ssc);
	fColumnTypes.push_back(column->resultType());
	fColumnMap.insert(make_pair(colId, index));
}
Esempio n. 12
0
execplan::ReturnedColumn* buildPseudoColumn(Item* item,
                                            gp_walk_info& gwi,
                                            bool& nonSupport,
                                            uint32_t pseudoType)
{
	Item_func* ifp = (Item_func*)item;

	// idblocalpm is replaced by constant
	if (pseudoType == PSEUDO_LOCALPM)
	{
		int64_t localPm = idblocalpm();
		ConstantColumn* cc;
		if (localPm)
			cc = new ConstantColumn(localPm);
		else
			cc = new ConstantColumn("", ConstantColumn::NULLDATA);
		cc->alias(ifp->name? ifp->name : "");
		return cc;
	}

	// convert udf item to pseudocolumn item.
	// adjust result type
	// put arg col to column map
	string funcName = ifp->func_name();
	if (ifp->arg_count != 1 ||
	    !(ifp->arguments()) ||
	    !(ifp->arguments()[0]) ||
	    ifp->arguments()[0]->type() != Item::FIELD_ITEM)
		return nullOnError(gwi, funcName);

	Item_field* field = (Item_field*)(ifp->arguments()[0]);

	// @todo rule out derive table
	if (!field->field || !field->db_name || strlen(field->db_name) == 0)
		return nullOnError(gwi, funcName);

	SimpleColumn *sc = buildSimpleColumn(field, gwi);
	if (!sc)
		return nullOnError(gwi, funcName);

	if ((pseudoType == PSEUDO_EXTENTMIN || pseudoType == PSEUDO_EXTENTMAX) &&
	   (sc->colType().colDataType == CalpontSystemCatalog::VARBINARY ||
	   (sc->colType().colDataType == CalpontSystemCatalog::VARCHAR && sc->colType().colWidth > 7) ||
	   (sc->colType().colDataType == CalpontSystemCatalog::CHAR && sc->colType().colWidth > 8)))
		return nullOnError(gwi, funcName);

	// put arg col to column map
	if (gwi.clauseType == SELECT || gwi.clauseType == GROUP_BY) // select clause
	{
		SRCP srcp(sc);
		gwi.columnMap.insert(CalpontSelectExecutionPlan::ColumnMap::value_type(sc->columnName(), srcp));
		gwi.tableMap[make_aliastable(sc->schemaName(), sc->tableName(), sc->tableAlias(), sc->isInfiniDB())] =
		       make_pair(1, field->cached_table);
	}
	else if (!gwi.rcWorkStack.empty())
	{
		gwi.rcWorkStack.pop();
	}

	if (pseudoType == PSEUDO_PARTITION)
	{
		// parms: psueducolumn dbroot, segmentdir, segment
		SPTP sptp;
		FunctionColumn *fc = new FunctionColumn(funcName);
		funcexp::FunctionParm parms;
		PseudoColumn *dbroot = new PseudoColumn(*sc, PSEUDO_DBROOT);
		sptp.reset(new ParseTree(dbroot));
		parms.push_back(sptp);
		PseudoColumn *pp = new PseudoColumn(*sc, PSEUDO_SEGMENTDIR);
		sptp.reset(new ParseTree(pp));
		parms.push_back(sptp);
		PseudoColumn* seg = new PseudoColumn(*sc, PSEUDO_SEGMENT);
		sptp.reset(new ParseTree(seg));
		parms.push_back(sptp);
		fc->functionParms(parms);
		fc->expressionId(gwi.expressionId++);

		// string result type
		CalpontSystemCatalog::ColType ct;
		ct.colDataType = CalpontSystemCatalog::VARCHAR;
		ct.colWidth = 256;
		fc->resultType(ct);

		// operation type integer
		funcexp::Func_idbpartition* idbpartition = new funcexp::Func_idbpartition();
		fc->operationType(idbpartition->operationType(parms, fc->resultType()));
		fc->alias(ifp->name? ifp->name : "");
		return fc;
	}

	PseudoColumn *pc = new PseudoColumn(*sc, pseudoType);

	// @bug5892. set alias for derived table column matching.
	pc->alias(ifp->name? ifp->name : "");
	return pc;
}
Esempio n. 13
0
    void selectExecutionPlan_1() {
        cout << "SQL: select region.r_regionkey from region, nation where nation.n_regionkey = region.r_regionkey and nation.n_regionkey != 3;" << endl;

        erydbSelectExecutionPlan csep;
        CPPUNIT_ASSERT (csep.location() == erydbSelectExecutionPlan::MAIN);
        CPPUNIT_ASSERT (csep.dependent() == false);
        CPPUNIT_ASSERT (csep.subSelects().size() == 0);
        
        // returned columns
        erydbSelectExecutionPlan::ReturnedColumnList colList;        
        SimpleColumn *sc = new SimpleColumn("tpch.region.r_regionkey", 0);
        colList.push_back(sc);        
        ArithmeticColumn *ac = new ArithmeticColumn("a+sum(r_regionkey)", 0);
        colList.push_back(ac);
        csep.returnedCols (colList);   
        CPPUNIT_ASSERT(csep.returnedCols().size() == 2);     
               
        // filters
        erydbSelectExecutionPlan::FilterTokenList filterTokenList;
       
        SimpleFilter *sf = new SimpleFilter();
        SimpleColumn *lhs = new SimpleColumn();
        *lhs = *sc;       
        SimpleColumn *rhs = new SimpleColumn("tpch.nation.n_regionkey", 0);
        CPPUNIT_ASSERT (*lhs == *sc);
        CPPUNIT_ASSERT (*rhs != *lhs);
        Operator *op = new Operator("=");
        
        sf->op(op);
        sf->lhs(lhs);
        sf->rhs(rhs);
        filterTokenList.push_back (sf);
        
        filterTokenList.push_back( new Operator ("And") );   
        SimpleFilter *sf1 = new SimpleFilter (new Operator("="), sc->clone(), ac->clone());
        
        filterTokenList.push_back (sf1);
               
        csep.filterTokenList (filterTokenList);
        ParseTree *filterList = const_cast<ParseTree*> (csep.filters());
        
        // draw filterList tree
        filterList->drawTree("selectExecutionPlan_1.dot");                     
        csep.filters (filterList);

        // Group by
	    erydbSelectExecutionPlan::GroupByColumnList groupByList;
        groupByList.push_back(sc->clone());        
        csep.groupByCols (groupByList);
        CPPUNIT_ASSERT(csep.groupByCols().size() == 1);
        
        // Having
        erydbSelectExecutionPlan::FilterTokenList havingTokenList;
        SimpleFilter *having = new SimpleFilter( new Operator("="),
                                                 new ArithmeticColumn("sum(volumn)", 0),
                                                 new ConstantColumn(8));
        havingTokenList.push_back (having);
        csep.havingTokenList (havingTokenList);
        CPPUNIT_ASSERT (*sf1 != *having);
        CPPUNIT_ASSERT (csep.havingTokenList().size() == 1);                                                         
        
        // Order by                                                
	    erydbSelectExecutionPlan::OrderByColumnList orderByList;
	    ArithmeticColumn *o1 = new ArithmeticColumn(*ac);
	    o1->asc(false);
	    orderByList.push_back(o1);
        csep.orderByCols(orderByList);
        CPPUNIT_ASSERT(csep.orderByCols().size() == 1);        
        
        // another csep
        erydbSelectExecutionPlan *newcsep = new erydbSelectExecutionPlan(erydbSelectExecutionPlan::FROM);
        erydbSelectExecutionPlan::ReturnedColumnList ncolList;        
        SimpleColumn *newsc = new SimpleColumn("tpch.region.r_regionkey", 0);
        ncolList.push_back(newsc);        
        newcsep->returnedCols (ncolList);  
        erydbSelectExecutionPlan::FilterTokenList nfilterTokenList; 
        SimpleFilter *newsf = new SimpleFilter ( new Operator (">"),
                                    sc->clone(),
                                    newsc->clone());
        nfilterTokenList.push_back(newsf);
        newcsep->filterTokenList (nfilterTokenList);
        erydbSelectExecutionPlan::FilterTokenList nhavingTokenList;
        SimpleFilter *newhaving = new SimpleFilter ( new Operator (">"),
                                    sc->clone(),
                                    newsc->clone());  
        CPPUNIT_ASSERT (*newsf == *newhaving);                                    
        nhavingTokenList.push_back(newhaving);
        newcsep->havingTokenList (nhavingTokenList);
        CPPUNIT_ASSERT (*newcsep != csep); 
        CPPUNIT_ASSERT (*newcsep->filters() == *newcsep->having());
        ByteStream b;
        csep.serialize (b);
        newcsep->unserialize (b);
        CPPUNIT_ASSERT (csep == *newcsep);
        erydbSelectExecutionPlan::SelectList selectList;
        selectList.push_back(newcsep);
        csep.subSelects(selectList);        
        cout << "\nerydb Execution Plan:" << endl;
        cout << csep;
        cout << " --- end of test 1 ---" << endl;
    }