1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-07-29 08:21:15 +03:00

parse_item() in execplan code now always get an actual GWI structure

to avoid accedental crashes.

Add check for Conversion of Big IN Predicates Into Subqueries optimization
conditions.

Enabled derivedTableOptimization() for group by and derived handlers.

Disabled Conversion of Big IN Predicates Into Subqueries optimization.

Disabled most of optimizer_flags for now.

RowGroup + operator now correctly sets useStringTable flag that
instructs code to check StringStore instead of plain data buffer.
This commit is contained in:
Roman Nozdrin
2019-07-26 23:39:51 +03:00
committed by Gagan Goel
parent 7d5275e1bd
commit d62b66ecf7
8 changed files with 119 additions and 44 deletions

View File

@ -146,7 +146,7 @@ static int columnstore_init_func(void* p)
mcs_hton->rollback = calpont_rollback; mcs_hton->rollback = calpont_rollback;
mcs_hton->close_connection = calpont_close_connection; mcs_hton->close_connection = calpont_close_connection;
//mcs_hton->create_group_by = create_calpont_group_by_handler; //mcs_hton->create_group_by = create_calpont_group_by_handler;
//mcs_hton->create_derived = create_columnstore_derived_handler; mcs_hton->create_derived = create_columnstore_derived_handler;
mcs_hton->create_select = create_columnstore_select_handler; mcs_hton->create_select = create_columnstore_select_handler;
DBUG_RETURN(0); DBUG_RETURN(0);
} }

View File

