SCSEP FromSubQuery::transform() { assert (fFromSub); SCSEP csep(new erydbSelectExecutionPlan()); csep->sessionID(fGwip.sessionid); csep->location(erydbSelectExecutionPlan::FROM); csep->subType (erydbSelectExecutionPlan::FROM_SUBS); // gwi for the sub query gp_walk_info gwi; gwi.thd = fGwip.thd; gwi.subQuery = this; gwi.viewName = fGwip.viewName; csep->derivedTbAlias(fAlias); // always lower case if (getSelectPlan(gwi, *fFromSub, csep) != 0) { fGwip.fatalParseError = true; if (!gwi.parseErrorText.empty()) fGwip.parseErrorText = gwi.parseErrorText; else fGwip.parseErrorText = "Error occured in FromSubQuery::transform()"; csep.reset(); return csep; } fGwip.subselectList.push_back(csep); return csep; }
SCSEP SelectSubQuery::transform() { idbassert(fSelSub); SCSEP csep(new CalpontSelectExecutionPlan()); csep->sessionID(fGwip.sessionid); csep->subType (CalpontSelectExecutionPlan::SELECT_SUBS); // gwi for the sub query gp_walk_info gwi; gwi.thd = fGwip.thd; gwi.subQuery = this; // @4632 merge table list to gwi in case there is FROM sub to be referenced // in the SELECT 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, *(fSelSub->get_select_lex()), csep) != 0) { if (!gwi.fatalParseError) { fGwip.fatalParseError = true; fGwip.parseErrorText = "Error occured in SelectSubQuery::transform()"; } else { fGwip.fatalParseError = gwi.fatalParseError; fGwip.parseErrorText = gwi.parseErrorText; } csep.reset(); return csep; } fGwip.subselectList.push_back(csep); // 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); return csep; }
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); }
/** MySQL transform (NOT) IN subquery to (NOT) EXIST * */ execplan::ParseTree* InSub::transform() { if (!fFunc) return NULL; // @todo need to handle scalar IN and BETWEEN specially // this blocks handles only one subselect scalar // arg[0]: column | arg[1]: subselect //assert (fFunc->argument_count() == 2 && fGwip.rcWorkStack.size() >= 2); if (fFunc->argument_count() != 2 || fGwip.rcWorkStack.size() < 2) { fGwip.fatalParseError = true; fGwip.parseErrorText = "Unsupported item in IN subquery"; return NULL; } ReturnedColumn* rhs = fGwip.rcWorkStack.top(); fGwip.rcWorkStack.pop(); delete rhs; ReturnedColumn* lhs = fGwip.rcWorkStack.top(); fGwip.rcWorkStack.pop(); delete lhs; fSub = (Item_subselect*)(fFunc->arguments()[1]); idbassert(fSub && fFunc); SCSEP csep (new CalpontSelectExecutionPlan()); csep->sessionID(fGwip.sessionid); csep->location(CalpontSelectExecutionPlan::WHERE); csep->subType (CalpontSelectExecutionPlan::IN_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) { fGwip.fatalParseError = true; if (gwi.fatalParseError && !gwi.parseErrorText.empty()) fGwip.parseErrorText = gwi.parseErrorText; else fGwip.parseErrorText = "Error occured in InSub::transform()"; 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); ExistsFilter* subFilter = new ExistsFilter(); subFilter->sub(csep); if (gwi.subQuery->correlated()) subFilter->correlated(true); else subFilter->correlated(false); if (fGwip.clauseType == HAVING && subFilter->correlated()) { fGwip.fatalParseError = true; fGwip.parseErrorText = logging::IDBErrorInfo::instance()->errorMsg(logging::ERR_NON_SUPPORT_HAVING); } fGwip.subselectList.push_back(csep); return new ParseTree(subFilter); }