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