@ -1143,6 +1143,12 @@ void debug_walk(const Item* item, void* arg)
break; break;
} }
case Item::TYPE_HOLDER:
{
cerr << "TYPE_HOLDER item with cmp_type " << item->cmp_type() << endl;
break;
}
default: default:
{ {
cerr << "UNKNOWN_ITEM type " << item->type() << endl; cerr << "UNKNOWN_ITEM type " << item->type() << endl;
@ -3120,7 +3126,7 @@ ReturnedColumn* buildReturnedColumn(Item* item, gp_walk_info& gwi, bool& nonSupp
vector <Item_field*> tmpVec; vector <Item_field*> tmpVec;
//bool hasAggColumn = false; //bool hasAggColumn = false;
uint16_t parseInfo = 0; uint16_t parseInfo = 0;
parse_item(ifp, tmpVec, gwi.fatalParseError, parseInfo); parse_item(ifp, tmpVec, gwi.fatalParseError, parseInfo, &gwi);
if (parseInfo & SUB_BIT) if (parseInfo & SUB_BIT)
{ {
@ -3616,7 +3622,7 @@ ReturnedColumn* buildFunctionColumn(
// try to identify const F&E. fall to primitive if parms are constant F&E. // try to identify const F&E. fall to primitive if parms are constant F&E.
vector <Item_field*> tmpVec; vector <Item_field*> tmpVec;
uint16_t parseInfo = 0; uint16_t parseInfo = 0;
parse_item(ifp->arguments()[i], tmpVec, gwi.fatalParseError, parseInfo); parse_item(ifp->arguments()[i], tmpVec, gwi.fatalParseError, parseInfo, &gwi);
if (!gwi.fatalParseError && !(parseInfo & AF_BIT) && tmpVec.size() == 0) if (!gwi.fatalParseError && !(parseInfo & AF_BIT) && tmpVec.size() == 0)
continue; continue;
@ -4625,7 +4631,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi)
// check count(1+1) case // check count(1+1) case
vector <Item_field*> tmpVec; vector <Item_field*> tmpVec;
uint16_t parseInfo = 0; uint16_t parseInfo = 0;
parse_item(ifp, tmpVec, gwi.fatalParseError, parseInfo); parse_item(ifp, tmpVec, gwi.fatalParseError, parseInfo, &gwi);
if (parseInfo & SUB_BIT) if (parseInfo & SUB_BIT)
{ {
@ -5238,7 +5244,7 @@ void gp_walk(const Item* item, void* arg)
// try to evaluate const F&E // try to evaluate const F&E
vector <Item_field*> tmpVec; vector <Item_field*> tmpVec;
uint16_t parseInfo = 0; uint16_t parseInfo = 0;
parse_item(ifp, tmpVec, gwip->fatalParseError, parseInfo); parse_item(ifp, tmpVec, gwip->fatalParseError, parseInfo, gwip);
// table mode takes only one table filter // table mode takes only one table filter
if (gwip->condPush) if (gwip->condPush)
@ -5704,10 +5710,6 @@ void gp_walk(const Item* item, void* arg)
printf("********** received INSERT_VALUE_ITEM *********\n"); printf("********** received INSERT_VALUE_ITEM *********\n");
break; break;
case Item::Item::TYPE_HOLDER:
printf("********** received TYPE_HOLDER *********\n");
break;
case Item::PARAM_ITEM: case Item::PARAM_ITEM:
printf("********** received PARAM_ITEM *********\n"); printf("********** received PARAM_ITEM *********\n");
break; break;
@ -5729,6 +5731,9 @@ void gp_walk(const Item* item, void* arg)
printf("********** received VIEW_FIXER_ITEM *********\n"); printf("********** received VIEW_FIXER_ITEM *********\n");
break; break;
*/ */
case Item::TYPE_HOLDER:
std::cerr << "********** received TYPE_HOLDER *********" << std::endl;
break;
default: default:
{ {
if (gwip->condPush) if (gwip->condPush)
@ -5779,7 +5784,7 @@ void parse_item (Item* item, vector<Item_field*>& field_vec,
Item** sfitempp = isp->arguments(); Item** sfitempp = isp->arguments();
for (uint32_t i = 0; i < isp->argument_count(); i++) for (uint32_t i = 0; i < isp->argument_count(); i++)
parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo); parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo, gwi);
break; break;
} }
@ -5839,7 +5844,7 @@ void parse_item (Item* item, vector<Item_field*>& field_vec,
} }
for (uint32_t i = 0; i < isp->argument_count(); i++) for (uint32_t i = 0; i < isp->argument_count(); i++)
parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo); parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo, gwi);
break; break;
} }
@ -5867,14 +5872,14 @@ void parse_item (Item* item, vector<Item_field*>& field_vec,
Item** sfitempp = isp->arguments(); Item** sfitempp = isp->arguments();
for (uint32_t i = 0; i < isp->argument_count(); i++) for (uint32_t i = 0; i < isp->argument_count(); i++)
parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo); parse_item(sfitempp[i], field_vec, hasNonSupportItem, parseInfo, gwi);
break; break;
} }
else if ((*(ref->ref))->type() == Item::CACHE_ITEM) else if ((*(ref->ref))->type() == Item::CACHE_ITEM)
{ {
Item_cache* isp = reinterpret_cast<Item_cache*>(*(ref->ref)); Item_cache* isp = reinterpret_cast<Item_cache*>(*(ref->ref));
parse_item(isp->get_example(), field_vec, hasNonSupportItem, parseInfo); parse_item(isp->get_example(), field_vec, hasNonSupportItem, parseInfo, gwi);
break; break;
} }
else if ((*(ref->ref))->type() == Item::REF_ITEM) else if ((*(ref->ref))->type() == Item::REF_ITEM)
@ -5913,7 +5918,7 @@ void parse_item (Item* item, vector<Item_field*>& field_vec,
Item_row* row = (Item_row*)item; Item_row* row = (Item_row*)item;
for (uint32_t i = 0; i < row->cols(); i++) for (uint32_t i = 0; i < row->cols(); i++)
parse_item(row->element_index(i), field_vec, hasNonSupportItem, parseInfo); parse_item(row->element_index(i), field_vec, hasNonSupportItem, parseInfo, gwi);
break; break;
} }
@ -5921,7 +5926,11 @@ void parse_item (Item* item, vector<Item_field*>& field_vec,
case Item::EXPR_CACHE_ITEM: case Item::EXPR_CACHE_ITEM:
{ {
// item is a Item_cache_wrapper. Shouldn't get here. // item is a Item_cache_wrapper. Shouldn't get here.
printf("EXPR_CACHE_ITEM in parse_item\n"); // WIP Why
IDEBUG(std::cerr << "EXPR_CACHE_ITEM in parse_item\n" << std::endl);
gwi->fatalParseError = true;
// DRRTUY The questionable error text. I've seen
// ERR_CORRELATED_SUB_OR
string parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_SUB_QUERY_TYPE); string parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_SUB_QUERY_TYPE);
setError(gwi->thd, ER_CHECK_NOT_IMPLEMENTED, parseErrorText); setError(gwi->thd, ER_CHECK_NOT_IMPLEMENTED, parseErrorText);
break; break;
@ -6570,7 +6579,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex,
uint16_t parseInfo = 0; uint16_t parseInfo = 0;
vector <Item_field*> tmpVec; vector <Item_field*> tmpVec;
bool hasNonSupportItem = false; bool hasNonSupportItem = false;
parse_item(ifp, tmpVec, hasNonSupportItem, parseInfo); parse_item(ifp, tmpVec, hasNonSupportItem, parseInfo, &gwi);
if (ifp->with_subquery() || if (ifp->with_subquery() ||
string(ifp->func_name()) == string("<in_optimizer>") || string(ifp->func_name()) == string("<in_optimizer>") ||
@ -6606,7 +6615,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex,
{ {
hasNonSupportItem = false; hasNonSupportItem = false;
uint32_t before_size = funcFieldVec.size(); uint32_t before_size = funcFieldVec.size();
parse_item(ifp, funcFieldVec, hasNonSupportItem, parseInfo); parse_item(ifp, funcFieldVec, hasNonSupportItem, parseInfo, &gwi);
uint32_t after_size = funcFieldVec.size(); uint32_t after_size = funcFieldVec.size();
// group by func and func in subquery can not be post processed // group by func and func in subquery can not be post processed
@ -6915,6 +6924,23 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex,
gwi.returnedCols.push_back(srcp); gwi.returnedCols.push_back(srcp);
break; break;
} }
case Item::TYPE_HOLDER:
{
if(!gwi.tbList.size())
{
gwi.parseErrorText = "subquery with VALUES";
gwi.fatalParseError = true;
setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi);
return ER_CHECK_NOT_IMPLEMENTED;
}
else
{
std::cerr << "********** received TYPE_HOLDER *********" << std::endl;
}
break;
}
default: default:
{ {
@ -7551,7 +7577,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex,
bool hasNonSupportItem = false; bool hasNonSupportItem = false;
uint16_t parseInfo = 0; uint16_t parseInfo = 0;
parse_item(ord_item, fieldVec, hasNonSupportItem, parseInfo); parse_item(ord_item, fieldVec, hasNonSupportItem, parseInfo, &gwi);
if (hasNonSupportItem) if (hasNonSupportItem)
{ {
@ -8099,6 +8125,8 @@ int cp_get_group_plan(THD* thd, SCSEP& csep, cal_impl_if::cal_group_info& gi)
return ER_INTERNAL_ERROR; return ER_INTERNAL_ERROR;
else if (status < 0) else if (status < 0)
return status; return status;
// Derived table projection and filter optimization.
derivedTableOptimization(csep);
return 0; return 0;
} }
@ -8120,7 +8148,8 @@ int cs_get_derived_plan(derived_handler* handler, THD* thd, SCSEP& csep)
cerr << *csep << endl ; cerr << *csep << endl ;
cerr << "-------------- EXECUTION PLAN END --------------\n" << endl; cerr << "-------------- EXECUTION PLAN END --------------\n" << endl;
#endif #endif
// Derived table projection and filter optimization.
derivedTableOptimization(csep);
return 0; return 0;
} }
@ -8682,7 +8711,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
uint16_t parseInfo = 0; uint16_t parseInfo = 0;
vector <Item_field*> tmpVec; vector <Item_field*> tmpVec;
bool hasNonSupportItem = false; bool hasNonSupportItem = false;
parse_item(ifp, tmpVec, hasNonSupportItem, parseInfo); parse_item(ifp, tmpVec, hasNonSupportItem, parseInfo, &gwi);
if (ifp->with_subquery() || if (ifp->with_subquery() ||
string(ifp->func_name()) == string("<in_optimizer>") || string(ifp->func_name()) == string("<in_optimizer>") ||

View File

@ -1380,15 +1380,7 @@ uint32_t doUpdateDelete(THD* thd)
columnAssignmentPtr->fFromCol = false; columnAssignmentPtr->fFromCol = false;
} }
} }
// WIP MCOL-2178 else if ( value->type() == Item::FUNC_ITEM )
/*else if ( value->type() == Item::VARBIN_ITEM )
{
String val, *str;
str = value->val_str(&val);
columnAssignmentPtr->fScalarExpression.assign(str->ptr(), str->length());
columnAssignmentPtr->fFromCol = false;
}*/
else if ( value->type() == Item::FUNC_ITEM )
{ {
//Bug 2092 handle negative values //Bug 2092 handle negative values
Item_func* ifp = (Item_func*)value; Item_func* ifp = (Item_func*)value;
@ -2994,13 +2986,6 @@ int ha_calpont_impl_rnd_end(TABLE* table, bool is_pushdown_hand)
if (get_fe_conn_info_ptr() != NULL) if (get_fe_conn_info_ptr() != NULL)
ci = reinterpret_cast<cal_connection_info*>(get_fe_conn_info_ptr()); ci = reinterpret_cast<cal_connection_info*>(get_fe_conn_info_ptr());
// WIP MCOL-2178. Won't see this state anymore.
if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ORDER_BY )
{
MIGR::infinidb_vtable.vtable_state = MIGR::INFINIDB_SELECT_VTABLE; // flip back to normal state
return rc;
}
if ( (thd->lex)->sql_command == SQLCOM_ALTER_TABLE ) if ( (thd->lex)->sql_command == SQLCOM_ALTER_TABLE )
return rc; return rc;
@ -4387,6 +4372,8 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type)
if (lock_type == 0) if (lock_type == 0)
{ {
ci->physTablesList.insert(table); ci->physTablesList.insert(table);
// MCOL-2178 Disable Conversion of Big IN Predicates Into Subqueries
thd->variables.in_subquery_conversion_threshold=~0;
} }
else if (lock_type == 2) else if (lock_type == 2)
{ {
@ -4413,6 +4400,9 @@ int ha_calpont_impl_external_lock(THD* thd, TABLE* table, int lock_type)
// storage for cal_conn_hndl to use it later in close_connection // storage for cal_conn_hndl to use it later in close_connection
thd_set_ha_data(thd, mcs_hton, get_fe_conn_info_ptr()); thd_set_ha_data(thd, mcs_hton, get_fe_conn_info_ptr());
ci->tableMap.clear(); ci->tableMap.clear();
// MCOL-2178 Enable Conversion of Big IN Predicates Into Subqueries
thd->variables.in_subquery_conversion_threshold = IN_SUBQUERY_CONVERSION_THRESHOLD;
restore_optimizer_flags(thd);
} }
} }
@ -5286,6 +5276,7 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table)
return ER_INTERNAL_ERROR; return ER_INTERNAL_ERROR;
} }
// WIP MCOL-2178 Remove this.
// mysql reads table twice for order by // mysql reads table twice for order by
if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_PHASE1 || if (MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_REDO_PHASE1 ||
MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ORDER_BY) MIGR::infinidb_vtable.vtable_state == MIGR::INFINIDB_ORDER_BY)
@ -5413,6 +5404,9 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table)
hndl = ci->cal_conn_hndl; hndl = ci->cal_conn_hndl;
// WIP MCOL-2178
std::cout << idb_mysql_query_str(thd) << std::endl;
if (MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_SELECT_VTABLE) if (MIGR::infinidb_vtable.vtable_state != MIGR::INFINIDB_SELECT_VTABLE)
{ {
if (!csep) if (!csep)
@ -5455,13 +5449,15 @@ int ha_cs_impl_pushdown_init(mcs_handler_info* handler_info, TABLE* table)
dh = reinterpret_cast<derived_handler*>(handler_info->hndl_ptr); dh = reinterpret_cast<derived_handler*>(handler_info->hndl_ptr);
status = cs_get_derived_plan(dh, thd, csep); status = cs_get_derived_plan(dh, thd, csep);
} }
// WIP MCOL-2178 Remove this
std::cout << "pushdown_init get_plan status " << status << std::endl; std::cout << "pushdown_init get_plan status " << status << std::endl;
// Return an error to avoid MDB crash later in end_statement // Return an error to avoid MDB crash later in end_statement
if (status != 0) if (status != 0)
goto internal_error; goto internal_error;
// WIP MCOL-2178 Remove this
std::cout << "pushdown_init impossibleWhereOnUnion " << status << std::endl; std::cout << "pushdown_init impossibleWhereOnUnion " << status << std::endl;
// @bug 2547. don't need to send the plan if it's impossible where for all unions. // @bug 2547. don't need to send the plan if it's impossible where for all unions.
if (MIGR::infinidb_vtable.impossibleWhereOnUnion) if (MIGR::infinidb_vtable.impossibleWhereOnUnion)
@ -5731,7 +5727,7 @@ error:
ci->cal_conn_hndl = 0; ci->cal_conn_hndl = 0;
} }
// do we need to close all connection handle of the table map? // do we need to close all connection handle of the table map
return ER_INTERNAL_ERROR; return ER_INTERNAL_ERROR;
internal_error: internal_error:

