#include #include using namespace std; #include "constantcolumn.h" #include "simplefilter.h" #include "calpontsystemcatalog.h" #include "parsetree.h" #include "simplecolumn.h" #include "calpontselectexecutionplan.h" using namespace execplan; #include "cseputils.h" namespace qfe { extern string DefaultSchema; namespace utils { ConstantColumn* createConstCol(const string& valstr) { ConstantColumn* cc = new ConstantColumn(valstr); cc->alias(valstr); return cc; } template ConstantColumn* createConstCol(const string& valstr, T val) { ConstantColumn* cc = new ConstantColumn(valstr, val); cc->alias(valstr); return cc; } SimpleFilter* createSimpleFilter(boost::shared_ptr& 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; } void appendSimpleFilter(ParseTree*& ptree, SimpleFilter* filter) { if (ptree->data() == 0) { // degenerate case, this filter goes at this node ptree->data(filter); } else if (ptree->right() == 0 && ptree->left() == 0) { // this will be the case when there is a single node in the tree // that contains a filter. Here we want to make the root node an // 'and' operator, push the existing down to the lhs and make a // new node for the new filter ParseTree* newLhs = new ParseTree(ptree->data()); ParseTree* newRhs = new ParseTree(filter); Operator* op = new Operator(); op->data("and"); ptree->data(op); ptree->left(newLhs); ptree->right(newRhs); } else { // this will be the case once we have a tree with an 'and' at the // root node, a filter in the lhs, and an arbitrary height tree // with the same properties on the rhs. Because all operators // are guaranteed to be and for now we simply insert a new rhs // node and "push down" the existing tree Operator* op = new Operator(); op->data("and"); ParseTree* newRhs = new ParseTree(op); newRhs->left(new ParseTree(filter)); newRhs->right(ptree->right()); ptree->right(newRhs); } } void updateParseTree(boost::shared_ptr& csc, execplan::CalpontSelectExecutionPlan*& csep, execplan::SimpleColumn* sc, const std::string& relop, pair cval) { execplan::ConstantColumn* cc = 0; if (cval.first == 0) cc = createConstCol(cval.second, static_cast(atoll(cval.second.c_str()))); else cc = createConstCol(cval.second); if (sc->schemaName() == "infinidb_unknown" && !DefaultSchema.empty()) sc->schemaName(DefaultSchema); execplan::SimpleFilter* sf = 0; sf = createSimpleFilter(csc, execplan::make_tcn(sc->schemaName(), sc->tableName(), sc->columnName()), relop, cc); execplan::ParseTree* ptp = 0; ptp = csep->filters(); if (ptp == 0) ptp = new execplan::ParseTree(); appendSimpleFilter(ptp, sf); csep->filters(ptp); } // template instantiations template ConstantColumn* createConstCol(const string& valstr, int64_t val); } // namespace utils } // namespace qfe