diff --git a/dbcon/mysql/ha_mcs_execplan.cpp b/dbcon/mysql/ha_mcs_execplan.cpp index 334243a66..f0d042545 100644 --- a/dbcon/mysql/ha_mcs_execplan.cpp +++ b/dbcon/mysql/ha_mcs_execplan.cpp @@ -7674,6 +7674,514 @@ void buildInToExistsFilter(gp_walk_info& gwi, SELECT_LEX& select_lex) } } + +/*@brief Process SELECT part of a query or sub-query */ +/*********************************************************** + * DESCRIPTION: + * Processes SELECT part of a query or sub-query + * RETURNS + * error id as an int + ***********************************************************/ + int processSelect(SELECT_LEX& select_lex, gp_walk_info& gwi, SCSEP& csep, + vector& funcFieldVec, + CalpontSelectExecutionPlan::SelectList& selectSubList) + { + gwi.select_lex = &select_lex; + #ifdef DEBUG_WALK_COND + { + cerr << "------------------- SELECT --------------------" << endl; + List_iterator_fast it(select_lex.item_list); + Item* item; + + while ((item = it++)) + { + debug_walk(item, 0); + } + + cerr << "-----------------------------------------------\n" << endl; + } + #endif + + // analyze SELECT and ORDER BY parts - do they have implicit GROUP BY induced by aggregates? + { + if (select_lex.group_list.first) + { + // we have an explicit GROUP BY. + gwi.implicitExplicitGroupBy = true; + } + else + { + // do we have an implicit GROUP BY? + List_iterator_fast it(select_lex.item_list); + Item* item; + + while ((item = it++)) + { + analyzeForImplicitGroupBy(item, gwi); + } + SQL_I_List order_list = select_lex.order_list; + ORDER* ordercol = static_cast(order_list.first); + + for (; ordercol; ordercol = ordercol->next) + { + analyzeForImplicitGroupBy(*(ordercol->item), gwi); + } + } + } + // populate returnedcolumnlist and columnmap + List_iterator_fast it(select_lex.item_list); + Item* item; + + // empty rcWorkStack and ptWorkStack. They should all be empty by now. + clearStacks(gwi, false, true); + + // indicate the starting pos of scalar returned column, because some join column + // has been inserted to the returned column list. + if (gwi.subQuery) + { + ScalarSub* scalar = dynamic_cast(gwi.subQuery); + + if (scalar) + scalar->returnedColPos(gwi.additionalRetCols.size()); + } + + + while ((item = it++)) + { + string itemAlias = (item->name.length ? item->name.str : ""); + + // @bug 5916. Need to keep checking until getting concret item in case + // of nested view. + Item* baseItem = item; + while (item->type() == Item::REF_ITEM) + { + Item_ref* ref = (Item_ref*)item; + item = (*(ref->ref)); + } + + Item::Type itype = item->type(); + + switch (itype) + { + case Item::FIELD_ITEM: + { + Item_field* ifp = (Item_field*)item; + SimpleColumn* sc = NULL; + + if (ifp->field_name.length && string(ifp->field_name.str) == "*") + { + collectAllCols(gwi, ifp); + break; + } + sc = buildSimpleColumn(ifp, gwi); + + if (sc) + { + string fullname; + String str; + ifp->print(&str, QT_ORDINARY); + fullname = str.c_ptr(); + + if (!ifp->is_explicit_name()) // no alias + { + sc->alias(fullname); + } + else // alias + { + if (!itemAlias.empty()) + sc->alias(itemAlias); + } + + // We need to look into GROUP BY columns to decide if we need to wrap a column. + ReturnedColumn* rc = wrapIntoAggregate(sc, gwi, baseItem); + + SRCP sprc(rc); + pushReturnedCol(gwi, baseItem, sprc); + + gwi.columnMap.insert( + CalpontSelectExecutionPlan::ColumnMap::value_type(string(ifp->field_name.str), sprc)); + TABLE_LIST* tmp = 0; + + if (ifp->cached_table) + tmp = ifp->cached_table; + + gwi.tableMap[make_aliastable(sc->schemaName(), sc->tableName(), sc->tableAlias(), + sc->isColumnStore())] = make_pair(1, tmp); + } + else + { + setError(gwi.thd, ER_INTERNAL_ERROR, gwi.parseErrorText, gwi); + delete sc; + return ER_INTERNAL_ERROR; + } + + break; + } + + // aggregate column + case Item::SUM_FUNC_ITEM: + { + ReturnedColumn* ac = buildAggregateColumn(item, gwi); + + if (gwi.fatalParseError) + { + // e.g., non-support ref column + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + delete ac; + return ER_CHECK_NOT_IMPLEMENTED; + } + + // add this agg col to returnedColumnList + boost::shared_ptr spac(ac); + pushReturnedCol(gwi, item, spac); + break; + } + + case Item::FUNC_ITEM: + { + Item_func* ifp = static_cast(item); + + // @bug4383. error out non-support stored function + if (ifp->functype() == Item_func::FUNC_SP) + { + gwi.fatalParseError = true; + gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_SP_FUNCTION_NOT_SUPPORT); + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + return ER_CHECK_NOT_IMPLEMENTED; + } + + if (string(ifp->func_name()) == "xor") + { + gwi.fatalParseError = true; + gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_FILTER_COND_EXP); + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + return ER_CHECK_NOT_IMPLEMENTED; + } + + uint16_t parseInfo = 0; + vector tmpVec; + bool hasNonSupportItem = false; + parse_item(ifp, tmpVec, hasNonSupportItem, parseInfo, &gwi); + + if (ifp->with_subquery() || string(ifp->func_name()) == string("") || + ifp->functype() == Item_func::NOT_ALL_FUNC || parseInfo & SUB_BIT) + { + gwi.fatalParseError = true; + gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_SELECT_SUB); + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + return ER_CHECK_NOT_IMPLEMENTED; + } + + // if "IN" or "BETWEEN" are in the SELECT clause, build function column + string funcName = ifp->func_name(); + ReturnedColumn* rc; + if (funcName == "in" || funcName == " IN " || funcName == "between") + { + rc = buildFunctionColumn(ifp, gwi, hasNonSupportItem, true); + } + else + { + rc = buildFunctionColumn(ifp, gwi, hasNonSupportItem); + } + + SRCP srcp(rc); + + if (rc) + { + // MCOL-2178 CS has to process determenistic functions with constant arguments. + if (!hasNonSupportItem && ifp->const_item() && !(parseInfo & AF_BIT) && tmpVec.size() == 0) + { + srcp.reset(buildReturnedColumn(item, gwi, gwi.fatalParseError)); + pushReturnedCol(gwi, item, srcp); + + if (ifp->name.length) + srcp->alias(ifp->name.str); + + continue; + } + // FIXME: usage of pushReturnedCol instead of gwi.returnedCols.push_back(srcp) here + // made within MCOL-5776 produced bug MCOL-5932 so, the check of equal columns is disabled + pushReturnedCol(gwi, item, srcp); + } + else // This was a vtable post-process block + { + hasNonSupportItem = false; + uint32_t before_size = funcFieldVec.size(); + parse_item(ifp, funcFieldVec, hasNonSupportItem, parseInfo, &gwi); + uint32_t after_size = funcFieldVec.size(); + + // pushdown handler projection functions + // @bug3881. set_user_var can not be treated as constant function + // @bug5716. Try to avoid post process function for union query. + if (!hasNonSupportItem && (after_size - before_size) == 0 && !(parseInfo & AGG_BIT) && + !(parseInfo & SUB_BIT)) + { + ConstantColumn* cc = buildConstantColumnMaybeNullUsingValStr(ifp, gwi); + + SRCP srcp(cc); + + if (ifp->name.length) + cc->alias(ifp->name.str); + + pushReturnedCol(gwi, ifp, srcp); + + // clear the error set by buildFunctionColumn + gwi.fatalParseError = false; + gwi.parseErrorText = ""; + break; + } + else if (hasNonSupportItem || parseInfo & AGG_BIT || parseInfo & SUB_BIT || + (gwi.fatalParseError && gwi.subQuery)) + { + if (gwi.parseErrorText.empty()) + { + Message::Args args; + args.add(ifp->func_name()); + gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORTED_FUNCTION, args); + } + + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + return ER_CHECK_NOT_IMPLEMENTED; + } + else if (gwi.subQuery && (isPredicateFunction(ifp, &gwi) || ifp->type() == Item::COND_ITEM)) + { + gwi.fatalParseError = true; + gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_FILTER_COND_EXP); + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + return ER_CHECK_NOT_IMPLEMENTED; + } + + //@Bug 3030 Add error check for dml statement + if (ha_mcs_common::isUpdateOrDeleteStatement(gwi.thd->lex->sql_command)) + { + if (after_size - before_size != 0) + { + gwi.parseErrorText = ifp->func_name(); + return -1; + } + } + else + { + Message::Args args; + args.add(ifp->func_name()); + gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORTED_FUNCTION, args); + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + return ER_CHECK_NOT_IMPLEMENTED; + } + } + + break; + } // End of FUNC_ITEM + + // DRRTUY Replace the whole section with typeid() checks or use + // static_cast here + case Item::CONST_ITEM: + { + switch (item->cmp_type()) + + { + case INT_RESULT: + case STRING_RESULT: + case DECIMAL_RESULT: + case REAL_RESULT: + case TIME_RESULT: + { + if (ha_mcs_common::isUpdateOrDeleteStatement(gwi.thd->lex->sql_command)) + { + } + else + { + // do not push the dummy column (mysql added) to returnedCol + if (item->name.length && string(item->name.str) == "Not_used") + continue; + + // @bug3509. Constant column is sent to ExeMgr now. + SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); + + if (item->name.length) + srcp->alias(item->name.str); + + pushReturnedCol(gwi, item, srcp); + } + + break; + } + // MCOL-2178 This switch doesn't handl + // ROW_ + default: + { + IDEBUG(cerr << "Warning unsupported cmp_type() in projection" << endl); + // noop + } + } + break; + } // CONST_ITEM ends here + + case Item::NULL_ITEM: + { + if (ha_mcs_common::isUpdateOrDeleteStatement(gwi.thd->lex->sql_command)) + { + } + else + { + SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); + pushReturnedCol(gwi, item, srcp); + + if (item->name.length) + srcp->alias(item->name.str); + } + + break; + } + + case Item::SUBSELECT_ITEM: + { + Item_subselect* sub = (Item_subselect*)item; + + if (sub->substype() != Item_subselect::SINGLEROW_SUBS) + { + gwi.fatalParseError = true; + gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_SELECT_SUB); + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + return ER_CHECK_NOT_IMPLEMENTED; + } + + #ifdef DEBUG_WALK_COND + cerr << "SELECT clause SUBSELECT Item: " << sub->substype() << endl; + JOIN* join = sub->get_select_lex()->join; + + if (join) + { + Item_cond* cond = static_cast(join->conds); + + if (cond) + cond->traverse_cond(debug_walk, &gwi, Item::POSTFIX); + } + + cerr << "Finish SELECT clause subselect item traversing" << endl; + #endif + SelectSubQuery* selectSub = new SelectSubQuery(gwi, sub); + // selectSub->gwip(&gwi); + SCSEP ssub = selectSub->transform(); + + if (!ssub || gwi.fatalParseError) + { + if (gwi.parseErrorText.empty()) + gwi.parseErrorText = "Unsupported Item in SELECT subquery."; + + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + + return ER_CHECK_NOT_IMPLEMENTED; + } + + selectSubList.push_back(ssub); + SimpleColumn* rc = new SimpleColumn(); + rc->colSource(rc->colSource() | SELECT_SUB); + rc->timeZone(gwi.timeZone); + + if (sub->get_select_lex()->get_table_list()) + { + rc->viewName(getViewName(sub->get_select_lex()->get_table_list()), lower_case_table_names); + } + if (sub->name.length) + rc->alias(sub->name.str); + + gwi.returnedCols.push_back(SRCP(rc)); + + break; + } + + case Item::COND_ITEM: + { + gwi.fatalParseError = true; + gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_FILTER_COND_EXP); + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + return ER_CHECK_NOT_IMPLEMENTED; + } + + case Item::EXPR_CACHE_ITEM: + { + printf("EXPR_CACHE_ITEM in getSelectPlan\n"); + gwi.fatalParseError = true; + gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_UNKNOWN_COL); + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + return ER_CHECK_NOT_IMPLEMENTED; + } + + case Item::WINDOW_FUNC_ITEM: + { + SRCP srcp(buildWindowFunctionColumn(item, gwi, gwi.fatalParseError)); + + if (!srcp || gwi.fatalParseError) + { + if (gwi.parseErrorText.empty()) + gwi.parseErrorText = "Unsupported Item in SELECT subquery."; + + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + return ER_CHECK_NOT_IMPLEMENTED; + } + + pushReturnedCol(gwi, item, srcp); + break; + } + case Item::TYPE_HOLDER: + { + if (!gwi.tbList.size()) + { + gwi.parseErrorText = "subquery with VALUES"; + gwi.fatalParseError = true; + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + return ER_CHECK_NOT_IMPLEMENTED; + } + else + { + std::cerr << "********** received TYPE_HOLDER *********" << std::endl; + } + break; + } + + default: + { + break; + } + } + } + + // @bug4388 normalize the project coltypes for union main select list + if (!csep->unionVec().empty()) + { + unsigned int unionedTypeRc = 0; + + for (uint32_t i = 0; i < gwi.returnedCols.size(); i++) + { + vector coltypes; + + for (uint32_t j = 0; j < csep->unionVec().size(); j++) + { + CalpontSelectExecutionPlan* unionCsep = + dynamic_cast(csep->unionVec()[j].get()); + coltypes.push_back(unionCsep->returnedCols()[i]->resultType()); + + // @bug5976. set hasAggregate true for the main column if + // one corresponding union column has aggregate + if (unionCsep->returnedCols()[i]->hasAggregate()) + gwi.returnedCols[i]->hasAggregate(true); + } + + gwi.returnedCols[i]->resultType( + CalpontSystemCatalog::ColType::convertUnionColType(coltypes, unionedTypeRc)); + + if (unionedTypeRc != 0) + { + gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(unionedTypeRc); + setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); + return ER_CHECK_NOT_IMPLEMENTED; + } + } + } + return 0; + } + /*@brief Translates SELECT_LEX into CSEP */ /*********************************************************** * DESCRIPTION: @@ -7724,501 +8232,13 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i } gwi.clauseType = SELECT; - SELECT_LEX* oldSelectLex = gwi.select_lex; // XXX: SZ: should it be restored in case of error return? - gwi.select_lex = &select_lex; -#ifdef DEBUG_WALK_COND - { - cerr << "------------------- SELECT --------------------" << endl; - List_iterator_fast it(select_lex.item_list); - Item* item; - - while ((item = it++)) - { - debug_walk(item, 0); - } - - cerr << "-----------------------------------------------\n" << endl; - } -#endif - - // analyze SELECT and ORDER BY parts - do they have implicit GROUP BY induced by aggregates? - { - if (select_lex.group_list.first) - { - // we have an explicit GROUP BY. - gwi.implicitExplicitGroupBy = true; - } - else - { - // do we have an implicit GROUP BY? - List_iterator_fast it(select_lex.item_list); - Item* item; - - while ((item = it++)) - { - analyzeForImplicitGroupBy(item, gwi); - } - SQL_I_List order_list = select_lex.order_list; - ORDER* ordercol = static_cast(order_list.first); - - for (; ordercol; ordercol = ordercol->next) - { - analyzeForImplicitGroupBy(*(ordercol->item), gwi); - } - } - } - // populate returnedcolumnlist and columnmap - List_iterator_fast it(select_lex.item_list); - Item* item; + SELECT_LEX* originalSelectLex = gwi.select_lex; // XXX: SZ: should it be restored in case of error return? vector funcFieldVec; - - // empty rcWorkStack and ptWorkStack. They should all be empty by now. - clearStacks(gwi, false, true); - - // indicate the starting pos of scalar returned column, because some join column - // has been inserted to the returned column list. - if (gwi.subQuery) - { - ScalarSub* scalar = dynamic_cast(gwi.subQuery); - - if (scalar) - scalar->returnedColPos(gwi.additionalRetCols.size()); - } - CalpontSelectExecutionPlan::SelectList selectSubList; - while ((item = it++)) + if ((rc = processSelect(select_lex, gwi, csep, funcFieldVec, selectSubList))) { - string itemAlias = (item->name.length ? item->name.str : ""); - - // @bug 5916. Need to keep checking until getting concret item in case - // of nested view. - Item* baseItem = item; - while (item->type() == Item::REF_ITEM) - { - Item_ref* ref = (Item_ref*)item; - item = (*(ref->ref)); - } - - Item::Type itype = item->type(); - - switch (itype) - { - case Item::FIELD_ITEM: - { - Item_field* ifp = (Item_field*)item; - SimpleColumn* sc = NULL; - - if (ifp->field_name.length && string(ifp->field_name.str) == "*") - { - collectAllCols(gwi, ifp); - break; - } - sc = buildSimpleColumn(ifp, gwi); - - if (sc) - { - string fullname; - String str; - ifp->print(&str, QT_ORDINARY); - fullname = str.c_ptr(); - - if (!ifp->is_explicit_name()) // no alias - { - sc->alias(fullname); - } - else // alias - { - if (!itemAlias.empty()) - sc->alias(itemAlias); - } - - // We need to look into GROUP BY columns to decide if we need to wrap a column. - ReturnedColumn* rc = wrapIntoAggregate(sc, gwi, baseItem); - - SRCP sprc(rc); - pushReturnedCol(gwi, baseItem, sprc); - - gwi.columnMap.insert( - CalpontSelectExecutionPlan::ColumnMap::value_type(string(ifp->field_name.str), sprc)); - TABLE_LIST* tmp = 0; - - if (ifp->cached_table) - tmp = ifp->cached_table; - - gwi.tableMap[make_aliastable(sc->schemaName(), sc->tableName(), sc->tableAlias(), - sc->isColumnStore())] = make_pair(1, tmp); - } - else - { - setError(gwi.thd, ER_INTERNAL_ERROR, gwi.parseErrorText, gwi); - delete sc; - return ER_INTERNAL_ERROR; - } - - break; - } - - // aggregate column - case Item::SUM_FUNC_ITEM: - { - ReturnedColumn* ac = buildAggregateColumn(item, gwi); - - if (gwi.fatalParseError) - { - // e.g., non-support ref column - setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); - delete ac; - return ER_CHECK_NOT_IMPLEMENTED; - } - - // add this agg col to returnedColumnList - boost::shared_ptr spac(ac); - pushReturnedCol(gwi, item, spac); - break; - } - - case Item::FUNC_ITEM: - { - Item_func* ifp = static_cast(item); - - // @bug4383. error out non-support stored function - if (ifp->functype() == Item_func::FUNC_SP) - { - gwi.fatalParseError = true; - gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_SP_FUNCTION_NOT_SUPPORT); - setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); - return ER_CHECK_NOT_IMPLEMENTED; - } - - if (string(ifp->func_name()) == "xor") - { - gwi.fatalParseError = true; - gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_FILTER_COND_EXP); - setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); - return ER_CHECK_NOT_IMPLEMENTED; - } - - uint16_t parseInfo = 0; - vector tmpVec; - bool hasNonSupportItem = false; - parse_item(ifp, tmpVec, hasNonSupportItem, parseInfo, &gwi); - - if (ifp->with_subquery() || string(ifp->func_name()) == string("") || - ifp->functype() == Item_func::NOT_ALL_FUNC || parseInfo & SUB_BIT) - { - gwi.fatalParseError = true; - gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_SELECT_SUB); - setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); - return ER_CHECK_NOT_IMPLEMENTED; - } - - // if "IN" or "BETWEEN" are in the SELECT clause, build function column - string funcName = ifp->func_name(); - ReturnedColumn* rc; - if (funcName == "in" || funcName == " IN " || funcName == "between") - { - rc = buildFunctionColumn(ifp, gwi, hasNonSupportItem, true); - } - else - { - rc = buildFunctionColumn(ifp, gwi, hasNonSupportItem); - } - - SRCP srcp(rc); - - if (rc) - { - // MCOL-2178 CS has to process determenistic functions with constant arguments. - if (!hasNonSupportItem && ifp->const_item() && !(parseInfo & AF_BIT) && tmpVec.size() == 0) - { - srcp.reset(buildReturnedColumn(item, gwi, gwi.fatalParseError)); - pushReturnedCol(gwi, item, srcp); - - if (ifp->name.length) - srcp->alias(ifp->name.str); - - continue; - } - // FIXME: usage of pushReturnedCol instead of gwi.returnedCols.push_back(srcp) here - // made within MCOL-5776 produced bug MCOL-5932 so, the check of equal columns is disabled - pushReturnedCol(gwi, item, srcp); - } - else // This was a vtable post-process block - { - hasNonSupportItem = false; - uint32_t before_size = funcFieldVec.size(); - parse_item(ifp, funcFieldVec, hasNonSupportItem, parseInfo, &gwi); - uint32_t after_size = funcFieldVec.size(); - - // pushdown handler projection functions - // @bug3881. set_user_var can not be treated as constant function - // @bug5716. Try to avoid post process function for union query. - if (!hasNonSupportItem && (after_size - before_size) == 0 && !(parseInfo & AGG_BIT) && - !(parseInfo & SUB_BIT)) - { - ConstantColumn* cc = buildConstantColumnMaybeNullUsingValStr(ifp, gwi); - - SRCP srcp(cc); - - if (ifp->name.length) - cc->alias(ifp->name.str); - - pushReturnedCol(gwi, ifp, srcp); - - // clear the error set by buildFunctionColumn - gwi.fatalParseError = false; - gwi.parseErrorText = ""; - break; - } - else if (hasNonSupportItem || parseInfo & AGG_BIT || parseInfo & SUB_BIT || - (gwi.fatalParseError && gwi.subQuery)) - { - if (gwi.parseErrorText.empty()) - { - Message::Args args; - args.add(ifp->func_name()); - gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORTED_FUNCTION, args); - } - - setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); - return ER_CHECK_NOT_IMPLEMENTED; - } - else if (gwi.subQuery && (isPredicateFunction(ifp, &gwi) || ifp->type() == Item::COND_ITEM)) - { - gwi.fatalParseError = true; - gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_FILTER_COND_EXP); - setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); - return ER_CHECK_NOT_IMPLEMENTED; - } - - //@Bug 3030 Add error check for dml statement - if (ha_mcs_common::isUpdateOrDeleteStatement(gwi.thd->lex->sql_command)) - { - if (after_size - before_size != 0) - { - gwi.parseErrorText = ifp->func_name(); - return -1; - } - } - else - { - Message::Args args; - args.add(ifp->func_name()); - gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORTED_FUNCTION, args); - setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); - return ER_CHECK_NOT_IMPLEMENTED; - } - } - - break; - } // End of FUNC_ITEM - - // DRRTUY Replace the whole section with typeid() checks or use - // static_cast here - case Item::CONST_ITEM: - { - switch (item->cmp_type()) - - { - case INT_RESULT: - case STRING_RESULT: - case DECIMAL_RESULT: - case REAL_RESULT: - case TIME_RESULT: - { - if (ha_mcs_common::isUpdateOrDeleteStatement(gwi.thd->lex->sql_command)) - { - } - else - { - // do not push the dummy column (mysql added) to returnedCol - if (item->name.length && string(item->name.str) == "Not_used") - continue; - - // @bug3509. Constant column is sent to ExeMgr now. - SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); - - if (item->name.length) - srcp->alias(item->name.str); - - pushReturnedCol(gwi, item, srcp); - } - - break; - } - // MCOL-2178 This switch doesn't handl - // ROW_ - default: - { - IDEBUG(cerr << "Warning unsupported cmp_type() in projection" << endl); - // noop - } - } - break; - } // CONST_ITEM ends here - - case Item::NULL_ITEM: - { - if (ha_mcs_common::isUpdateOrDeleteStatement(gwi.thd->lex->sql_command)) - { - } - else - { - SRCP srcp(buildReturnedColumn(item, gwi, gwi.fatalParseError)); - pushReturnedCol(gwi, item, srcp); - - if (item->name.length) - srcp->alias(item->name.str); - } - - break; - } - - case Item::SUBSELECT_ITEM: - { - Item_subselect* sub = (Item_subselect*)item; - - if (sub->substype() != Item_subselect::SINGLEROW_SUBS) - { - gwi.fatalParseError = true; - gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_SELECT_SUB); - setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); - return ER_CHECK_NOT_IMPLEMENTED; - } - -#ifdef DEBUG_WALK_COND - cerr << "SELECT clause SUBSELECT Item: " << sub->substype() << endl; - JOIN* join = sub->get_select_lex()->join; - - if (join) - { - Item_cond* cond = static_cast(join->conds); - - if (cond) - cond->traverse_cond(debug_walk, &gwi, Item::POSTFIX); - } - - cerr << "Finish SELECT clause subselect item traversing" << endl; -#endif - SelectSubQuery* selectSub = new SelectSubQuery(gwi, sub); - // selectSub->gwip(&gwi); - SCSEP ssub = selectSub->transform(); - - if (!ssub || gwi.fatalParseError) - { - if (gwi.parseErrorText.empty()) - gwi.parseErrorText = "Unsupported Item in SELECT subquery."; - - setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); - - return ER_CHECK_NOT_IMPLEMENTED; - } - - selectSubList.push_back(ssub); - SimpleColumn* rc = new SimpleColumn(); - rc->colSource(rc->colSource() | SELECT_SUB); - rc->timeZone(gwi.timeZone); - - if (sub->get_select_lex()->get_table_list()) - { - rc->viewName(getViewName(sub->get_select_lex()->get_table_list()), lower_case_table_names); - } - if (sub->name.length) - rc->alias(sub->name.str); - - gwi.returnedCols.push_back(SRCP(rc)); - - break; - } - - case Item::COND_ITEM: - { - gwi.fatalParseError = true; - gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_FILTER_COND_EXP); - setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); - return ER_CHECK_NOT_IMPLEMENTED; - } - - case Item::EXPR_CACHE_ITEM: - { - printf("EXPR_CACHE_ITEM in getSelectPlan\n"); - gwi.fatalParseError = true; - gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_UNKNOWN_COL); - setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); - return ER_CHECK_NOT_IMPLEMENTED; - } - - case Item::WINDOW_FUNC_ITEM: - { - SRCP srcp(buildWindowFunctionColumn(item, gwi, gwi.fatalParseError)); - - if (!srcp || gwi.fatalParseError) - { - if (gwi.parseErrorText.empty()) - gwi.parseErrorText = "Unsupported Item in SELECT subquery."; - - setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); - return ER_CHECK_NOT_IMPLEMENTED; - } - - pushReturnedCol(gwi, item, srcp); - break; - } - case Item::TYPE_HOLDER: - { - if (!gwi.tbList.size()) - { - gwi.parseErrorText = "subquery with VALUES"; - gwi.fatalParseError = true; - setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); - return ER_CHECK_NOT_IMPLEMENTED; - } - else - { - std::cerr << "********** received TYPE_HOLDER *********" << std::endl; - } - break; - } - - default: - { - break; - } - } - } - - // @bug4388 normalize the project coltypes for union main select list - if (!csep->unionVec().empty()) - { - unsigned int unionedTypeRc = 0; - - for (uint32_t i = 0; i < gwi.returnedCols.size(); i++) - { - vector coltypes; - - for (uint32_t j = 0; j < csep->unionVec().size(); j++) - { - CalpontSelectExecutionPlan* unionCsep = - dynamic_cast(csep->unionVec()[j].get()); - coltypes.push_back(unionCsep->returnedCols()[i]->resultType()); - - // @bug5976. set hasAggregate true for the main column if - // one corresponding union column has aggregate - if (unionCsep->returnedCols()[i]->hasAggregate()) - gwi.returnedCols[i]->hasAggregate(true); - } - - gwi.returnedCols[i]->resultType( - CalpontSystemCatalog::ColType::convertUnionColType(coltypes, unionedTypeRc)); - - if (unionedTypeRc != 0) - { - gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(unionedTypeRc); - setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi); - return ER_CHECK_NOT_IMPLEMENTED; - } - } + return rc; } // Having clause handling @@ -8994,7 +9014,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i for (uint32_t i = 0; i < gwi.localCols.size(); i++) gwi.localCols[i]->sequence(i); - gwi.select_lex = oldSelectLex; + gwi.select_lex = originalSelectLex; // append additionalRetCols to returnedCols gwi.returnedCols.insert(gwi.returnedCols.begin(), gwi.additionalRetCols.begin(), gwi.additionalRetCols.end());