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-5215 Fix overflow of UNION operation involving DECIMAL datatypes.
When a UNION operation involving DECIMAL datatypes with scale and digits before the decimal exceeds the currently supported maximum precision of 38, we throw an error to the user: "MCS-2060: Union operation exceeds maximum DECIMAL precision of 38". This is until MCOL-5417 is implemented where ColumnStore will have full parity with MariaDB server in terms of maximum supported DECIMAL precision and scale of 65 and 38 digits respectively.
This commit is contained in:
@ -6819,7 +6819,7 @@ int processFrom(bool& isUnion, SELECT_LEX& select_lex, gp_walk_info& gwi, SCSEP&
|
||||
bool unionSel = false;
|
||||
// UNION master unit check
|
||||
// Existed pushdown handlers won't get in this scope
|
||||
// except UNION pushdown that is to come.
|
||||
// MDEV-25080 Union pushdown would enter this scope
|
||||
// is_unit_op() give a segv for derived_handler's SELECT_LEX
|
||||
if (!isUnion && (!isSelectHandlerTop || isSelectLexUnit) && select_lex.master_unit()->is_unit_op())
|
||||
{
|
||||
@ -7414,8 +7414,6 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool unionSel = (!isUnion && select_lex.master_unit()->is_unit_op()) ? true : false;
|
||||
|
||||
gwi.clauseType = WHERE;
|
||||
if ((rc = processWhere(select_lex, gwi, csep, condStack)))
|
||||
{
|
||||
@ -7857,25 +7855,32 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
|
||||
// @bug4388 normalize the project coltypes for union main select list
|
||||
if (!csep->unionVec().empty())
|
||||
{
|
||||
unsigned int unionedTypeRc = 0;
|
||||
|
||||
for (uint32_t i = 0; i < gwi.returnedCols.size(); i++)
|
||||
{
|
||||
vector<CalpontSystemCatalog::ColType> coltypes;
|
||||
|
||||
for (uint32_t j = 0; j < csep->unionVec().size(); j++)
|
||||
{
|
||||
coltypes.push_back(dynamic_cast<CalpontSelectExecutionPlan*>(csep->unionVec()[j].get())
|
||||
->returnedCols()[i]
|
||||
->resultType());
|
||||
CalpontSelectExecutionPlan* unionCsep =
|
||||
dynamic_cast<CalpontSelectExecutionPlan*>(csep->unionVec()[j].get());
|
||||
coltypes.push_back(unionCsep->returnedCols()[i]->resultType());
|
||||
|
||||
// @bug5976. set hasAggregate true for the main column if
|
||||
// one corresponding union column has aggregate
|
||||
if (dynamic_cast<CalpontSelectExecutionPlan*>(csep->unionVec()[j].get())
|
||||
->returnedCols()[i]
|
||||
->hasAggregate())
|
||||
if (unionCsep->returnedCols()[i]->hasAggregate())
|
||||
gwi.returnedCols[i]->hasAggregate(true);
|
||||
}
|
||||
|
||||
gwi.returnedCols[i]->resultType(CalpontSystemCatalog::ColType::convertUnionColType(coltypes));
|
||||
gwi.returnedCols[i]->resultType(CalpontSystemCatalog::ColType::convertUnionColType(coltypes, unionedTypeRc));
|
||||
|
||||
if (unionedTypeRc != 0)
|
||||
{
|
||||
gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(unionedTypeRc);
|
||||
setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi);
|
||||
return ER_CHECK_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8044,6 +8049,8 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, bool i
|
||||
|
||||
SRCP minSc; // min width projected column. for count(*) use
|
||||
|
||||
bool unionSel = (!isUnion && select_lex.master_unit()->is_unit_op()) ? true : false;
|
||||
|
||||
// Group by list. not valid for union main query
|
||||
if (!unionSel)
|
||||
{
|
||||
@ -9681,25 +9688,32 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
||||
// @bug4388 normalize the project coltypes for union main select list
|
||||
if (!csep->unionVec().empty())
|
||||
{
|
||||
unsigned int unionedTypeRc = 0;
|
||||
|
||||
for (uint32_t i = 0; i < gwi.returnedCols.size(); i++)
|
||||
{
|
||||
vector<CalpontSystemCatalog::ColType> coltypes;
|
||||
|
||||
for (uint32_t j = 0; j < csep->unionVec().size(); j++)
|
||||
{
|
||||
coltypes.push_back(dynamic_cast<CalpontSelectExecutionPlan*>(csep->unionVec()[j].get())
|
||||
->returnedCols()[i]
|
||||
->resultType());
|
||||
CalpontSelectExecutionPlan* unionCsep =
|
||||
dynamic_cast<CalpontSelectExecutionPlan*>(csep->unionVec()[j].get());
|
||||
coltypes.push_back(unionCsep->returnedCols()[i]->resultType());
|
||||
|
||||
// @bug5976. set hasAggregate true for the main column if
|
||||
// one corresponding union column has aggregate
|
||||
if (dynamic_cast<CalpontSelectExecutionPlan*>(csep->unionVec()[j].get())
|
||||
->returnedCols()[i]
|
||||
->hasAggregate())
|
||||
if (unionCsep->returnedCols()[i]->hasAggregate())
|
||||
gwi.returnedCols[i]->hasAggregate(true);
|
||||
}
|
||||
|
||||
gwi.returnedCols[i]->resultType(CalpontSystemCatalog::ColType::convertUnionColType(coltypes));
|
||||
gwi.returnedCols[i]->resultType(CalpontSystemCatalog::ColType::convertUnionColType(coltypes, unionedTypeRc));
|
||||
|
||||
if (unionedTypeRc != 0)
|
||||
{
|
||||
gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(unionedTypeRc);
|
||||
setError(gwi.thd, ER_CHECK_NOT_IMPLEMENTED, gwi.parseErrorText, gwi);
|
||||
return ER_CHECK_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -738,7 +738,6 @@ int ha_mcs_group_by_handler::end_scan()
|
||||
* thd - THD pointer.
|
||||
* sel_lex - SELECT_LEX* that describes the query.
|
||||
* sel_unit - SELECT_LEX_UNIT* that describes the query.
|
||||
* Only one of sel_lex and sel_unit is not null.
|
||||
* RETURN:
|
||||
* select_handler if possible
|
||||
* NULL in other case
|
||||
@ -816,15 +815,15 @@ select_handler* create_columnstore_select_handler_(THD* thd, SELECT_LEX* sel_lex
|
||||
// or unsupported feature.
|
||||
ha_columnstore_select_handler* handler;
|
||||
|
||||
if (sel_unit && sel_lex)
|
||||
if (sel_unit && sel_lex) // partial pushdown of the SELECT_LEX_UNIT
|
||||
{
|
||||
handler = new ha_columnstore_select_handler(thd, sel_lex, sel_unit);
|
||||
}
|
||||
else if (sel_unit)
|
||||
else if (sel_unit) // complete pushdown of the SELECT_LEX_UNIT
|
||||
{
|
||||
handler = new ha_columnstore_select_handler(thd, sel_unit);
|
||||
}
|
||||
else
|
||||
else // Query only has a SELECT_LEX, no SELECT_LEX_UNIT
|
||||
{
|
||||
handler = new ha_columnstore_select_handler(thd, sel_lex);
|
||||
}
|
||||
|
Reference in New Issue
Block a user