diff --git a/dbcon/mysql/ha_calpont_execplan.cpp b/dbcon/mysql/ha_calpont_execplan.cpp index 9e63f29fc..23765af86 100755 --- a/dbcon/mysql/ha_calpont_execplan.cpp +++ b/dbcon/mysql/ha_calpont_execplan.cpp @@ -428,6 +428,18 @@ void debug_walk(const Item *item, void *arg) ((Item_cache_wrapper*)item)->get_orig_item()->traverse_cond(debug_walk, arg, Item::POSTFIX); break; } + case Item::CACHE_ITEM: + { + Item_cache* isp = (Item_cache*)item; + if (item->result_type() == ROW_RESULT) + { + cout << "CACHE_ROW_ITEM" << endl; + break; + } + String val, *str = isp->val_str(&val); + cout << "CACHE_ITEM: >" << str->c_ptr() << '<' << endl; + break; + } case Item::WINDOW_FUNC_ITEM: { cout << "Window Function Item" << endl; @@ -442,6 +454,51 @@ void debug_walk(const Item *item, void *arg) } #endif +void buildNestedTableOuterJoin(gp_walk_info& gwi, TABLE_LIST* table_ptr) +{ + TABLE_LIST *table; + List_iterator li(table_ptr->nested_join->join_list); + while ((table= li++)) + { + gwi.innerTables.clear(); + if (table->outer_join) + { + CalpontSystemCatalog::TableAliasName ta = make_aliasview( + (table->db ? table->db : ""), + (table->table_name ? table->table_name : ""), + (table->alias ? table->alias : ""), + getViewName(table)); + gwi.innerTables.insert(ta); + } + if (table->nested_join) + { + TABLE_LIST *tab; + List_iterator li(table->nested_join->join_list); + while ((tab= li++)) + { + CalpontSystemCatalog::TableAliasName ta = make_aliasview( + (tab->db ? table->db : ""), + (tab->table_name ? tab->table_name : ""), + (tab->alias ? tab->alias : ""), + getViewName(tab)); + gwi.innerTables.insert(ta); + } + } + if (table->on_expr) + { + Item_cond* expr = reinterpret_cast(table->on_expr); +#ifdef DEBUG_WALK_COND + expr->traverse_cond(debug_walk, &gwi, Item::POSTFIX); +#endif + expr->traverse_cond(gp_walk, &gwi, Item::POSTFIX); + } + if (table->nested_join && &(table->nested_join->join_list)) + { + buildNestedTableOuterJoin(gwi, table); + } + } +} + uint32_t buildOuterJoin(gp_walk_info& gwi, SELECT_LEX& select_lex) { // check non-collapsed outer join @@ -476,6 +533,20 @@ uint32_t buildOuterJoin(gp_walk_info& gwi, SELECT_LEX& select_lex) { Item_cond* expr = reinterpret_cast(table_ptr->on_expr); gwi_outer.innerTables.insert(tan); + if (table_ptr->nested_join && &(table_ptr->nested_join->join_list)) + { + TABLE_LIST *table; + List_iterator li(table_ptr->nested_join->join_list); + while ((table= li++)) + { + CalpontSystemCatalog::TableAliasName ta = make_aliasview( + (table->db ? table->db : ""), + (table->table_name ? table->table_name : ""), + (table->alias ? table->alias : ""), + getViewName(table)); + gwi_outer.innerTables.insert(ta); + } + } #ifdef DEBUG_WALK_COND if (table_ptr->alias) @@ -487,12 +558,17 @@ uint32_t buildOuterJoin(gp_walk_info& gwi, SELECT_LEX& select_lex) #endif expr->traverse_cond(gp_walk, &gwi_outer, Item::POSTFIX); } + if (table_ptr->nested_join && &(table_ptr->nested_join->join_list)) + { + buildNestedTableOuterJoin(gwi_outer, table_ptr); + } // this part is ambiguous. Not quite sure how MySQL's lay out the outer join filters in the structure - else if (table_ptr->embedding && table_ptr->embedding->outer_join && table_ptr->embedding->on_expr) + if (table_ptr->embedding && table_ptr->embedding->outer_join && table_ptr->embedding->sj_on_expr) { // all the tables in nested_join are inner tables. TABLE_LIST *table; List_iterator li(table_ptr->embedding->nested_join->join_list); + gwi_outer.innerTables.clear(); while ((table= li++)) { CalpontSystemCatalog:: TableAliasName ta = make_aliasview( @@ -506,7 +582,7 @@ uint32_t buildOuterJoin(gp_walk_info& gwi, SELECT_LEX& select_lex) if (embeddingSet.find(table_ptr->embedding) != embeddingSet.end()) continue; embeddingSet.insert(table_ptr->embedding); - Item_cond* expr = reinterpret_cast(table_ptr->embedding->on_expr); + Item_cond* expr = reinterpret_cast(table_ptr->embedding->sj_on_expr); #ifdef DEBUG_WALK_COND cout << "inner tables: " << endl; @@ -519,7 +595,7 @@ uint32_t buildOuterJoin(gp_walk_info& gwi, SELECT_LEX& select_lex) expr->traverse_cond(gp_walk, &gwi_outer, Item::POSTFIX); } // @bug 2849 - else if (table_ptr->embedding && table_ptr->embedding->nested_join) + if (table_ptr->embedding && table_ptr->embedding->nested_join) { // if this is dervied table process phase, mysql may have not developed the plan // completely. Return and let it finish. It will come to rnd_init again. @@ -535,6 +611,7 @@ uint32_t buildOuterJoin(gp_walk_info& gwi, SELECT_LEX& select_lex) if (embeddingSet.find(table_ptr->embedding) != embeddingSet.end()) continue; + gwi_outer.innerTables.clear(); gwi_outer.innerTables.insert(tan); embeddingSet.insert(table_ptr->embedding); List *inners = &(table_ptr->embedding->nested_join->join_list); @@ -542,12 +619,12 @@ uint32_t buildOuterJoin(gp_walk_info& gwi, SELECT_LEX& select_lex) TABLE_LIST* curr; while ((curr = li++)) { - if (curr->on_expr) + if (curr->sj_on_expr) { if (!curr->outer_join) // only handle nested JOIN for now { gwi_outer.innerTables.clear(); - Item_cond* expr = reinterpret_cast(curr->on_expr); + Item_cond* expr = reinterpret_cast(curr->sj_on_expr); #ifdef DEBUG_WALK_COND expr->traverse_cond(debug_walk, &gwi_outer, Item::POSTFIX); @@ -628,7 +705,7 @@ ParseTree* buildRowPredicate(RowColumn* lhs, RowColumn* rhs, string predicateOp) return pt; } -void buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, Item_func* ifp) +bool buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, Item_func* ifp) { if (ifp->functype() == Item_func::EQ_FUNC || ifp->functype() == Item_func::NE_FUNC) { @@ -653,7 +730,7 @@ void buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It predicateOp = "="; logicOp = "or"; } - LogicOperator *lo = new LogicOperator(logicOp); + scoped_ptr lo(new LogicOperator(logicOp)); // 1st round. build the equivalent filters // two entries have been popped from the stack already: lhs and rhs @@ -688,7 +765,7 @@ void buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It // done for NOTIN clause if (predicateOp == "<>") - return; + return true; // 2nd round. add the filter to favor casual partition for IN clause boost::shared_ptr sop; @@ -765,11 +842,12 @@ void buildRowColumnFilter(gp_walk_info* gwip, RowColumn* rhs, RowColumn* lhs, It { gwip->fatalParseError = true; gwip->parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_FUNC_MULTI_COL); - return; + return false; } + return true; } -void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) +bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) { boost::shared_ptr sop(new PredicateOperator(ifp->func_name())); if (!(gwip->thd->infinidb_vtable.cal_conn_info)) @@ -813,11 +891,12 @@ void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) // @bug5811. This filter string is for cross engine to use. // Use real table name. ifp->print(&str, QT_INFINIDB_DERIVED); - IDEBUG(cout << str.c_ptr() << endl); + //IDEBUG(cout << str.c_ptr() << endl); if (str.c_ptr()) cf->data(str.c_ptr()); ParseTree* ptp = new ParseTree(cf); gwip->ptWorkStack.push(ptp); + return true; } else if (ifp->functype() == Item_func::IN_FUNC) { @@ -832,8 +911,7 @@ void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) RowColumn *rlhs = dynamic_cast(lhs); if (rrhs && rlhs) { - buildRowColumnFilter(gwip, rrhs, rlhs, ifp); - return; + return buildRowColumnFilter(gwip, rrhs, rlhs, ifp); } ConstantColumn *crhs = dynamic_cast(rhs); @@ -842,7 +920,7 @@ void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) { gwip->fatalParseError = true; gwip->parseErrorText = "non constant value in IN clause"; - return; + return false; } string eqop; @@ -885,7 +963,7 @@ void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) gwip->fatalParseError = true; gwip->parseErrorText = "non constant value in IN clause"; delete cf; - return; + return false; } cf->functionName(gwip->funcName); String str; @@ -918,7 +996,7 @@ void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) { gwip->fatalParseError = true; gwip->parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_FILTER_COND_EXP); - return; + return false; } } @@ -947,7 +1025,7 @@ void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) oss << "Unknown user variable: " << udf->name.str; gwip->parseErrorText = oss.str(); gwip->fatalParseError = true; - return; + return false; } if (udf->result_type() == STRING_RESULT) @@ -956,8 +1034,10 @@ void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) { gwip->rcWorkStack.push(new ConstantColumn(buf.c_ptr(), ConstantColumn::NUM)); } + return false; } } +#if 0 else if (ifp->functype() == Item_func::NEG_FUNC) { //peek at the (hopefully) ConstantColumn on the top of stack, negate it in place @@ -978,14 +1058,15 @@ void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) newval = "-" + cval; ccp->constval(newval); } +#endif else if (ifp->functype() == Item_func::NOT_FUNC) { if (gwip->condPush && ifp->next->type() == Item::SUBSELECT_ITEM) - return; + return false; if (ifp->next && ifp->next->type() == Item::SUBSELECT_ITEM && gwip->lastSub) { gwip->lastSub->handleNot(); - return; + return false; } idbassert(ifp->argument_count() == 1); @@ -1017,16 +1098,44 @@ void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) rhs = buildReturnedColumn(ifp->arguments()[0], *gwip, gwip->fatalParseError); } if (rhs && !gwip->fatalParseError) - buildConstPredicate(ifp, rhs, gwip); + return buildConstPredicate(ifp, rhs, gwip); else if (!rhs) // @bug3802 { gwip->fatalParseError = true; gwip->parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_FILTER_COND_EXP); - return; + return false; } } } + else if (ifp->functype() == Item_func::MULT_EQUAL_FUNC) + { +#if 0 // MYSQL_5.6 + Item_equal* item_eq = (Item_equal*)ifp; + // This code is for mysql 5.6. Need to convert to MariaDB 10.1 + List_iterator_fast it(item_eq->fields); + idbassert(item_eq->fields.elements == 2); + // @todo handle more than 2 equal fields + Item *item_field = it++; + ReturnedColumn* lhs = buildReturnedColumn(item_field, *gwip, gwip->fatalParseError); + item_field = it++; + ReturnedColumn* rhs = buildReturnedColumn(item_field, *gwip, gwip->fatalParseError); + if (!rhs || !lhs) + { + gwip->fatalParseError = true; + gwip->parseErrorText = "Unsupport elements in MULT_EQUAL item"; + delete rhs; + delete lhs; + return false; + } + PredicateOperator *po = new PredicateOperator("="); + boost::shared_ptr sop(po); + sop->setOpType(lhs->resultType(), rhs->resultType()); + SimpleFilter *sf = new SimpleFilter(sop, lhs, rhs); + ParseTree *pt = new ParseTree(sf); + gwip->ptWorkStack.push(pt); +#endif + } else //std rel ops (incl "like") { if (gwip->rcWorkStack.size() < 2) @@ -1040,7 +1149,7 @@ void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) gwip->fatalParseError = true; gwip->parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_FILTER_COND_EXP); } - return; + return false; } ReturnedColumn* rhs = gwip->rcWorkStack.top(); @@ -1054,8 +1163,7 @@ void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) if (rrhs && rlhs) { - buildRowColumnFilter(gwip, rrhs, rlhs, ifp); - return; + return buildRowColumnFilter(gwip, rrhs, rlhs, ifp); } // push the column that is associated with the correlated column to the returned @@ -1125,7 +1233,7 @@ void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) IDEBUG( cout << "deleted func with 2 const columns" << endl ); delete rhs; delete lhs; - return; + return false; } // handle noop (only for table mode) @@ -1174,8 +1282,10 @@ void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) } if (notInner) + { lhs->returnAll(true); - IDEBUG( cout << "setting returnAll on " << tan_lhs << endl); + IDEBUG( cout << "setting returnAll on " << tan_lhs << endl); + } } if (!gwip->innerTables.empty()) { @@ -1188,8 +1298,10 @@ void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) } if (notInner) + { rhs->returnAll(true); - IDEBUG( cout << "setting returnAll on " << tan_rhs << endl ); + IDEBUG( cout << "setting returnAll on " << tan_rhs << endl ); + } } ParseTree* ptp = new ParseTree(sf); @@ -1208,9 +1320,10 @@ void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip) gwip->ptWorkStack.push(ptp); } } + return true; } -void buildConstPredicate(Item_func* ifp, ReturnedColumn* rhs, gp_walk_info* gwip) +bool buildConstPredicate(Item_func* ifp, ReturnedColumn* rhs, gp_walk_info* gwip) { SimpleFilter *sf = new SimpleFilter(); boost::shared_ptr sop(new PredicateOperator(ifp->func_name())); @@ -1249,6 +1362,7 @@ void buildConstPredicate(Item_func* ifp, ReturnedColumn* rhs, gp_walk_info* gwip sf->rhs(lhs); ParseTree* ptp = new ParseTree(sf); gwip->ptWorkStack.push(ptp); + return true; } SimpleColumn* buildSimpleColFromDerivedTable(gp_walk_info& gwi, Item_field* ifp) @@ -1547,6 +1661,8 @@ void buildSubselectFunc(Item_func* ifp, gp_walk_info* gwip) bool isPredicateFunction(Item* item, gp_walk_info* gwip) { + if (item->type() == Item::COND_ITEM) + return true; if (item->type() != Item::FUNC_ITEM) return false; Item_func* ifp = (Item_func*)item; @@ -1566,8 +1682,8 @@ bool isPredicateFunction(Item* item, gp_walk_info* gwip) ifp->functype() == Item_func::NOT_FUNC || ifp->functype() == Item_func::ISNOTNULLTEST_FUNC || ifp->functype() == Item_func::TRIG_COND_FUNC || - string(ifp->func_name()) == "" || - string(ifp->func_name()) == "xor"); + string(ifp->func_name()) == ""/* || + string(ifp->func_name()) == "xor"*/); } void setError(THD* thd, uint32_t errcode, string errmsg) @@ -2203,7 +2319,7 @@ ArithmeticColumn* buildArithmeticColumn(Item_func* item, gp_walk_info& gwi, bool // decimal arithmetic operation gives double result when the session variable is set. //idbassert(pt->left() && pt->right() && pt->left()->data() && pt->right()->data()); CalpontSystemCatalog::ColType mysql_type = colType_MysqlToIDB(item); - if (gwi.thd->variables.infinidb_double_for_decimal_math == 1) + if (current_thd->variables.infinidb_double_for_decimal_math == 1) aop->adjustResultType(mysql_type); else aop->resultType(mysql_type); @@ -2277,6 +2393,10 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non return rc; } + // TODO MariaDB 10.1: Until we figure out what to do with this + if (funcName == "multiple equal") + return NULL; + // Arithmetic exp if (funcName == "+" || funcName == "-" || funcName == "*" || funcName == "/" ) { @@ -2341,6 +2461,7 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non // @todo non-support function as argument. need to do post process. Assume all support for now fc = new FunctionColumn(); + fc->data(funcName); FunctionParm funcParms; SPTP sptp; ClauseType clauseType = gwi.clauseType; @@ -2368,7 +2489,7 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non } // special handling for function that takes a filter arguments, like if(). // @todo. merge this logic to buildParseTree(). - if (funcName == "if" && i == 0) + if ((funcName == "if" && i == 0) || funcName == "xor") { // make sure the rcWorkStack is cleaned. gwi.clauseType = WHERE; @@ -2383,7 +2504,8 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non continue; } // @bug 3039 - if (isPredicateFunction(ifp->arguments()[i], &gwi) || ifp->arguments()[i]->with_subselect) + //if (isPredicateFunction(ifp->arguments()[i], &gwi) || ifp->arguments()[i]->has_subquery()) + if (ifp->arguments()[i]->has_subquery()) { nonSupport = true; gwi.fatalParseError = true; @@ -2403,68 +2525,25 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non } else // where clause { - stack tmpPtStack;; - for (uint32_t i = 0; i < ifp->argument_count(); i++) + stack tmpPtStack; + for (int32_t i = ifp->argument_count(); i>0; i--) { - if (funcName == "if" ) + if (isPredicateFunction((ifp->arguments()[i]), &gwi) && !gwi.ptWorkStack.empty()) { - // bug5438 - gwi.clauseType = SELECT; - if (i == 0) - { - // @bug 2366. build item from arguments to avoid parm sequence complexity - sptp.reset(buildParseTree((Item_func*)(ifp->arguments()[i]), gwi, nonSupport)); - if (nonSupport) - return NULL; - funcParms.push_back(sptp); - if (!gwi.ptWorkStack.empty()) - gwi.ptWorkStack.pop(); - continue; - } - else - { - ReturnedColumn *rc = buildReturnedColumn(ifp->arguments()[i], gwi, nonSupport); - if (!rc || nonSupport) - { - nonSupport = true; - return NULL; - } - sptp.reset(new ParseTree(rc)); - funcParms.push_back(sptp); - if (!gwi.rcWorkStack.empty()) - gwi.rcWorkStack.pop(); - } - gwi.clauseType = clauseType; + sptp.reset(gwi.ptWorkStack.top()); + tmpPtStack.push(sptp); + gwi.ptWorkStack.pop(); + } + else if (!isPredicateFunction((ifp->arguments()[i]), &gwi) && !gwi.rcWorkStack.empty()) + { + sptp.reset(new ParseTree(gwi.rcWorkStack.top())); + tmpPtStack.push(sptp); + gwi.rcWorkStack.pop(); } else { - if (isPredicateFunction(ifp->arguments()[i], &gwi) || ifp->arguments()[i]->with_subselect) - { - nonSupport = true; - gwi.fatalParseError = true; - gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_SUB_EXPRESSION); - return NULL; - } - else - { - if (gwi.rcWorkStack.empty()) - { - ReturnedColumn *rc = buildReturnedColumn(ifp->arguments()[i], gwi, nonSupport); - if (!rc || nonSupport) - { - nonSupport = true; - gwi.fatalParseError = true; - return NULL; - } - sptp.reset(new ParseTree(buildReturnedColumn(ifp->arguments()[i], gwi, nonSupport))); - } - else - { - sptp.reset(new ParseTree(gwi.rcWorkStack.top())); - gwi.rcWorkStack.pop(); - } - } - tmpPtStack.push(sptp); + nonSupport = true; + return NULL; } } @@ -2600,6 +2679,23 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non // MySQL give string result type for date function, but has the flag set. // we should set the result type to be datetime for comparision. + if (ifp->field_type() == MYSQL_TYPE_DATETIME || + ifp->field_type() == MYSQL_TYPE_TIMESTAMP || + funcName == "add_time") + { + CalpontSystemCatalog::ColType ct; + ct.colDataType = CalpontSystemCatalog::DATETIME; + ct.colWidth = 8; + fc->resultType(ct); + } + else if (ifp->field_type() == MYSQL_TYPE_DATE) + { + CalpontSystemCatalog::ColType ct; + ct.colDataType = CalpontSystemCatalog::DATE; + ct.colWidth = 4; + fc->resultType(ct); + } +#if 0 if (is_temporal_type_with_date(ifp->field_type())) { CalpontSystemCatalog::ColType ct; @@ -2614,6 +2710,7 @@ ReturnedColumn* buildFunctionColumn(Item_func* ifp, gp_walk_info& gwi, bool& non ct.colWidth = 4; fc->resultType(ct); } +#endif fc->operationType(functor->operationType(funcParms, fc->resultType())); fc->expressionId(ci->expressionId++); @@ -3002,10 +3099,11 @@ ParseTree* buildParseTree(Item_func* item, gp_walk_info& gwi, bool& nonSupport) { ParseTree* pt = 0; Item_cond* icp = (Item_cond*)item; +#ifdef DEBUG_WALK_COND // debug - //cout << "Build Parsetree: " << endl; - //icp->traverse_cond(debug_walk, &gwi, Item::POSTFIX); - + cout << "Build Parsetree: " << endl; + icp->traverse_cond(debug_walk, &gwi, Item::POSTFIX); +#endif //@bug5044. PPSTFIX walking should always be treated as WHERE clause filter ClauseType clauseType = gwi.clauseType; gwi.clauseType = WHERE; @@ -3036,7 +3134,8 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) cal_connection_info* ci = reinterpret_cast(gwi.thd->infinidb_vtable.cal_conn_info); Item_sum* isp = reinterpret_cast(item); - Item** sfitempp = isp->arguments(); + Item** sfitempp = isp->get_orig_args(); +// Item** sfitempp = isp->arguments(); SRCP parm; // @bug4756 if (gwi.clauseType == SELECT) @@ -3105,7 +3204,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi) { rc = buildReturnedColumn(ord_col, gwi, gwi.fatalParseError); } - rc->asc((*order_item)->asc); + rc->asc((*order_item)->asc); orderCols.push_back(SRCP(rc)); } @@ -3481,14 +3580,22 @@ void gp_walk(const Item *item, void *arg) { gp_walk_info* gwip = reinterpret_cast(arg); idbassert(gwip); + bool isCached = false; //Bailout... if (gwip->fatalParseError) return; RecursionCounter r(gwip); // Increments and auto-decrements upon exit. Item::Type itype = item->type(); - if (itype == Item::FUNC_ITEM && string(((Item_func*)item)->func_name()) == "xor") - itype = Item::COND_ITEM; + //if (itype == Item::FUNC_ITEM && string(((Item_func*)item)->func_name()) == "xor") + // itype = Item::COND_ITEM; + + if(item->type() == Item::CACHE_ITEM) + { + item = ((Item_cache*)item)->get_example(); + itype = item->type(); + isCached = true; + } switch (itype) { @@ -3586,12 +3693,12 @@ void gp_walk(const Item *item, void *arg) if (!gwip->condPush) { - if (ifp->with_subselect || funcName == "") + if (ifp->has_subquery() || funcName == "") { buildSubselectFunc(ifp, gwip); return; } - if (ifp->arguments() && ifp->argument_count() > 0) + if (ifp->argument_count() > 0 && ifp->arguments()) { for (uint32_t i = 0; i < ifp->argument_count(); i++) { @@ -3645,7 +3752,8 @@ void gp_walk(const Item *item, void *arg) !(parseInfo & SUB_BIT) && !nonConstFunc(ifp) && !(parseInfo & AF_BIT) && - tmpVec.size() == 0) + tmpVec.size() == 0 && + ifp->functype() != Item_func::MULT_EQUAL_FUNC) { String val, *str = ifp->val_str(&val); @@ -3668,11 +3776,14 @@ void gp_walk(const Item *item, void *arg) cc->resultType(colType_MysqlToIDB(item)); } - for (uint32_t i = 0; i < ifp->argument_count() && !gwip->rcWorkStack.empty(); i++) + // cached item comes in one piece + if (!isCached) { - gwip->rcWorkStack.pop(); + for (uint32_t i = 0; i < ifp->argument_count() && !gwip->rcWorkStack.empty(); i++) + { + gwip->rcWorkStack.pop(); + } } - // bug 3137. If filter constant like 1=0, put it to ptWorkStack // MariaDB bug 750. Breaks if compare is an argument to a function. if ((int32_t)gwip->rcWorkStack.size() <= (gwip->rcBookMarkStack.empty() ? 0 : gwip->rcBookMarkStack.top()) @@ -3974,6 +4085,48 @@ void gp_walk(const Item *item, void *arg) gwip->rcWorkStack.push(af); break; } + case Item::COPY_STR_ITEM: + printf("********** received COPY_STR_ITEM *********"); + break; + case Item::FIELD_AVG_ITEM: + printf("********** received FIELD_AVG_ITEM *********"); + break; + case Item::DEFAULT_VALUE_ITEM: + printf("********** received DEFAULT_VALUE_ITEM *********"); + break; + case Item::PROC_ITEM: + printf("********** received PROC_ITEM *********"); + break; + case Item::FIELD_STD_ITEM: + printf("********** received FIELD_STD_ITEM *********"); + break; + case Item::FIELD_VARIANCE_ITEM: + printf("********** received FIELD_VARIANCE_ITEM *********"); + break; + case Item::INSERT_VALUE_ITEM: + printf("********** received INSERT_VALUE_ITEM *********"); + break; + case Item::Item::TYPE_HOLDER: + printf("********** received TYPE_HOLDER *********"); + break; + case Item::PARAM_ITEM: + printf("********** received PARAM_ITEM *********"); + break; + case Item::TRIGGER_FIELD_ITEM: + printf("********** received TRIGGER_FIELD_ITEM *********"); + break; + case Item::XPATH_NODESET: + printf("********** received XPATH_NODESET *********"); + break; + case Item::XPATH_NODESET_CMP: + printf("********** received XPATH_NODESET_CMP *********"); + break; + case Item::VIEW_FIXER_ITEM: + printf("********** received VIEW_FIXER_ITEM *********"); + break; + case Item::DATE_ITEM: + printf("********** received DATE_ITEM *********"); + break; default: { if (gwip->condPush) @@ -4029,7 +4182,8 @@ void parse_item (Item *item, vector& field_vec, bool& hasNonSupport } Item** sfitempp = isp->arguments(); for (uint32_t i = 0; i < isp->argument_count(); i++) - parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo); + parse_item(isp->arguments()[i], field_vec, hasNonSupportItem, parseInfo); +// parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo); break; } case Item::COND_ITEM: @@ -4223,6 +4377,16 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i TABLE_LIST* table_ptr = select_lex.get_table_list(); CalpontSelectExecutionPlan::SelectList derivedTbList; +// DEBUG +#ifdef DEBUG_WALK_COND + List_iterator sj_list_it(select_lex.sj_nests); + TABLE_LIST *sj_nest; + while ((sj_nest= sj_list_it++)) + { + cout << sj_nest->db << "." << sj_nest->table_name << endl; + } +#endif + // @bug 1796. Remember table order on the FROM list. gwi.clauseType = FROM; try { @@ -4248,6 +4412,12 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i // @todo process from subquery if (table_ptr->derived) { + //cout << "DERIVED TABLE DEBUG" << endl; + //String str; + //(table_ptr->derived->first_select())->print(gwi.thd, &str, QT_INFINIDB_DERIVED); + //cout << str.ptr() << endl; + //cout << "DERIVED TABLE DEBUG END" << endl; + SELECT_LEX *select_cursor = table_ptr->derived->first_select(); FromSubQuery fromSub(gwi, select_cursor); string alias(table_ptr->alias); @@ -4298,6 +4468,9 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i gwi.tbList.push_back(tn); CalpontSystemCatalog::TableAliasName tan = make_aliastable(table_ptr->db, table_name, table_ptr->alias, infiniDB); gwi.tableMap[tan] = make_pair(0,table_ptr); +#ifdef DEBUG_WALK_COND + cout << tn << endl; +#endif } } if (gwi.fatalParseError) @@ -4426,23 +4599,30 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i return ER_CHECK_NOT_IMPLEMENTED; } } + else if (join && join->zero_result_cause) + { + gwi.rcWorkStack.push(new ConstantColumn((int64_t)0, ConstantColumn::NUM)); + } + - // ZZ - the followinig debug shows the structure of nested outer join. should - // use a recursive function. + // ZZ - the followinig debug shows the structure of nested outer join. should + // use a recursive function. #ifdef OUTER_JOIN_DEBUG - List *tables = &(select_lex.top_join_list); - List_iterator_fast ti(*tables); - TABLE_LIST *inner; - TABLE_LIST **table= (TABLE_LIST **)gwi.thd->alloc(sizeof(TABLE_LIST*) * tables->elements); - for (TABLE_LIST **t= table + (tables->elements - 1); t >= table; t--) - *t= ti++; + List *tables = &(select_lex.top_join_list); + List_iterator_fast ti(*tables); + //TABLE_LIST *inner; + //TABLE_LIST **table= (TABLE_LIST **)gwi.thd->alloc(sizeof(TABLE_LIST*) * tables->elements); + //for (TABLE_LIST **t= table + (tables->elements - 1); t >= table; t--) + // *t= ti++; - DBUG_ASSERT(tables->elements >= 1); + //DBUG_ASSERT(tables->elements >= 1); - TABLE_LIST **end= table + tables->elements; - for (TABLE_LIST **tbl= table; tbl < end; tbl++) - { - TABLE_LIST *curr= *tbl; + //TABLE_LIST **end= table + tables->elements; + //for (TABLE_LIST **tbl= table; tbl < end; tbl++) + TABLE_LIST *curr; + while ((curr= ti++)) + { + TABLE_LIST *curr= *tbl; if (curr->table_name) cout << curr->table_name << " "; else @@ -4466,20 +4646,21 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i { TABLE_LIST *curr1= *tb; cout << curr1->alias << endl; - if (curr1->on_expr) + if (curr1->sj_on_expr) { - curr1->on_expr->traverse_cond(debug_walk, &gwi, Item::POSTFIX); + curr1->sj_on_expr->traverse_cond(debug_walk, &gwi, Item::POSTFIX); } } } - if (curr->on_expr) + if (curr->sj_on_expr) { - curr->on_expr->traverse_cond(debug_walk, &gwi, Item::POSTFIX); + curr->sj_on_expr->traverse_cond(debug_walk, &gwi, Item::POSTFIX); } } #endif uint32_t failed = buildOuterJoin(gwi, select_lex); + if (failed) return failed; // @bug5764. build outer join for view, make sure outerjoin filter is appended // to the end of the filter list. @@ -4498,7 +4679,9 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i // @bug 2932. for "select * from region where r_name" case. if icp not null and // ptWorkStack empty, the item is in rcWorkStack. - if (icp && gwi.ptWorkStack.empty() && !gwi.rcWorkStack.empty()) + // MySQL 5.6 (MariaDB?). when icp is null and zero_result_cause is set, a constant 0 + // is pushed to rcWorkStack. + if (/*icp && */gwi.ptWorkStack.empty() && !gwi.rcWorkStack.empty()) { filters = new ParseTree(gwi.rcWorkStack.top()); gwi.rcWorkStack.pop(); @@ -4680,7 +4863,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i vector tmpVec; bool hasNonSupportItem = false; parse_item(ifp, tmpVec, hasNonSupportItem, parseInfo); - if (ifp->with_subselect || + if (ifp->has_subquery() || string(ifp->func_name()) == string("") || ifp->functype() == Item_func::NOT_ALL_FUNC || parseInfo & SUB_BIT) @@ -5442,7 +5625,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i { Item* ord_item = *(ordercol->item); // ignore not_used column on order by. - if (ord_item->type() == Item::INT_ITEM && ord_item->name && string(ord_item->name) == "Not_used") + if (ord_item->type() == Item::INT_ITEM && ord_item->full_name() && string(ord_item->full_name()) == "Not_used") continue; else if (ord_item->type() == Item::INT_ITEM) rc = gwi.returnedCols[((Item_int*)ord_item)->val_int()-1]->clone(); @@ -5637,19 +5820,22 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i { Item_field *field = reinterpret_cast(ord_item); ReturnedColumn *rc = buildSimpleColumn(field, gwi); - if (field->db_name) - fullname += string(field->db_name) + "."; - if (field->table_name) - fullname += string(field->table_name) + "."; - if (field->field_name) - fullname += string(field->field_name); + fullname = field->full_name(); +// if (field->db_name) +// fullname += string(field->db_name) + "."; +// if (field->table_name) +// fullname += string(field->table_name) + "."; +// if (field->field_name) +// fullname += string(field->field_name); for (uint32_t i = 0; i < gwi.returnedCols.size(); i++) { SimpleColumn* sc = dynamic_cast(gwi.returnedCols[i].get()); if (sc && ((Item_field*)ord_item)->cached_table && - (strcasecmp(getViewName(((Item_field*)ord_item)->cached_table).c_str(), sc->viewName().c_str()) != 0)) + (strcasecmp(getViewName(((Item_field*)ord_item)->cached_table).c_str(), sc->viewName().c_str()) != 0)) + { continue; + } if (strcasecmp(fullname.c_str(),gwi.returnedCols[i]->alias().c_str()) == 0 || strcasecmp(ord_item->name,gwi.returnedCols[i]->alias().c_str()) == 0) { diff --git a/dbcon/mysql/ha_calpont_impl.cpp b/dbcon/mysql/ha_calpont_impl.cpp index b96d48a50..d645d332a 100755 --- a/dbcon/mysql/ha_calpont_impl.cpp +++ b/dbcon/mysql/ha_calpont_impl.cpp @@ -656,7 +656,6 @@ int fetchNextRow(uchar *buf, cal_table_info& ti, cal_connection_info* ci) ti.c = 0; ti.moreRows = false; rc = HA_ERR_END_OF_FILE; - current_thd->infinidb_vtable.has_limit = true; ci->rc = rc; } else @@ -773,8 +772,10 @@ uint32_t doUpdateDelete(THD *thd) ci->stats.reset(); ci->stats.setStartTime(); ci->stats.fUser = thd->main_security_ctx.user; - if (thd->main_security_ctx.host) - ci->stats.fHost = thd->main_security_ctx.host; +// if (thd->main_security_ctx.host) +// ci->stats.fHost = thd->main_security_ctx.host; + if (thd->main_security_ctx.get_host()) + ci->stats.fHost = thd->main_security_ctx.get_host()->c_ptr(); else if (thd->main_security_ctx.host_or_ip) ci->stats.fHost = thd->main_security_ctx.host_or_ip; else @@ -828,7 +829,8 @@ uint32_t doUpdateDelete(THD *thd) } // @bug 1127. Re-construct update stmt using lex instead of using the original query. - string dmlStmt=""; +// string dmlStmt=""; + string dmlStmt=string(idb_mysql_query_str(thd)); string schemaName; string tableName(""); string aliasName(""); @@ -844,27 +846,27 @@ uint32_t doUpdateDelete(THD *thd) { ColumnAssignment* columnAssignmentPtr; Item_field *item; - TABLE_LIST* table_ptr = thd->lex->select_lex.get_table_list(); +// TABLE_LIST* table_ptr = thd->lex->select_lex.get_table_list(); List_iterator_fast field_it(thd->lex->select_lex.item_list); List_iterator_fast value_it(thd->lex->value_list); - dmlStmt += "update "; +// dmlStmt += "update "; updateCP->queryType(CalpontSelectExecutionPlan::UPDATE); ci->stats.fQueryType = updateCP->queryType(); uint32_t cnt = 0; - for (; table_ptr; table_ptr= table_ptr->next_local) - { - dmlStmt += string(table_ptr->table_name); - if (table_ptr->next_local) - dmlStmt += ", "; - } +// for (; table_ptr; table_ptr= table_ptr->next_local) +// { +// dmlStmt += string(table_ptr->table_name); +// if (table_ptr->next_local) +// dmlStmt += ", "; +// } - dmlStmt += " set "; +// dmlStmt += " set "; while ((item= (Item_field *) field_it++)) { cnt++; - dmlStmt += string(item->name) + "="; +// dmlStmt += string(item->name) + "="; string tmpTableName = bestTableName(item); @@ -913,7 +915,7 @@ uint32_t doUpdateDelete(THD *thd) //@Bug 2587 use val_str to replace value->name to get rid of 255 limit String val, *str; str = value->val_str(&val); - dmlStmt += "'" + string(str->c_ptr()) + "'"; +// dmlStmt += "'" + string(str->c_ptr()) + "'"; columnAssignmentPtr->fScalarExpression = string(str->c_ptr()) ; columnAssignmentPtr->fFromCol = false; } @@ -921,7 +923,7 @@ uint32_t doUpdateDelete(THD *thd) { String val, *str; str = value->val_str(&val); - dmlStmt += "'" + string(str->c_ptr()) + "'"; +// dmlStmt += "'" + string(str->c_ptr()) + "'"; columnAssignmentPtr->fScalarExpression = string(str->c_ptr()) ; columnAssignmentPtr->fFromCol = false; } @@ -995,7 +997,7 @@ uint32_t doUpdateDelete(THD *thd) { oss << value->val_int(); } - dmlStmt += oss.str(); +// dmlStmt += oss.str(); columnAssignmentPtr->fScalarExpression = oss.str(); columnAssignmentPtr->fFromCol = false; } @@ -1020,21 +1022,21 @@ uint32_t doUpdateDelete(THD *thd) } else if ( value->type() == Item::NULL_ITEM ) { - dmlStmt += "NULL"; +// dmlStmt += "NULL"; columnAssignmentPtr->fScalarExpression = "NULL"; columnAssignmentPtr->fFromCol = false; } else if ( value->type() == Item::SUBSELECT_ITEM ) { - isFromCol = true; - columnAssignmentPtr->fFromCol = true; - Item_field* setIt = reinterpret_cast (value); - string sectableName = string(setIt->table_name); - string secschemaName = string(setIt->db_name); - if ( (strcasecmp(tableName.c_str(), sectableName.c_str()) != 0) || (strcasecmp(schemaName.c_str(), secschemaName.c_str()) != 0)) - { +// isFromCol = true; +// columnAssignmentPtr->fFromCol = true; +// Item_field* setIt = reinterpret_cast (value); +// string sectableName = string(setIt->table_name); +// string secschemaName = string(setIt->db_name); +// if ( (strcasecmp(tableName.c_str(), sectableName.c_str()) != 0) || (strcasecmp(schemaName.c_str(), secschemaName.c_str()) != 0)) +// { isFromSameTable = false; - } +// } } //@Bug 4449 handle default value else if (value->type() == Item::DEFAULT_VALUE_ITEM) @@ -1043,7 +1045,7 @@ uint32_t doUpdateDelete(THD *thd) if (!tmp->field_name) //null { - dmlStmt += "NULL"; +// dmlStmt += "NULL"; columnAssignmentPtr->fScalarExpression = "NULL"; columnAssignmentPtr->fFromCol = false; } @@ -1051,7 +1053,7 @@ uint32_t doUpdateDelete(THD *thd) { String val, *str; str = value->val_str(&val); - dmlStmt += string(str->c_ptr()); +// dmlStmt += string(str->c_ptr()); columnAssignmentPtr->fScalarExpression = string(str->c_ptr()); columnAssignmentPtr->fFromCol = false; } @@ -1069,26 +1071,26 @@ uint32_t doUpdateDelete(THD *thd) str = value->val_str(&val); if (str) { - dmlStmt += string(str->c_ptr()); +// dmlStmt += string(str->c_ptr()); columnAssignmentPtr->fScalarExpression = string(str->c_ptr()); columnAssignmentPtr->fFromCol = false; } else { - dmlStmt += "NULL"; +// dmlStmt += "NULL"; columnAssignmentPtr->fScalarExpression = "NULL"; columnAssignmentPtr->fFromCol = false; } } colAssignmentListPtr->push_back ( columnAssignmentPtr ); - if (cnt < thd->lex->select_lex.item_list.elements) - dmlStmt += ", "; +// if (cnt < thd->lex->select_lex.item_list.elements) +// dmlStmt += ", "; } } else { - dmlStmt = string(idb_mysql_query_str(thd)); +// dmlStmt = string(idb_mysql_query_str(thd)); updateCP->queryType(CalpontSelectExecutionPlan::DELETE); ci->stats.fQueryType = updateCP->queryType(); } @@ -1126,7 +1128,7 @@ uint32_t doUpdateDelete(THD *thd) ci->tableOid = roPair.objnum; CalpontDMLPackage* pDMLPackage = 0; - dmlStmt += ";"; +// dmlStmt += ";"; IDEBUG( cout << "STMT: " << dmlStmt << " and sessionID " << thd->thread_id << endl ); VendorDMLStatement dmlStatement(dmlStmt, sessionID); if (( (thd->lex)->sql_command == SQLCOM_UPDATE ) || ( (thd->lex)->sql_command == SQLCOM_UPDATE_MULTI ) ) @@ -1314,14 +1316,6 @@ uint32_t doUpdateDelete(THD *thd) } if ( notFirst ) { - //error out for now. Wait for scalar join. -/* Message::Args args; - string emsg(IDBErrorInfo::instance()->errorMsg(ERR_COLUMN_EQ_DIFFTABLE_COLUMN, args)); - thd->raise_error_printf(ER_INTERNAL_ERROR, emsg.c_str()); - ci->rc = 1; - thd->set_row_count_func(0); - return 0; -*/ CalpontSystemCatalog::TableAliasName tn = make_aliastable(schemaName, tableName, aliasName); iter = tbList.begin(); tbList.insert( iter, 1, tn ); @@ -1669,7 +1663,7 @@ uint32_t doUpdateDelete(THD *thd) } else { - if (dmlRowCount != 0) //Bug 5117. Handling self join. +// if (dmlRowCount != 0) //Bug 5117. Handling self join. thd->set_row_count_func(dmlRowCount); @@ -2433,6 +2427,12 @@ int ha_calpont_impl_rnd_init(TABLE* table) idbassert(ci != 0); + // MySQL sometimes calls rnd_init multiple times, plan should only be + // generated and sent once. + if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE && + !thd->infinidb_vtable.isNewQuery) + return 0; + if(thd->killed == KILL_QUERY || thd->killed == KILL_QUERY_HARD) { if (ci->cal_conn_hndl) @@ -2450,7 +2450,6 @@ int ha_calpont_impl_rnd_init(TABLE* table) sm::sm_cleanup(ci->cal_conn_hndl); ci->cal_conn_hndl = 0; } - thd->infinidb_vtable.has_limit = false; return 0; } @@ -2545,8 +2544,10 @@ int ha_calpont_impl_rnd_init(TABLE* table) ci->stats.reset(); // reset query stats ci->stats.setStartTime(); ci->stats.fUser = thd->main_security_ctx.user; - if (thd->main_security_ctx.host) - ci->stats.fHost = thd->main_security_ctx.host; +// if (thd->main_security_ctx.host) +// ci->stats.fHost = thd->main_security_ctx.host; + if (thd->main_security_ctx.get_host()) + ci->stats.fHost = thd->main_security_ctx.get_host()->c_ptr(); else if (thd->main_security_ctx.host_or_ip) ci->stats.fHost = thd->main_security_ctx.host_or_ip; else @@ -2558,7 +2559,6 @@ int ha_calpont_impl_rnd_init(TABLE* table) string msg = string("InfiniDB User Priority - ") + e.what(); ci->warningMsg = msg; } - thd->infinidb_vtable.has_limit = false; // if the previous query has error, re-establish the connection if (ci->queryState != 0) @@ -2753,6 +2753,11 @@ int ha_calpont_impl_rnd_init(TABLE* table) } } + // set query state to be in_process. Sometimes mysql calls rnd_init multiple + // times, this makes sure plan only being generated and sent once. It will be + // reset when query finishes in sm::end_query + thd->infinidb_vtable.isNewQuery = false; + // common path for both vtable select phase and table mode -- open scan handle ti = ci->tableMap[table]; ti.msTablePtr = table; @@ -2904,7 +2909,6 @@ int ha_calpont_impl_rnd_next(uchar *buf, TABLE* table) sm::sm_cleanup(ci->cal_conn_hndl); ci->cal_conn_hndl = 0; } - thd->infinidb_vtable.has_limit = false; return 0; } @@ -2916,13 +2920,6 @@ int ha_calpont_impl_rnd_next(uchar *buf, TABLE* table) if (!ti.tpl_ctx || !ti.tpl_scan_ctx) { - // @bug 2135. Changed wording of error message below. If error already - // set, do not reset. - if (!thd->get_stmt_da()->is_error()) - { - string emsg = "Cannot open table handle for " + string(table->s->table_name.str) + "."; - setError(thd, ER_INTERNAL_ERROR, emsg); - } CalpontSystemCatalog::removeCalpontSystemCatalog(tid2sid(thd->thread_id)); return ER_INTERNAL_ERROR; } @@ -3017,7 +3014,6 @@ int ha_calpont_impl_rnd_end(TABLE* table) } sm::sm_cleanup(ci->cal_conn_hndl); ci->cal_conn_hndl = 0; - thd->infinidb_vtable.has_limit = false; // prevent connection re-established return rc; } } @@ -3052,7 +3048,6 @@ int ha_calpont_impl_rnd_end(TABLE* table) // clear querystats because no query stats available for cancelled query ci->queryStats = ""; } - thd->infinidb_vtable.has_limit = false; return 0; } @@ -3174,13 +3169,6 @@ int ha_calpont_impl_delete_table(const char *name) TABLE_LIST *first_table= (TABLE_LIST*) thd->lex->select_lex.table_list.first; - // should never get in here - if (!first_table) - { - setError(thd, ER_INTERNAL_ERROR, "Null table pointer detected when dropping table"); - return 1; - } - if (!ci) return 0; //@Bug 1948,2306. if alter table want to drop the old table, InfiniDB does not need to drop. @@ -3420,10 +3408,10 @@ void ha_calpont_impl_start_bulk_insert(ha_rows rows, TABLE* table) ci->mysqld_pid = getpid(); //get delimiter - if (char(thd->variables.infinidb_import_for_batchinsert_delimiter) != '\7') + if (char(thd->variables.infinidb_import_for_batchinsert_delimiter) != '\007') ci->delimiter = char(thd->variables.infinidb_import_for_batchinsert_delimiter); else - ci->delimiter = '\7'; + ci->delimiter = '\007'; //get enclosed by if (char(thd->variables.infinidb_import_for_batchinsert_enclosed_by) != 8) ci->enclosed_by = char(thd->variables.infinidb_import_for_batchinsert_enclosed_by); @@ -3734,8 +3722,10 @@ void ha_calpont_impl_start_bulk_insert(ha_rows rows, TABLE* table) ci->stats.reset(); ci->stats.setStartTime(); ci->stats.fUser = thd->main_security_ctx.user; - if (thd->main_security_ctx.host) - ci->stats.fHost = thd->main_security_ctx.host; +// if (thd->main_security_ctx.host) +// ci->stats.fHost = thd->main_security_ctx.host; + if (thd->main_security_ctx.get_host()) + ci->stats.fHost = thd->main_security_ctx.get_host()->c_ptr(); else if (thd->main_security_ctx.host_or_ip) ci->stats.fHost = thd->main_security_ctx.host_or_ip; else @@ -4017,6 +4007,12 @@ int ha_calpont_impl_end_bulk_insert(bool abort, TABLE* table) int ha_calpont_impl_commit (handlerton *hton, THD *thd, bool all) { + if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE || + thd->infinidb_vtable.vtable_state == THD::INFINIDB_ALTER_VTABLE || + thd->infinidb_vtable.vtable_state == THD::INFINIDB_DROP_VTABLE || + thd->infinidb_vtable.vtable_state == THD::INFINIDB_REDO_PHASE1) + return 0; + if (!thd->infinidb_vtable.cal_conn_info) thd->infinidb_vtable.cal_conn_info = (void*)(new cal_connection_info()); cal_connection_info* ci = reinterpret_cast(thd->infinidb_vtable.cal_conn_info); @@ -4130,14 +4126,6 @@ int ha_calpont_impl_rename_table(const char* from, const char* to) } else if ( thd->infinidb_vtable.vtable_state == THD::INFINIDB_ALTER_VTABLE ) return 0; - else - { -#if 0 - thd->get_stmt_da()->set_overwrite_status(true); - thd->raise_error_printf(ER_CHECK_NOT_IMPLEMENTED, "Syntax is not supported in InfiniDB."); - return 1; -#endif - } int rc = ha_calpont_impl_rename_table_(from, to, *ci); return rc; @@ -4255,7 +4243,6 @@ int ha_calpont_impl_external_lock(THD *thd, TABLE* table, int lock_type) sm::sm_cleanup(ci->cal_conn_hndl); ci->cal_conn_hndl = 0; } - thd->infinidb_vtable.has_limit = false; return 0; } @@ -4307,7 +4294,6 @@ int ha_calpont_impl_external_lock(THD *thd, TABLE* table, int lock_type) ci->miniStats = ci->cal_conn_hndl->miniStats; ci->queryState = 0; thd->infinidb_vtable.override_largeside_estimate = false; - thd->infinidb_vtable.has_limit = false; } } ci->tableMap.erase(table); diff --git a/dbcon/mysql/ha_calpont_impl_if.h b/dbcon/mysql/ha_calpont_impl_if.h index bfb530986..657f1a763 100644 --- a/dbcon/mysql/ha_calpont_impl_if.h +++ b/dbcon/mysql/ha_calpont_impl_if.h @@ -317,13 +317,13 @@ void castTypeArgs(Item_func* ifp, funcexp::FunctionParm& functionParms); void parse_item (Item *item, std::vector& field_vec, bool& hasNonSupportItem, uint16& parseInfo); bool isPredicateFunction(Item* item, gp_walk_info* gwip); execplan::ParseTree* buildRowPredicate(execplan::RowColumn* lhs, execplan::RowColumn* rhs, std::string predicateOp); -void buildRowColumnFilter(gp_walk_info* gwip, execplan::RowColumn* rhs, execplan::RowColumn* lhs, Item_func* ifp); -void buildPredicateItem(Item_func* ifp, gp_walk_info* gwip); +bool buildRowColumnFilter(gp_walk_info* gwip, execplan::RowColumn* rhs, execplan::RowColumn* lhs, Item_func* ifp); +bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip); void collectAllCols(gp_walk_info& gwi, Item_field* ifp); void buildSubselectFunc(Item_func* ifp, gp_walk_info* gwip); uint32_t buildOuterJoin(gp_walk_info& gwi, SELECT_LEX& select_lex); std::string getViewName(TABLE_LIST* table_ptr); -void buildConstPredicate(Item_func* ifp, execplan::ReturnedColumn* rhs, gp_walk_info* gwip); +bool buildConstPredicate(Item_func* ifp, execplan::ReturnedColumn* rhs, gp_walk_info* gwip); execplan::CalpontSystemCatalog::ColType fieldType_MysqlToIDB (const Field* field); execplan::CalpontSystemCatalog::ColType colType_MysqlToIDB (const Item* item); execplan::SPTP getIntervalType(int interval_type); diff --git a/dbcon/mysql/ha_pseudocolumn.cpp b/dbcon/mysql/ha_pseudocolumn.cpp index 3450b94f2..a993b18cf 100755 --- a/dbcon/mysql/ha_pseudocolumn.cpp +++ b/dbcon/mysql/ha_pseudocolumn.cpp @@ -489,7 +489,7 @@ execplan::ReturnedColumn* buildPseudoColumn(Item* item, cc = new ConstantColumn(localPm); else cc = new ConstantColumn("", ConstantColumn::NULLDATA); - cc->alias(ifp->name? ifp->name : ""); + cc->alias(ifp->full_name() ? ifp->full_name() : ""); return cc; } @@ -559,7 +559,7 @@ execplan::ReturnedColumn* buildPseudoColumn(Item* item, // operation type integer funcexp::Func_idbpartition* idbpartition = new funcexp::Func_idbpartition(); fc->operationType(idbpartition->operationType(parms, fc->resultType())); - fc->alias(ifp->name? ifp->name : ""); + fc->alias(ifp->full_name() ? ifp->full_name() : ""); return fc; } diff --git a/dbcon/mysql/ha_scalar_sub.cpp b/dbcon/mysql/ha_scalar_sub.cpp index d4aa1ca5e..7e7a3459e 100755 --- a/dbcon/mysql/ha_scalar_sub.cpp +++ b/dbcon/mysql/ha_scalar_sub.cpp @@ -288,7 +288,8 @@ execplan::ParseTree* ScalarSub::buildParseTree(PredicateOperator* op) csep->tableList(tblist); csep->derivedTableList(derivedTbList); - if (fSub->is_correlated) +// if (fSub->is_correlated) + if (fSub->unit->first_select()->master_unit()->uncacheable) { SelectFilter *subFilter = new SelectFilter(); subFilter->correlated(true); diff --git a/dbcon/mysql/ha_window_function.cpp b/dbcon/mysql/ha_window_function.cpp index f14b633cf..2d17965c4 100755 --- a/dbcon/mysql/ha_window_function.cpp +++ b/dbcon/mysql/ha_window_function.cpp @@ -427,8 +427,8 @@ ReturnedColumn* buildWindowFunctionColumn(Item* item, gp_walk_info& gwi, bool& n ac->adjustResultType(); ac->expressionId(ci->expressionId++); - if (item->name) - ac->alias(item->name); + if (item->full_name()) + ac->alias(item->full_name()); // put ac on windowFuncList gwi.windowFuncList.push_back(ac);