You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-29 08:21:15 +03:00
MCOL-1052 WIP Working with HAVING over agg functions problem.
This commit is contained in:
@ -20,8 +20,8 @@ SET ( libcalmysql_SRCS
|
|||||||
ha_pseudocolumn.cpp)
|
ha_pseudocolumn.cpp)
|
||||||
|
|
||||||
add_definitions(-DMYSQL_DYNAMIC_PLUGIN)
|
add_definitions(-DMYSQL_DYNAMIC_PLUGIN)
|
||||||
add_definitions(-DDEBUG_WALK_COND)
|
add_definitions(-DDEBUG_WALK_COND=1)
|
||||||
add_definitions(-DINFINIDB_DEBUG)
|
add_definitions(-DINFINIDB_DEBUG=1)
|
||||||
#add_definitions(-DOUTER_JOIN_DEBUG)
|
#add_definitions(-DOUTER_JOIN_DEBUG)
|
||||||
|
|
||||||
set_source_files_properties(ha_calpont.cpp PROPERTIES COMPILE_FLAGS "-fno-rtti -fno-implicit-templates")
|
set_source_files_properties(ha_calpont.cpp PROPERTIES COMPILE_FLAGS "-fno-rtti -fno-implicit-templates")
|
||||||
|
@ -1139,9 +1139,7 @@ static MYSQL_SYSVAR_ULONG(
|
|||||||
0);
|
0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*@brief ha_calpont_impl_group_by_init - Get data for MariaDB group_by
|
/*@brief create_calpont_group_by_handler- Creates handler*/
|
||||||
pushdown handler
|
|
||||||
*/
|
|
||||||
/***********************************************************
|
/***********************************************************
|
||||||
* DESCRIPTION:
|
* DESCRIPTION:
|
||||||
* Creates a group_by pushdown handler.
|
* Creates a group_by pushdown handler.
|
||||||
@ -1158,16 +1156,27 @@ create_calpont_group_by_handler(THD *thd, Query *query)
|
|||||||
{
|
{
|
||||||
ha_calpont_group_by_handler *handler = NULL;
|
ha_calpont_group_by_handler *handler = NULL;
|
||||||
|
|
||||||
handler = new ha_calpont_group_by_handler(thd, query);
|
if ( thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE )
|
||||||
|
{
|
||||||
|
handler = new ha_calpont_group_by_handler(thd, query);
|
||||||
|
|
||||||
|
// Notify the server, that CS handles GROUP BY, ORDER BY and HAVING clauses.
|
||||||
|
query->group_by = NULL;
|
||||||
|
query->order_by = NULL;
|
||||||
|
query->having = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Notify the server, that CS handles GROUP BY, ORDER BY and HAVING clauses.
|
|
||||||
query->group_by = NULL;
|
|
||||||
query->order_by = NULL;
|
|
||||||
query->having = NULL;
|
|
||||||
|
|
||||||
|
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* DESCRIPTION:
|
||||||
|
* Makes the plan and prepares the data
|
||||||
|
* RETURN:
|
||||||
|
* int rc
|
||||||
|
***********************************************************/
|
||||||
int ha_calpont_group_by_handler::init_scan()
|
int ha_calpont_group_by_handler::init_scan()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("ha_calpont_group_by_handler::init_scan");
|
DBUG_ENTER("ha_calpont_group_by_handler::init_scan");
|
||||||
@ -1181,6 +1190,12 @@ int ha_calpont_group_by_handler::init_scan()
|
|||||||
DBUG_RETURN(rc);
|
DBUG_RETURN(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* DESCRIPTION:
|
||||||
|
* Fetches a row and saves it to a temporary table.
|
||||||
|
* RETURN:
|
||||||
|
* int rc
|
||||||
|
***********************************************************/
|
||||||
int ha_calpont_group_by_handler::next_row()
|
int ha_calpont_group_by_handler::next_row()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("ha_calpont_group_by_handler::next_row");
|
DBUG_ENTER("ha_calpont_group_by_handler::next_row");
|
||||||
@ -1189,6 +1204,12 @@ int ha_calpont_group_by_handler::next_row()
|
|||||||
DBUG_RETURN(rc);
|
DBUG_RETURN(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* DESCRIPTION:
|
||||||
|
* Shuts the scan down.
|
||||||
|
* RETURN:
|
||||||
|
* int rc
|
||||||
|
***********************************************************/
|
||||||
int ha_calpont_group_by_handler::end_scan()
|
int ha_calpont_group_by_handler::end_scan()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("ha_calpont_group_by_handler::end_scan");
|
DBUG_ENTER("ha_calpont_group_by_handler::end_scan");
|
||||||
@ -1196,7 +1217,6 @@ int ha_calpont_group_by_handler::end_scan()
|
|||||||
int rc = ha_calpont_impl_group_by_end(this, table);
|
int rc = ha_calpont_impl_group_by_end(this, table);
|
||||||
|
|
||||||
DBUG_RETURN(rc);
|
DBUG_RETURN(rc);
|
||||||
// return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2713,7 +2713,7 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp
|
|||||||
|
|
||||||
if ( gwi.thd)
|
if ( gwi.thd)
|
||||||
{
|
{
|
||||||
if ( ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE ) || ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE_MULTI ))
|
//if ( ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE ) || ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE_MULTI ))
|
||||||
{
|
{
|
||||||
if ( !item->fixed)
|
if ( !item->fixed)
|
||||||
{
|
{
|
||||||
@ -2959,6 +2959,260 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnedColumn* buildReturnedColumnGr(Item* item, gp_walk_info& gwi, bool& nonSupport)
|
||||||
|
{
|
||||||
|
ReturnedColumn* rc = NULL;
|
||||||
|
|
||||||
|
if ( gwi.thd)
|
||||||
|
{
|
||||||
|
//if ( ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE ) || ((gwi.thd->lex)->sql_command == SQLCOM_UPDATE_MULTI ))
|
||||||
|
{
|
||||||
|
if ( !item->fixed)
|
||||||
|
{
|
||||||
|
item->fix_fields(gwi.thd, (Item**)&item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item::Type itype = Item::SUM_FUNC_ITEM;
|
||||||
|
|
||||||
|
switch (itype)
|
||||||
|
{
|
||||||
|
case Item::FIELD_ITEM:
|
||||||
|
{
|
||||||
|
Item_field* ifp = (Item_field*)item;
|
||||||
|
return buildSimpleColumn(ifp, gwi);
|
||||||
|
}
|
||||||
|
|
||||||
|
case Item::INT_ITEM:
|
||||||
|
case Item::VARBIN_ITEM:
|
||||||
|
{
|
||||||
|
String val, *str = item->val_str(&val);
|
||||||
|
string valStr;
|
||||||
|
valStr.assign(str->ptr(), str->length());
|
||||||
|
|
||||||
|
if (item->unsigned_flag)
|
||||||
|
{
|
||||||
|
//cc = new ConstantColumn(valStr, (uint64_t)item->val_uint(), ConstantColumn::NUM);
|
||||||
|
// It seems that str at this point is crap if val_uint() is > MAX_BIGINT. By using
|
||||||
|
// this constructor, ConstantColumn is built with the proper string. For whatever reason,
|
||||||
|
// ExeMgr converts the fConstval member to numeric, rather than using the existing numeric
|
||||||
|
// values available, so it's important to have fConstval correct.
|
||||||
|
rc = new ConstantColumn((uint64_t)item->val_uint(), ConstantColumn::NUM);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = new ConstantColumn(valStr, (int64_t)item->val_int(), ConstantColumn::NUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
//return cc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Item::STRING_ITEM:
|
||||||
|
{
|
||||||
|
String val, *str = item->val_str(&val);
|
||||||
|
string valStr;
|
||||||
|
valStr.assign(str->ptr(), str->length());
|
||||||
|
rc = new ConstantColumn(valStr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Item::REAL_ITEM:
|
||||||
|
{
|
||||||
|
String val, *str = item->val_str(&val);
|
||||||
|
string valStr;
|
||||||
|
valStr.assign(str->ptr(), str->length());
|
||||||
|
rc = new ConstantColumn(valStr, item->val_real());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Item::DECIMAL_ITEM:
|
||||||
|
{
|
||||||
|
rc = buildDecimalColumn(item, gwi);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Item::FUNC_ITEM:
|
||||||
|
{
|
||||||
|
Item_func* ifp = (Item_func*)item;
|
||||||
|
string func_name = ifp->func_name();
|
||||||
|
|
||||||
|
// try to evaluate const F&E. only for select clause
|
||||||
|
vector <Item_field*> tmpVec;
|
||||||
|
//bool hasAggColumn = false;
|
||||||
|
uint16_t parseInfo = 0;
|
||||||
|
parse_item(ifp, tmpVec, gwi.fatalParseError, parseInfo);
|
||||||
|
|
||||||
|
if (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);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gwi.fatalParseError &&
|
||||||
|
!nonConstFunc(ifp) &&
|
||||||
|
!(parseInfo & AF_BIT) &&
|
||||||
|
(tmpVec.size() == 0))
|
||||||
|
{
|
||||||
|
String val, *str = ifp->val_str(&val);
|
||||||
|
string valStr;
|
||||||
|
|
||||||
|
if (str)
|
||||||
|
{
|
||||||
|
valStr.assign(str->ptr(), str->length());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!str)
|
||||||
|
{
|
||||||
|
rc = new ConstantColumn("", ConstantColumn::NULLDATA);
|
||||||
|
}
|
||||||
|
else if (ifp->result_type() == STRING_RESULT)
|
||||||
|
{
|
||||||
|
rc = new ConstantColumn(valStr, ConstantColumn::LITERAL);
|
||||||
|
rc->resultType(colType_MysqlToIDB(item));
|
||||||
|
}
|
||||||
|
else if (ifp->result_type() == DECIMAL_RESULT)
|
||||||
|
rc = buildDecimalColumn(ifp, gwi);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = new ConstantColumn(valStr, ConstantColumn::NUM);
|
||||||
|
rc->resultType(colType_MysqlToIDB(item));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (func_name == "+" || func_name == "-" || func_name == "*" || func_name == "/" )
|
||||||
|
return buildArithmeticColumn(ifp, gwi, nonSupport);
|
||||||
|
else
|
||||||
|
return buildFunctionColumn(ifp, gwi, nonSupport);
|
||||||
|
}
|
||||||
|
|
||||||
|
case Item::SUM_FUNC_ITEM:
|
||||||
|
{
|
||||||
|
return buildAggregateColumn(item, gwi);
|
||||||
|
}
|
||||||
|
|
||||||
|
case Item::REF_ITEM:
|
||||||
|
{
|
||||||
|
Item_ref* ref = (Item_ref*)item;
|
||||||
|
|
||||||
|
switch ((*(ref->ref))->type())
|
||||||
|
{
|
||||||
|
case Item::SUM_FUNC_ITEM:
|
||||||
|
return buildAggregateColumn(*(ref->ref), gwi);
|
||||||
|
|
||||||
|
case Item::FIELD_ITEM:
|
||||||
|
return buildReturnedColumn(*(ref->ref), gwi, nonSupport);
|
||||||
|
|
||||||
|
case Item::REF_ITEM:
|
||||||
|
return buildReturnedColumn(*(((Item_ref*)(*(ref->ref)))->ref), gwi, nonSupport);
|
||||||
|
|
||||||
|
case Item::FUNC_ITEM:
|
||||||
|
return buildFunctionColumn((Item_func*)(*(ref->ref)), gwi, nonSupport);
|
||||||
|
|
||||||
|
case Item::WINDOW_FUNC_ITEM:
|
||||||
|
return buildWindowFunctionColumn(*(ref->ref), gwi, nonSupport);
|
||||||
|
|
||||||
|
default:
|
||||||
|
gwi.fatalParseError = true;
|
||||||
|
gwi.parseErrorText = "Unknown REF item";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case Item::NULL_ITEM:
|
||||||
|
{
|
||||||
|
if (gwi.condPush)
|
||||||
|
return new SimpleColumn("noop");
|
||||||
|
|
||||||
|
return new ConstantColumn("", ConstantColumn::NULLDATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
case Item::CACHE_ITEM:
|
||||||
|
{
|
||||||
|
Item* col = ((Item_cache*)item)->get_example();
|
||||||
|
rc = buildReturnedColumn(col, gwi, nonSupport);
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
ConstantColumn* cc = dynamic_cast<ConstantColumn*>(rc);
|
||||||
|
|
||||||
|
if (!cc)
|
||||||
|
{
|
||||||
|
rc->joinInfo(rc->joinInfo() | JOIN_CORRELATED);
|
||||||
|
|
||||||
|
if (gwi.subQuery)
|
||||||
|
gwi.subQuery->correlated(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Item::EXPR_CACHE_ITEM:
|
||||||
|
{
|
||||||
|
// TODO: item is a Item_cache_wrapper
|
||||||
|
printf("EXPR_CACHE_ITEM in buildReturnedColumn\n");
|
||||||
|
cerr << "EXPR_CACHE_ITEM in buildReturnedColumn" << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Item::DATE_ITEM:
|
||||||
|
{
|
||||||
|
String val, *str = item->val_str(&val);
|
||||||
|
string valStr;
|
||||||
|
valStr.assign(str->ptr(), str->length());
|
||||||
|
rc = new ConstantColumn(valStr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Item::WINDOW_FUNC_ITEM:
|
||||||
|
{
|
||||||
|
return buildWindowFunctionColumn(item, gwi, nonSupport);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if INTERVAL_ITEM
|
||||||
|
|
||||||
|
case Item::INTERVAL_ITEM:
|
||||||
|
{
|
||||||
|
Item_interval* interval = (Item_interval*)item;
|
||||||
|
SRCP srcp;
|
||||||
|
srcp.reset(buildReturnedColumn(interval->item, gwi, nonSupport));
|
||||||
|
|
||||||
|
if (!srcp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
rc = new IntervalColumn(srcp, (int)interval->interval);
|
||||||
|
rc->resultType(srcp->resultType());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case Item::SUBSELECT_ITEM:
|
||||||
|
{
|
||||||
|
gwi.hasSubSelect = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
gwi.fatalParseError = true;
|
||||||
|
gwi.parseErrorText = "Unknown item type";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc && item->name)
|
||||||
|
rc->alias(item->name);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
ArithmeticColumn* buildArithmeticColumn(Item_func* item, gp_walk_info& gwi, bool& nonSupport)
|
ArithmeticColumn* buildArithmeticColumn(Item_func* item, gp_walk_info& gwi, bool& nonSupport)
|
||||||
{
|
{
|
||||||
if (!(gwi.thd->infinidb_vtable.cal_conn_info))
|
if (!(gwi.thd->infinidb_vtable.cal_conn_info))
|
||||||
@ -5029,7 +5283,13 @@ void gp_walk(const Item* item, void* arg)
|
|||||||
gwip->clauseType = SELECT;
|
gwip->clauseType = SELECT;
|
||||||
|
|
||||||
if (col->type() != Item::COND_ITEM)
|
if (col->type() != Item::COND_ITEM)
|
||||||
rc = buildReturnedColumn(col, *gwip, gwip->fatalParseError);
|
{
|
||||||
|
/*if ( col->type() == Item::FIELD_ITEM )
|
||||||
|
{
|
||||||
|
rc = buildReturnedColumnGr(col, *gwip, gwip->fatalParseError);
|
||||||
|
} else*/
|
||||||
|
rc = buildReturnedColumn(col, *gwip, gwip->fatalParseError);
|
||||||
|
}
|
||||||
|
|
||||||
SimpleColumn* sc = dynamic_cast<SimpleColumn*>(rc);
|
SimpleColumn* sc = dynamic_cast<SimpleColumn*>(rc);
|
||||||
|
|
||||||
@ -7937,8 +8197,7 @@ int cp_get_table_plan(THD* thd, SCSEP& csep, cal_table_info& ti)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ti is useless
|
int cp_get_group_plan(THD* thd, SCSEP& csep, cal_impl_if::cal_group_info& gi)
|
||||||
int cp_get_group_plan(THD* thd, SCSEP& csep, cal_group_info& gi )
|
|
||||||
{
|
{
|
||||||
LEX* lex = thd->lex;
|
LEX* lex = thd->lex;
|
||||||
idbassert(lex != 0);
|
idbassert(lex != 0);
|
||||||
@ -7957,176 +8216,15 @@ int cp_get_group_plan(THD* thd, SCSEP& csep, cal_group_info& gi )
|
|||||||
cerr << *csep << endl ;
|
cerr << *csep << endl ;
|
||||||
cerr << "-------------- EXECUTION PLAN END --------------\n" << endl;
|
cerr << "-------------- EXECUTION PLAN END --------------\n" << endl;
|
||||||
|
|
||||||
// Derived table projection and filter optimization.
|
|
||||||
//derivedTableOptimization(csep);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
int cp_get_group_plan(THD* thd, SCSEP& csep, cal_table_info& ti )
|
|
||||||
{
|
|
||||||
gp_walk_info* gwi = ti.condInfo;
|
|
||||||
List_iterator_fast<Item> it(*ti.groupByFields);
|
|
||||||
Item* item;
|
|
||||||
|
|
||||||
if (!gwi)
|
|
||||||
gwi = new gp_walk_info();
|
|
||||||
|
|
||||||
gwi->thd = thd;
|
|
||||||
LEX* lex = thd->lex;
|
|
||||||
idbassert(lex != 0);
|
|
||||||
uint32_t sessionID = csep->sessionID();
|
|
||||||
gwi->sessionid = sessionID;
|
|
||||||
TABLE* table = ti.msTablePtr;
|
|
||||||
TABLE_LIST* table_list = ti.groupByTables;
|
|
||||||
boost::shared_ptr<CalpontSystemCatalog> csc =
|
|
||||||
CalpontSystemCatalog::makeCalpontSystemCatalog(sessionID);
|
|
||||||
csc->identity(CalpontSystemCatalog::FE);
|
|
||||||
|
|
||||||
// get all columns that mysql needs to fetch
|
|
||||||
MY_BITMAP* read_set = table->read_set;
|
|
||||||
Field** f_ptr, *field;
|
|
||||||
gwi->columnMap.clear();
|
|
||||||
|
|
||||||
CalpontSystemCatalog::TableAliasName tan=
|
|
||||||
make_aliastable(table->s->db.str, table->s->table_name.str, table->alias.c_ptr());
|
|
||||||
|
|
||||||
gwi->tbList.push_back(tan);
|
|
||||||
gwi->tableMap[tan] = make_pair(0, table_list);
|
|
||||||
|
|
||||||
while ((item = it++))
|
|
||||||
{
|
|
||||||
Item *arg0;
|
|
||||||
Field *field;
|
|
||||||
ReturnedColumn* rc = buildAggregateColumn(item, *gwi);
|
|
||||||
//string alias(table->alias.c_ptr());
|
|
||||||
//rc->tableAlias(lower(alias));
|
|
||||||
assert (rc);
|
|
||||||
boost::shared_ptr<ReturnedColumn> sprc(rc);
|
|
||||||
gwi->returnedCols.push_back(sprc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TO DO add table into tableMap
|
|
||||||
// TO DO add the column only if there is no any for a table.
|
|
||||||
TableMap::iterator tb_iter = gwi->tableMap.begin();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for (; tb_iter != gwi->tableMap.end(); tb_iter++)
|
|
||||||
{
|
|
||||||
if ((*tb_iter).second.first == 1) continue;
|
|
||||||
|
|
||||||
CalpontSystemCatalog::TableAliasName tan = (*tb_iter).first;
|
|
||||||
CalpontSystemCatalog::TableName tn = make_table((*tb_iter).first.schema, (*tb_iter).first.table);
|
|
||||||
SimpleColumn* sc = getSmallestColumn(csc, tn, tan, (*tb_iter).second.second->table, *gwi);
|
|
||||||
SRCP srcp(sc);
|
|
||||||
gwi->columnMap.insert(CalpontSelectExecutionPlan::ColumnMap::value_type(sc->columnName(), srcp));
|
|
||||||
(*tb_iter).second.first = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (runtime_error& e)
|
|
||||||
{
|
|
||||||
setError(gwi->thd, ER_INTERNAL_ERROR, e.what(), *gwi);
|
|
||||||
CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID);
|
|
||||||
return ER_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
string emsg = IDBErrorInfo::instance()->errorMsg(ERR_LOST_CONN_EXEMGR);
|
|
||||||
setError(gwi->thd, ER_INTERNAL_ERROR, emsg, *gwi);
|
|
||||||
CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID);
|
|
||||||
return ER_INTERNAL_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (gwi->columnMap.empty())
|
|
||||||
//{
|
|
||||||
// CalpontSystemCatalog::TableName tn = make_table(table->s->db.str, table->s->table_name.str);
|
|
||||||
// CalpontSystemCatalog::TableAliasName tan = make_aliastable(table->s->db.str, table->s->table_name.str, table->alias.c_ptr());
|
|
||||||
// SimpleColumn* sc = getSmallestColumn(csc, tn, tan, table, *gwi);
|
|
||||||
// SRCP srcp(sc);
|
|
||||||
// gwi->columnMap.insert(CalpontSelectExecutionPlan::ColumnMap::value_type(sc->columnName(), srcp));
|
|
||||||
// gwi->returnedCols.push_back(srcp);
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
CalpontSystemCatalog::TableName tn = make_table(table->s->db.str, table->s->table_name.str);
|
|
||||||
//SimpleColumn* minSc = getSmallestColumn(csc, tn, tan, table, *gwi);
|
|
||||||
SRCP minSc;
|
|
||||||
minSc = gwi->returnedCols[0];
|
|
||||||
std::vector<AggregateColumn*>::iterator coliter;
|
|
||||||
for (coliter = gwi->count_asterisk_list.begin(); coliter != gwi->count_asterisk_list.end(); ++coliter)
|
|
||||||
{
|
|
||||||
(*coliter)->functionParms(minSc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get filter
|
|
||||||
if (ti.condInfo)
|
|
||||||
{
|
|
||||||
gp_walk_info* gwi = ti.condInfo;
|
|
||||||
ParseTree* filters = 0;
|
|
||||||
ParseTree* ptp = 0;
|
|
||||||
ParseTree* rhs = 0;
|
|
||||||
|
|
||||||
while (!gwi->ptWorkStack.empty())
|
|
||||||
{
|
|
||||||
filters = gwi->ptWorkStack.top();
|
|
||||||
gwi->ptWorkStack.pop();
|
|
||||||
SimpleFilter* sf = dynamic_cast<SimpleFilter*>(filters->data());
|
|
||||||
|
|
||||||
if (sf && sf->op()->data() == "noop")
|
|
||||||
{
|
|
||||||
delete filters;
|
|
||||||
filters = 0;
|
|
||||||
|
|
||||||
if (gwi->ptWorkStack.empty())
|
|
||||||
break;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gwi->ptWorkStack.empty())
|
|
||||||
break;
|
|
||||||
|
|
||||||
ptp = new ParseTree(new LogicOperator("and"));
|
|
||||||
ptp->left(filters);
|
|
||||||
rhs = gwi->ptWorkStack.top();
|
|
||||||
gwi->ptWorkStack.pop();
|
|
||||||
ptp->right(rhs);
|
|
||||||
gwi->ptWorkStack.push(ptp);
|
|
||||||
}
|
|
||||||
|
|
||||||
csep->filters(filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
csep->returnedCols(gwi->returnedCols);
|
|
||||||
csep->columnMap(gwi->columnMap);
|
|
||||||
CalpontSelectExecutionPlan::TableList tblist;
|
|
||||||
tblist.push_back(tan);
|
|
||||||
csep->tableList(tblist);
|
|
||||||
|
|
||||||
// @bug 3321. Set max number of blocks in a dictionary file to be scanned for filtering
|
|
||||||
csep->stringScanThreshold(gwi->thd->variables.infinidb_string_scan_threshold);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_group_info& gi, bool isUnion)
|
int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_group_info& gi, bool isUnion)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_WALK_COND
|
#ifdef DEBUG_WALK_COND
|
||||||
cerr << "getGroupPlan()" << endl;
|
cerr << "getGroupPlan()" << endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// by pass the derived table resolve phase of mysql
|
|
||||||
/*if (!(((gwi.thd->lex)->sql_command == SQLCOM_UPDATE ) ||
|
|
||||||
((gwi.thd->lex)->sql_command == SQLCOM_DELETE ) ||
|
|
||||||
((gwi.thd->lex)->sql_command == SQLCOM_UPDATE_MULTI ) ||
|
|
||||||
((gwi.thd->lex)->sql_command == SQLCOM_DELETE_MULTI ) ) && gwi.thd->derived_tables_processing)
|
|
||||||
{
|
|
||||||
gwi.thd->infinidb_vtable.isUnion = false;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// rollup is currently not supported
|
// rollup is currently not supported
|
||||||
if (select_lex.olap == ROLLUP_TYPE)
|
if (select_lex.olap == ROLLUP_TYPE)
|
||||||
{
|
{
|
||||||
@ -8324,74 +8422,9 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
|||||||
|
|
||||||
bool unionSel = false;
|
bool unionSel = false;
|
||||||
|
|
||||||
// MCOL-1052
|
|
||||||
/*
|
|
||||||
if (!isUnion && select_lex.master_unit()->is_union())
|
|
||||||
{
|
|
||||||
// gwi.thd->infinidb_vtable.isUnion = true;
|
|
||||||
CalpontSelectExecutionPlan::SelectList unionVec;
|
|
||||||
SELECT_LEX* select_cursor = select_lex.master_unit()->first_select();
|
|
||||||
unionSel = true;
|
|
||||||
uint8_t distUnionNum = 0;
|
|
||||||
|
|
||||||
for (SELECT_LEX* sl = select_cursor; sl; sl = sl->next_select())
|
|
||||||
{
|
|
||||||
SCSEP plan(new CalpontSelectExecutionPlan());
|
|
||||||
plan->txnID(csep->txnID());
|
|
||||||
plan->verID(csep->verID());
|
|
||||||
plan->sessionID(csep->sessionID());
|
|
||||||
plan->traceFlags(csep->traceFlags());
|
|
||||||
plan->data(csep->data());
|
|
||||||
|
|
||||||
// @bug 3853. When one or more sides or union queries contain derived tables,
|
|
||||||
// sl->join->zero_result_cause is not trustable. Since we've already handled
|
|
||||||
// constant filter now (0/1), we can relax the following checking.
|
|
||||||
// @bug 2547. ignore union unit of zero result set case
|
|
||||||
// if (sl->join)
|
|
||||||
// {
|
|
||||||
// sl->join->optimize();
|
|
||||||
// @bug 3067. not clear MySQL's behavior. when in subquery, this variable
|
|
||||||
// is not trustable.
|
|
||||||
// if (sl->join->zero_result_cause && !gwi.subQuery)
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// gwi for the union unit
|
|
||||||
gp_walk_info union_gwi;
|
|
||||||
union_gwi.thd = gwi.thd;
|
|
||||||
uint32_t err = 0;
|
|
||||||
|
|
||||||
if ((err = getGroupPlan(union_gwi, *sl, plan, gi, unionSel)) != 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
unionVec.push_back(SCEP(plan));
|
|
||||||
|
|
||||||
// distinct union num
|
|
||||||
if (sl == select_lex.master_unit()->union_distinct)
|
|
||||||
distUnionNum = unionVec.size();
|
|
||||||
|
|
||||||
*//*#ifdef DEBUG_WALK_COND
|
|
||||||
IDEBUG( cerr << ">>>> UNION DEBUG" << endl );
|
|
||||||
JOIN* join = sl->join;
|
|
||||||
Item_cond* icp = 0;
|
|
||||||
if (join != 0)
|
|
||||||
icp = reinterpret_cast<Item_cond*>(join->conds);
|
|
||||||
if (icp)
|
|
||||||
icp->traverse_cond(debug_walk, &gwi, Item::POSTFIX);
|
|
||||||
IDEBUG ( cerr << *plan << endl );
|
|
||||||
IDEBUG ( cerr << "<<<<UNION DEBUG" << endl );
|
|
||||||
#endif*/
|
|
||||||
/* }
|
|
||||||
|
|
||||||
csep->unionVec(unionVec);
|
|
||||||
csep->distinctUnionNum(distUnionNum);
|
|
||||||
|
|
||||||
if (unionVec.empty())
|
|
||||||
gwi.thd->infinidb_vtable.impossibleWhereOnUnion = true;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
gwi.clauseType = WHERE;
|
gwi.clauseType = WHERE;
|
||||||
|
|
||||||
|
|
||||||
if (icp)
|
if (icp)
|
||||||
{
|
{
|
||||||
// MCOL-1052 The condition could be useless.
|
// MCOL-1052 The condition could be useless.
|
||||||
@ -8434,6 +8467,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
|||||||
{
|
{
|
||||||
gwi.rcWorkStack.push(new ConstantColumn((int64_t)0, ConstantColumn::NUM));
|
gwi.rcWorkStack.push(new ConstantColumn((int64_t)0, ConstantColumn::NUM));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ZZ - the followinig debug shows the structure of nested outer join. should
|
// ZZ - the followinig debug shows the structure of nested outer join. should
|
||||||
@ -9148,9 +9182,11 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
|||||||
gwi.fatalParseError = false;
|
gwi.fatalParseError = false;
|
||||||
gwi.parseErrorText = "";
|
gwi.parseErrorText = "";
|
||||||
|
|
||||||
if (gi.groupByHaving != 0)
|
//if (gi.groupByHaving != 0)
|
||||||
|
if ( select_lex.having != 0 )
|
||||||
{
|
{
|
||||||
Item_cond* having = reinterpret_cast<Item_cond*>(gi.groupByHaving);
|
Item_cond* having = reinterpret_cast<Item_cond*>(select_lex.having);
|
||||||
|
//Item_cond* having = reinterpret_cast<Item_cond*>(gi.groupByHaving);
|
||||||
#ifdef DEBUG_WALK_COND
|
#ifdef DEBUG_WALK_COND
|
||||||
cerr << "------------------- HAVING ---------------------" << endl;
|
cerr << "------------------- HAVING ---------------------" << endl;
|
||||||
having->traverse_cond(debug_walk, &gwi, Item::POSTFIX);
|
having->traverse_cond(debug_walk, &gwi, Item::POSTFIX);
|
||||||
@ -9270,13 +9306,11 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
|||||||
SRCP minSc; // min width projected column. for count(*) use
|
SRCP minSc; // min width projected column. for count(*) use
|
||||||
|
|
||||||
// Group by list. not valid for union main query
|
// Group by list. not valid for union main query
|
||||||
|
|
||||||
/*
|
|
||||||
if (gwi.thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE && !unionSel)
|
if (gwi.thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE && !unionSel)
|
||||||
{
|
{
|
||||||
gwi.clauseType = GROUP_BY;
|
gwi.clauseType = GROUP_BY;
|
||||||
Item* nonSupportItem = NULL;
|
Item* nonSupportItem = NULL;
|
||||||
ORDER* groupcol = reinterpret_cast<ORDER*>(gi.groupByGr.first);
|
ORDER* groupcol = reinterpret_cast<ORDER*>(gi.groupByGroup);
|
||||||
|
|
||||||
// check if window functions are in order by. InfiniDB process order by list if
|
// check if window functions are in order by. InfiniDB process order by list if
|
||||||
// window functions are involved, either in order by or projection.
|
// window functions are involved, either in order by or projection.
|
||||||
@ -9298,7 +9332,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
|||||||
}
|
}
|
||||||
|
|
||||||
gwi.hasWindowFunc = hasWindowFunc;
|
gwi.hasWindowFunc = hasWindowFunc;
|
||||||
groupcol = reinterpret_cast<ORDER*>(gi.groupByGr.first);
|
groupcol = reinterpret_cast<ORDER*>(gi.groupByGroup);
|
||||||
|
|
||||||
for (; groupcol; groupcol = groupcol->next)
|
for (; groupcol; groupcol = groupcol->next)
|
||||||
{
|
{
|
||||||
@ -9547,13 +9581,11 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
|||||||
setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi);
|
setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi);
|
||||||
return ER_CHECK_NOT_IMPLEMENTED;
|
return ER_CHECK_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
}
|
} // GROUP processing ends here
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
if (gwi.thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE)
|
if (gwi.thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE)
|
||||||
{
|
{
|
||||||
//SQL_I_List<ORDER> order_list = gi.groupByOrder;
|
|
||||||
ORDER* ordercol = reinterpret_cast<ORDER*>(gi.groupByOrder);
|
ORDER* ordercol = reinterpret_cast<ORDER*>(gi.groupByOrder);
|
||||||
string create_query(gwi.thd->infinidb_vtable.create_vtable_query.c_ptr());
|
string create_query(gwi.thd->infinidb_vtable.create_vtable_query.c_ptr());
|
||||||
string select_query(gwi.thd->infinidb_vtable.select_vtable_query.c_ptr());
|
string select_query(gwi.thd->infinidb_vtable.select_vtable_query.c_ptr());
|
||||||
@ -9576,7 +9608,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
|||||||
|
|
||||||
// for subquery, order+limit by will be supported in infinidb. build order by columns
|
// for subquery, order+limit by will be supported in infinidb. build order by columns
|
||||||
// @todo union order by and limit support
|
// @todo union order by and limit support
|
||||||
if (gwi.hasWindowFunc || gwi.subSelectType != CalpontSelectExecutionPlan::MAIN_SELECT)
|
//if (gwi.hasWindowFunc || gwi.subSelectType != CalpontSelectExecutionPlan::MAIN_SELECT)
|
||||||
{
|
{
|
||||||
for (; ordercol; ordercol = ordercol->next)
|
for (; ordercol; ordercol = ordercol->next)
|
||||||
{
|
{
|
||||||
@ -9634,6 +9666,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
|||||||
gwi.orderByCols.push_back(SRCP(rc));
|
gwi.orderByCols.push_back(SRCP(rc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
else if (!isUnion)
|
else if (!isUnion)
|
||||||
{
|
{
|
||||||
vector <Item_field*> fieldVec;
|
vector <Item_field*> fieldVec;
|
||||||
@ -9817,12 +9850,6 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
|||||||
Item_field* field = reinterpret_cast<Item_field*>(ord_item);
|
Item_field* field = reinterpret_cast<Item_field*>(ord_item);
|
||||||
ReturnedColumn* rc = buildSimpleColumn(field, gwi);
|
ReturnedColumn* rc = buildSimpleColumn(field, gwi);
|
||||||
fullname = field->full_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++)
|
for (uint32_t i = 0; i < gwi.returnedCols.size(); i++)
|
||||||
{
|
{
|
||||||
@ -9933,6 +9960,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// make sure columnmap, returnedcols and count(*) arg_list are not empty
|
// make sure columnmap, returnedcols and count(*) arg_list are not empty
|
||||||
TableMap::iterator tb_iter = gwi.tableMap.begin();
|
TableMap::iterator tb_iter = gwi.tableMap.begin();
|
||||||
@ -10291,127 +10319,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
|||||||
select_query += ord_cols;
|
select_query += ord_cols;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} // ORDER BY processing ends here
|
||||||
// MCOL-1052 LIMIT
|
|
||||||
/*
|
|
||||||
if (unionSel || gwi.subSelectType != CalpontSelectExecutionPlan::MAIN_SELECT)
|
|
||||||
{
|
|
||||||
if (select_lex.master_unit()->global_parameters()->explicit_limit)
|
|
||||||
{
|
|
||||||
if (select_lex.master_unit()->global_parameters()->offset_limit)
|
|
||||||
{
|
|
||||||
Item_int* offset = (Item_int*)select_lex.master_unit()->global_parameters()->offset_limit;
|
|
||||||
csep->limitStart(offset->val_int());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (select_lex.master_unit()->global_parameters()->select_limit)
|
|
||||||
{
|
|
||||||
Item_int* select = (Item_int*)select_lex.master_unit()->global_parameters()->select_limit;
|
|
||||||
csep->limitNum(select->val_int());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unionSel && gwi.subSelectType == CalpontSelectExecutionPlan::MAIN_SELECT)
|
|
||||||
{
|
|
||||||
ostringstream limit;
|
|
||||||
limit << " limit ";
|
|
||||||
limit << csep->limitStart() << ", ";
|
|
||||||
limit << csep->limitNum();
|
|
||||||
select_query += limit.str();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (isUnion && select_lex.explicit_limit)
|
|
||||||
{
|
|
||||||
if (select_lex.braces)
|
|
||||||
{
|
|
||||||
if (select_lex.offset_limit)
|
|
||||||
csep->limitStart(((Item_int*)select_lex.offset_limit)->val_int());
|
|
||||||
|
|
||||||
if (select_lex.select_limit)
|
|
||||||
csep->limitNum(((Item_int*)select_lex.select_limit)->val_int());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (select_lex.explicit_limit)
|
|
||||||
{
|
|
||||||
uint32_t limitOffset = 0;
|
|
||||||
uint32_t limitNum = std::numeric_limits<uint32_t>::max();
|
|
||||||
|
|
||||||
if (join)
|
|
||||||
{
|
|
||||||
#if MYSQL_VERSION_ID >= 50172
|
|
||||||
|
|
||||||
// @bug5729. After upgrade, join->unit sometimes is uninitialized pointer
|
|
||||||
// (not null though) and will cause seg fault. Prefer checking
|
|
||||||
// select_lex->offset_limit if not null.
|
|
||||||
if (join->select_lex &&
|
|
||||||
join->select_lex->offset_limit &&
|
|
||||||
join->select_lex->offset_limit->fixed &&
|
|
||||||
join->select_lex->select_limit &&
|
|
||||||
join->select_lex->select_limit->fixed)
|
|
||||||
{
|
|
||||||
limitOffset = join->select_lex->offset_limit->val_int();
|
|
||||||
limitNum = join->select_lex->select_limit->val_int();
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (join->unit)
|
|
||||||
{
|
|
||||||
limitOffset = join->unit->offset_limit_cnt;
|
|
||||||
limitNum = join->unit->select_limit_cnt - limitOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
limitOffset = (join->unit)->offset_limit_cnt;
|
|
||||||
limitNum = (join->unit)->select_limit_cnt - (join->unit)->offset_limit_cnt;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (select_lex.master_unit()->global_parameters()->offset_limit)
|
|
||||||
{
|
|
||||||
Item_int* offset = (Item_int*)select_lex.master_unit()->global_parameters()->offset_limit;
|
|
||||||
limitOffset = offset->val_int();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (select_lex.master_unit()->global_parameters()->select_limit)
|
|
||||||
{
|
|
||||||
Item_int* select = (Item_int*)select_lex.master_unit()->global_parameters()->select_limit;
|
|
||||||
limitNum = select->val_int();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// relate to bug4848. let mysql drive limit when limit session variable set.
|
|
||||||
// do not set in csep. @bug5096. ignore session limit setting for dml
|
|
||||||
if ((gwi.thd->variables.select_limit == (uint64_t) - 1 ||
|
|
||||||
(gwi.thd->variables.select_limit != (uint64_t) - 1 &&
|
|
||||||
gwi.thd->infinidb_vtable.vtable_state != THD::INFINIDB_CREATE_VTABLE)) &&
|
|
||||||
!csep->hasOrderBy())
|
|
||||||
{
|
|
||||||
csep->limitStart(limitOffset);
|
|
||||||
csep->limitNum(limitNum);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ostringstream limit;
|
|
||||||
limit << " limit " << limitOffset << ", " << limitNum;
|
|
||||||
select_query += limit.str();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gwi.thd->infinidb_vtable.select_vtable_query.free();
|
|
||||||
gwi.thd->infinidb_vtable.select_vtable_query.append(select_query.c_str(), select_query.length());
|
|
||||||
|
|
||||||
// We don't currently support limit with correlated subquery
|
|
||||||
if (csep->limitNum() != (uint64_t) - 1 &&
|
|
||||||
gwi.subQuery && !gwi.correlatedTbNameVec.empty())
|
|
||||||
{
|
|
||||||
gwi.fatalParseError = true;
|
|
||||||
gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_LIMIT_SUB);
|
|
||||||
setError(gwi.thd, ER_INTERNAL_ERROR, gwi.parseErrorText, gwi);
|
|
||||||
return ER_CHECK_NOT_IMPLEMENTED;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( gi.groupByDistinct )
|
if ( gi.groupByDistinct )
|
||||||
csep->distinct(true);
|
csep->distinct(true);
|
||||||
|
@ -5932,7 +5932,7 @@ int ha_calpont_impl_rnd_pos(uchar* buf, uchar* pos)
|
|||||||
* Prepares data for group_by_handler::next_row() calls.
|
* Prepares data for group_by_handler::next_row() calls.
|
||||||
* PARAMETERS:
|
* PARAMETERS:
|
||||||
* group_hand - group by handler, that preserves initial table and items lists. .
|
* group_hand - group by handler, that preserves initial table and items lists. .
|
||||||
* table - TABLE pointer The table to save the result set in.
|
* table - TABLE pointer The table to save the result set into.
|
||||||
* RETURN:
|
* RETURN:
|
||||||
* 0 if success
|
* 0 if success
|
||||||
* others if something went wrong whilst getting the result set
|
* others if something went wrong whilst getting the result set
|
||||||
@ -5967,25 +5967,6 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE
|
|||||||
// prevent "create table as select" from running on slave
|
// prevent "create table as select" from running on slave
|
||||||
thd->infinidb_vtable.hasInfiniDBTable = true;
|
thd->infinidb_vtable.hasInfiniDBTable = true;
|
||||||
|
|
||||||
/* If this node is the slave, ignore DML to IDB tables */
|
|
||||||
/*if (thd->slave_thread && (
|
|
||||||
thd->lex->sql_command == SQLCOM_INSERT ||
|
|
||||||
thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
|
|
||||||
thd->lex->sql_command == SQLCOM_UPDATE ||
|
|
||||||
thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
|
|
||||||
thd->lex->sql_command == SQLCOM_DELETE ||
|
|
||||||
thd->lex->sql_command == SQLCOM_DELETE_MULTI ||
|
|
||||||
thd->lex->sql_command == SQLCOM_TRUNCATE ||
|
|
||||||
thd->lex->sql_command == SQLCOM_LOAD))
|
|
||||||
return 0;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// @bug 3005. if the table is not $vtable, then this could be a UDF defined on the connector.
|
|
||||||
// watch this for other complications
|
|
||||||
//if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_SELECT_VTABLE &&
|
|
||||||
// string(table->s->table_name.str).find("$vtable") != 0)
|
|
||||||
// return 0;
|
|
||||||
|
|
||||||
// return error if error status has been already set
|
// return error if error status has been already set
|
||||||
if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_ERROR)
|
if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_ERROR)
|
||||||
return ER_INTERNAL_ERROR;
|
return ER_INTERNAL_ERROR;
|
||||||
@ -6007,14 +5988,6 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE
|
|||||||
if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_REDO_PHASE1 ||
|
if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_REDO_PHASE1 ||
|
||||||
thd->infinidb_vtable.vtable_state == THD::INFINIDB_ORDER_BY)
|
thd->infinidb_vtable.vtable_state == THD::INFINIDB_ORDER_BY)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ( (thd->lex)->sql_command == SQLCOM_ALTER_TABLE )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
|
||||||
//Update and delete code
|
|
||||||
if ( ((thd->lex)->sql_command == SQLCOM_UPDATE) || ((thd->lex)->sql_command == SQLCOM_DELETE) || ((thd->lex)->sql_command == SQLCOM_DELETE_MULTI) || ((thd->lex)->sql_command == SQLCOM_UPDATE_MULTI))
|
|
||||||
return doUpdateDelete(thd);
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
uint32_t sessionID = tid2sid(thd->thread_id);
|
uint32_t sessionID = tid2sid(thd->thread_id);
|
||||||
@ -6032,10 +6005,11 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE
|
|||||||
MySQL sometimes calls rnd_init multiple times, plan should only be
|
MySQL sometimes calls rnd_init multiple times, plan should only be
|
||||||
generated and sent once.
|
generated and sent once.
|
||||||
TO DO Check this statement.
|
TO DO Check this statement.
|
||||||
*/
|
|
||||||
if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE &&
|
if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE &&
|
||||||
!thd->infinidb_vtable.isNewQuery)
|
!thd->infinidb_vtable.isNewQuery)
|
||||||
return 0;
|
return 0;
|
||||||
|
*/
|
||||||
|
|
||||||
if (thd->killed == KILL_QUERY || thd->killed == KILL_QUERY_HARD)
|
if (thd->killed == KILL_QUERY || thd->killed == KILL_QUERY_HARD)
|
||||||
{
|
{
|
||||||
@ -6068,101 +6042,9 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE
|
|||||||
sm::cpsm_conhdl_t* hndl;
|
sm::cpsm_conhdl_t* hndl;
|
||||||
SCSEP csep;
|
SCSEP csep;
|
||||||
|
|
||||||
// update traceFlags according to the autoswitch state. replication query
|
|
||||||
// on slave are in table mode (create table as...)
|
|
||||||
if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE)
|
|
||||||
{
|
|
||||||
ci->traceFlags |= CalpontSelectExecutionPlan::TRACE_TUPLE_OFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MCOL-1052 TO DO Remove this
|
|
||||||
ci->traceFlags = CalpontSelectExecutionPlan::TRACE_LOG;
|
|
||||||
|
|
||||||
bool localQuery = (thd->variables.infinidb_local_query > 0 ? true : false);
|
bool localQuery = (thd->variables.infinidb_local_query > 0 ? true : false);
|
||||||
|
|
||||||
/*
|
|
||||||
// table mode
|
|
||||||
if (thd->infinidb_vtable.vtable_state == THD::INFINIDB_DISABLE_VTABLE)
|
|
||||||
{
|
|
||||||
ti = ci->tableMap[group_hand->table_list->table];
|
|
||||||
|
|
||||||
// get connection handle for this table handler
|
|
||||||
// re-establish table handle
|
|
||||||
if (ti.conn_hndl)
|
|
||||||
{
|
|
||||||
sm::sm_cleanup(ti.conn_hndl);
|
|
||||||
ti.conn_hndl = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
sm::sm_init(sessionID, &ti.conn_hndl, localQuery);
|
|
||||||
ti.conn_hndl->csc = csc;
|
|
||||||
hndl = ti.conn_hndl;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ti.conn_hndl->connect();
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
setError(thd, ER_INTERNAL_ERROR, IDBErrorInfo::instance()->errorMsg(ERR_LOST_CONN_EXEMGR));
|
|
||||||
CalpontSystemCatalog::removeCalpontSystemCatalog(sessionID);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get filter plan for table
|
|
||||||
if (ti.csep.get() == 0)
|
|
||||||
{
|
|
||||||
ti.csep.reset(new CalpontSelectExecutionPlan());
|
|
||||||
|
|
||||||
SessionManager sm;
|
|
||||||
BRM::TxnID txnID;
|
|
||||||
txnID = sm.getTxnID(sessionID);
|
|
||||||
|
|
||||||
if (!txnID.valid)
|
|
||||||
{
|
|
||||||
txnID.id = 0;
|
|
||||||
txnID.valid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryContext verID;
|
|
||||||
verID = sm.verID();
|
|
||||||
|
|
||||||
ti.csep->txnID(txnID.id);
|
|
||||||
ti.csep->verID(verID);
|
|
||||||
ti.csep->sessionID(sessionID);
|
|
||||||
|
|
||||||
if (group_hand->table_list->db_length)
|
|
||||||
ti.csep->schemaName(group_hand->table_list->db);
|
|
||||||
|
|
||||||
ti.csep->traceFlags(ci->traceFlags);
|
|
||||||
ti.msTablePtr = group_hand->table_list->table;
|
|
||||||
//ti.groupByTables = group_hand->table_list;
|
|
||||||
//ti.groupByFields = group_hand->fields;
|
|
||||||
|
|
||||||
gi.groupByTables = group_hand->table_list;
|
|
||||||
gi.groupByFields = group_hand->select;
|
|
||||||
gi.groupByWhere = group_hand->where;
|
|
||||||
gi.groupByGroup = group_hand->group_by;
|
|
||||||
gi.groupByOrder = group_hand->order_by;
|
|
||||||
gi.groupByHaving = group_hand->having;
|
|
||||||
gi.groupByDistinct = group_hand->distinct;
|
|
||||||
|
|
||||||
// send plan whenever group_init is called
|
|
||||||
cp_get_group_plan(thd, ti.csep, ti, gi);
|
|
||||||
}
|
|
||||||
|
|
||||||
IDEBUG( cerr << tableName << " send plan:" << endl );
|
|
||||||
IDEBUG( cerr << *ti.csep << endl );
|
|
||||||
csep = ti.csep;
|
|
||||||
|
|
||||||
// for ExeMgr logging sqltext. only log once for the query although multi plans may be sent
|
|
||||||
if (ci->tableMap.size() == 1)
|
|
||||||
ti.csep->data(idb_mysql_query_str(thd));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// vtable mode
|
|
||||||
//else
|
|
||||||
{
|
|
||||||
//if (!ci->cal_conn_hndl || thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE)
|
//if (!ci->cal_conn_hndl || thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE)
|
||||||
if ( thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE)
|
if ( thd->infinidb_vtable.vtable_state == THD::INFINIDB_CREATE_VTABLE)
|
||||||
{
|
{
|
||||||
@ -6240,7 +6122,6 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE
|
|||||||
csep->schemaName(group_hand->table_list->db);
|
csep->schemaName(group_hand->table_list->db);
|
||||||
|
|
||||||
csep->traceFlags(ci->traceFlags);
|
csep->traceFlags(ci->traceFlags);
|
||||||
//ti.msTablePtr = group_hand->table_list->table;
|
|
||||||
|
|
||||||
gi.groupByTables = group_hand->table_list;
|
gi.groupByTables = group_hand->table_list;
|
||||||
gi.groupByFields = group_hand->select;
|
gi.groupByFields = group_hand->select;
|
||||||
@ -6311,7 +6192,7 @@ int ha_calpont_impl_group_by_init(ha_calpont_group_by_handler* group_hand, TABLE
|
|||||||
IDEBUG( cout << "-------------- EXECUTION PLAN END --------------\n" << endl );
|
IDEBUG( cout << "-------------- EXECUTION PLAN END --------------\n" << endl );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}// end of execution plan generation
|
// end of execution plan generation
|
||||||
|
|
||||||
if (thd->infinidb_vtable.vtable_state != THD::INFINIDB_SELECT_VTABLE)
|
if (thd->infinidb_vtable.vtable_state != THD::INFINIDB_SELECT_VTABLE)
|
||||||
{
|
{
|
||||||
|
@ -320,7 +320,7 @@ int cp_get_plan(THD* thd, execplan::SCSEP& csep);
|
|||||||
int cp_get_table_plan(THD* thd, execplan::SCSEP& csep, cal_impl_if::cal_table_info& ti);
|
int cp_get_table_plan(THD* thd, execplan::SCSEP& csep, cal_impl_if::cal_table_info& ti);
|
||||||
int cp_get_group_plan(THD* thd, execplan::SCSEP& csep, cal_impl_if::cal_group_info& gi);
|
int cp_get_group_plan(THD* thd, execplan::SCSEP& csep, cal_impl_if::cal_group_info& gi);
|
||||||
int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, execplan::SCSEP& csep, bool isUnion = false);
|
int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, execplan::SCSEP& csep, bool isUnion = false);
|
||||||
int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, execplan::SCSEP& csep,cal_group_info& gi, bool isUnion = false);
|
int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, execplan::SCSEP& csep, cal_group_info& gi, bool isUnion = false);
|
||||||
void setError(THD* thd, uint32_t errcode, const std::string errmsg, gp_walk_info* gwi);
|
void setError(THD* thd, uint32_t errcode, const std::string errmsg, gp_walk_info* gwi);
|
||||||
void setError(THD* thd, uint32_t errcode, const std::string errmsg);
|
void setError(THD* thd, uint32_t errcode, const std::string errmsg);
|
||||||
void gp_walk(const Item* item, void* arg);
|
void gp_walk(const Item* item, void* arg);
|
||||||
|
Reference in New Issue
Block a user