View File

@ -17,6 +17,29 @@
// ha_calpont.cpp includes this file. // ha_calpont.cpp includes this file.
void mutate_optimizer_flags(THD *thd_)
{
// MCOL-2178 Disable all optimizer flags as it was in the fork.
// CS restores it later in SH::scan_end() and in case of an error
// in SH::scan_init()
set_original_optimizer_flags(thd_->variables.optimizer_switch, thd_);
thd_->variables.optimizer_switch = OPTIMIZER_SWITCH_IN_TO_EXISTS |
OPTIMIZER_SWITCH_EXISTS_TO_IN |
OPTIMIZER_SWITCH_COND_PUSHDOWN_FOR_DERIVED;
}
void restore_optimizer_flags(THD *thd_)
{
// MCOL-2178 restore original optimizer flags after SH, DH
ulonglong orig_flags = get_original_optimizer_flags(thd_);
if (orig_flags)
{
thd_->variables.optimizer_switch = orig_flags;
set_original_optimizer_flags(0, thd_);
}
}
/*@brief check_walk - It traverses filter conditions*/ /*@brief check_walk - It traverses filter conditions*/
/************************************************************ /************************************************************
* DESCRIPTION: * DESCRIPTION:
@ -508,6 +531,7 @@ create_columnstore_select_handler(THD* thd, SELECT_LEX* select_lex)
if (!unsupported_feature) if (!unsupported_feature)
{ {
handler = new ha_columnstore_select_handler(thd, select_lex); handler = new ha_columnstore_select_handler(thd, select_lex);
mutate_optimizer_flags(thd);
} }
return handler; return handler;

View File

@ -21,6 +21,9 @@
#include "idb_mysql.h" #include "idb_mysql.h"
#include "ha_calpont.h" #include "ha_calpont.h"
void mutate_optimizer_flags(THD *thd_);
void restore_optimizer_flags(THD *thd_);
enum mcs_handler_types_t enum mcs_handler_types_t
{ {
SELECT, SELECT,

View File

@ -58,6 +58,21 @@ static MYSQL_THDVAR_ULONGLONG(
1 1
); );
// optimizer flags vault
static MYSQL_THDVAR_ULONGLONG(
original_optimizer_flags,
PLUGIN_VAR_NOSYSVAR | PLUGIN_VAR_NOCMDOPT,
"Vault for original optimizer flags. For internal usage.",
NULL,
NULL,
0,
0,
~0U,
1
);
// legacy system variables // legacy system variables
static MYSQL_THDVAR_ULONG( static MYSQL_THDVAR_ULONG(
decimal_scale, decimal_scale,
@ -240,6 +255,7 @@ st_mysql_sys_var* mcs_system_variables[] =
{ {
MYSQL_SYSVAR(compression_type), MYSQL_SYSVAR(compression_type),
MYSQL_SYSVAR(fe_conn_info_ptr), MYSQL_SYSVAR(fe_conn_info_ptr),
MYSQL_SYSVAR(original_optimizer_flags),
MYSQL_SYSVAR(decimal_scale), MYSQL_SYSVAR(decimal_scale),
MYSQL_SYSVAR(use_decimal_scale), MYSQL_SYSVAR(use_decimal_scale),
MYSQL_SYSVAR(ordered_only), MYSQL_SYSVAR(ordered_only),
@ -275,14 +291,20 @@ void set_fe_conn_info_ptr(void* ptr, THD* thd)
THDVAR(current_thd, fe_conn_info_ptr) = (uint64_t)(ptr); THDVAR(current_thd, fe_conn_info_ptr) = (uint64_t)(ptr);
} }
bool get_use_legacy_sysvars(THD* thd) ulonglong get_original_optimizer_flags(THD* thd)
{ {
return ( thd == NULL ) ? false : THDVAR(thd, use_legacy_sysvars); return ( current_thd == NULL && thd == NULL ) ? NULL :
THDVAR(current_thd, original_optimizer_flags);
} }
void set_use_legacy_sysvars(THD* thd, bool value) void set_original_optimizer_flags(ulonglong ptr, THD* thd)
{ {
THDVAR(thd, use_legacy_sysvars) = value; if ( current_thd == NULL && thd == NULL)
{
return;
}
THDVAR(current_thd, original_optimizer_flags) = (uint64_t)(ptr);
} }
void set_compression_type(THD* thd, ulong value) void set_compression_type(THD* thd, ulong value)

View File

@ -40,8 +40,8 @@ void set_compression_type(THD* thd, ulong value);
void* get_fe_conn_info_ptr(THD* thd = NULL); void* get_fe_conn_info_ptr(THD* thd = NULL);
void set_fe_conn_info_ptr(void* ptr, THD* thd = NULL); void set_fe_conn_info_ptr(void* ptr, THD* thd = NULL);
bool get_use_legacy_sysvars(THD* thd); ulonglong get_original_optimizer_flags(THD* thd = NULL);
void set_use_legacy_sysvars(THD* thd, bool value); void set_original_optimizer_flags(ulonglong ptr, THD* thd = NULL);
bool get_use_decimal_scale(THD* thd); bool get_use_decimal_scale(THD* thd);
void set_use_decimal_scale(THD* thd, bool value); void set_use_decimal_scale(THD* thd, bool value);

View File

@ -1591,6 +1591,7 @@ RowGroup& RowGroup::operator+=(const RowGroup& rhs)
} }
hasLongStringField = rhs.hasLongStringField || hasLongStringField; hasLongStringField = rhs.hasLongStringField || hasLongStringField;
useStringTable = rhs.useStringTable || useStringTable;
offsets = (useStringTable ? &stOffsets[0] : &oldOffsets[0]); offsets = (useStringTable ? &stOffsets[0] : &oldOffsets[0]);
return *this; return *this;