You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-02 17:22:27 +03:00
Replace underlying type for avg and sum for int types from long double to wide decimal
This commit is contained in:
@ -361,7 +361,6 @@ static inline bool isWideDecimalType(const datatypes::SystemCatalog::ColDataType
|
|||||||
dt == SystemCatalog::UDECIMAL);
|
dt == SystemCatalog::UDECIMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** convenience function to determine if column type is a char
|
/** convenience function to determine if column type is a char
|
||||||
* type
|
* type
|
||||||
*/
|
*/
|
||||||
@ -480,27 +479,18 @@ inline bool isSignedInteger(const datatypes::SystemCatalog::ColDataType type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@brief Returns true if all arguments have a DECIMAL/UDECIMAL type
|
@brief The method netects whether type sum and avg aggregate will have
|
||||||
|
wide decimal underlying type
|
||||||
*/
|
*/
|
||||||
static inline bool isDecimalOperands(const SystemCatalog::ColDataType resultDataType,
|
inline bool hasUnderlyingWideDecimalForSumAndAvg(datatypes::SystemCatalog::ColDataType type)
|
||||||
const SystemCatalog::ColDataType leftColDataType,
|
|
||||||
const SystemCatalog::ColDataType rightColDataType)
|
|
||||||
{
|
{
|
||||||
return ((resultDataType == SystemCatalog::DECIMAL ||
|
return datatypes::isSignedInteger(type) || datatypes::isUnsigned(type);
|
||||||
resultDataType == SystemCatalog::UDECIMAL) &&
|
|
||||||
(leftColDataType == SystemCatalog::DECIMAL ||
|
|
||||||
leftColDataType == SystemCatalog::UDECIMAL) &&
|
|
||||||
(rightColDataType == SystemCatalog::DECIMAL ||
|
|
||||||
rightColDataType == SystemCatalog::UDECIMAL));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of namespace datatypes
|
} // end of namespace datatypes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace datatypes
|
namespace datatypes
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -1957,7 +1947,7 @@ public:
|
|||||||
MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr,
|
MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr,
|
||||||
const MinMaxInfo &a,
|
const MinMaxInfo &a,
|
||||||
const MinMaxInfo &b) const override
|
const MinMaxInfo &b) const override
|
||||||
{
|
{
|
||||||
return MinMaxInfo::widenSInt64(a, b);
|
return MinMaxInfo::widenSInt64(a, b);
|
||||||
}
|
}
|
||||||
MinMaxPartitionInfo getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr,
|
MinMaxPartitionInfo getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr,
|
||||||
@ -2038,7 +2028,7 @@ public:
|
|||||||
MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr,
|
MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr,
|
||||||
const MinMaxInfo &a,
|
const MinMaxInfo &a,
|
||||||
const MinMaxInfo &b) const override
|
const MinMaxInfo &b) const override
|
||||||
{
|
{
|
||||||
return MinMaxInfo::widenSInt64(a, b);
|
return MinMaxInfo::widenSInt64(a, b);
|
||||||
}
|
}
|
||||||
MinMaxPartitionInfo getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr,
|
MinMaxPartitionInfo getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr,
|
||||||
@ -2123,7 +2113,7 @@ public:
|
|||||||
MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr,
|
MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr,
|
||||||
const MinMaxInfo &a,
|
const MinMaxInfo &a,
|
||||||
const MinMaxInfo &b) const override
|
const MinMaxInfo &b) const override
|
||||||
{
|
{
|
||||||
return MinMaxInfo::widenSInt128(a, b);
|
return MinMaxInfo::widenSInt128(a, b);
|
||||||
}
|
}
|
||||||
MinMaxPartitionInfo getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr,
|
MinMaxPartitionInfo getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr,
|
||||||
@ -2202,7 +2192,7 @@ public:
|
|||||||
MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr,
|
MinMaxInfo widenMinMaxInfo(const SystemCatalog::TypeAttributesStd &attr,
|
||||||
const MinMaxInfo &a,
|
const MinMaxInfo &a,
|
||||||
const MinMaxInfo &b) const override
|
const MinMaxInfo &b) const override
|
||||||
{
|
{
|
||||||
return MinMaxInfo::widenSInt128(a, b);
|
return MinMaxInfo::widenSInt128(a, b);
|
||||||
}
|
}
|
||||||
MinMaxPartitionInfo getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr,
|
MinMaxPartitionInfo getExtentPartitionInfo(const SystemCatalog::TypeAttributesStd &attr,
|
||||||
|
@ -285,7 +285,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
decimal.scale = fResultType.scale;
|
decimal.scale = fResultType.scale;
|
||||||
decimal.precision = fResultType.precision;
|
decimal.precision = std::max(fResultType.precision, static_cast<int32_t>(decimal.precision));
|
||||||
return decimal;
|
return decimal;
|
||||||
}
|
}
|
||||||
virtual bool getBoolVal(rowgroup::Row& row, bool& isNull)
|
virtual bool getBoolVal(rowgroup::Row& row, bool& isNull)
|
||||||
|
@ -361,6 +361,13 @@ void wideDecimalOrLongDouble(const uint64_t colProj,
|
|||||||
precisionAgg.push_back(precisionProj[colProj]);
|
precisionAgg.push_back(precisionProj[colProj]);
|
||||||
widthAgg.push_back(width[colProj]);
|
widthAgg.push_back(width[colProj]);
|
||||||
}
|
}
|
||||||
|
else if (datatypes::hasUnderlyingWideDecimalForSumAndAvg(type))
|
||||||
|
{
|
||||||
|
typeAgg.push_back(CalpontSystemCatalog::DECIMAL);
|
||||||
|
scaleAgg.push_back(0);
|
||||||
|
precisionAgg.push_back(datatypes::INT128MAXPRECISION);
|
||||||
|
widthAgg.push_back(datatypes::MAXDECIMALWIDTH);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
typeAgg.push_back(CalpontSystemCatalog::LONGDOUBLE);
|
typeAgg.push_back(CalpontSystemCatalog::LONGDOUBLE);
|
||||||
@ -1683,6 +1690,14 @@ void TupleAggregateStep::prep1PhaseDistinctAggregate(
|
|||||||
// for count column of average function
|
// for count column of average function
|
||||||
map<uint32_t, SP_ROWAGG_FUNC_t> avgFuncMap, avgDistFuncMap;
|
map<uint32_t, SP_ROWAGG_FUNC_t> avgFuncMap, avgDistFuncMap;
|
||||||
|
|
||||||
|
// collect the projected column info, prepare for aggregation
|
||||||
|
vector<uint32_t> width;
|
||||||
|
for (uint64_t i = 0; i < keysProj.size(); i++)
|
||||||
|
{
|
||||||
|
width.push_back(projRG.getColumnWidth(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// associate the columns between projected RG and aggregate RG on UM
|
// associate the columns between projected RG and aggregate RG on UM
|
||||||
// populated the aggregate columns
|
// populated the aggregate columns
|
||||||
// the groupby columns are put in front, even not a returned column
|
// the groupby columns are put in front, even not a returned column
|
||||||
@ -1934,11 +1949,10 @@ void TupleAggregateStep::prep1PhaseDistinctAggregate(
|
|||||||
|
|
||||||
oidsAgg.push_back(oidsProj[colProj]);
|
oidsAgg.push_back(oidsProj[colProj]);
|
||||||
keysAgg.push_back(aggKey);
|
keysAgg.push_back(aggKey);
|
||||||
typeAgg.push_back(CalpontSystemCatalog::LONGDOUBLE);
|
|
||||||
csNumAgg.push_back(8);
|
csNumAgg.push_back(8);
|
||||||
precisionAgg.push_back(-1);
|
wideDecimalOrLongDouble(colProj, typeProj[colProj],
|
||||||
widthAgg.push_back(sizeof(long double));
|
precisionProj, scaleProj, width,
|
||||||
scaleAgg.push_back(0);
|
typeAgg, scaleAgg, precisionAgg, widthAgg);
|
||||||
colAgg++;
|
colAgg++;
|
||||||
|
|
||||||
// has distinct step, put the count column for avg next to the sum
|
// has distinct step, put the count column for avg next to the sum
|
||||||
@ -2265,11 +2279,10 @@ void TupleAggregateStep::prep1PhaseDistinctAggregate(
|
|||||||
|
|
||||||
oidsAggDist.push_back(oidsAgg[colAgg]);
|
oidsAggDist.push_back(oidsAgg[colAgg]);
|
||||||
keysAggDist.push_back(retKey);
|
keysAggDist.push_back(retKey);
|
||||||
typeAggDist.push_back(CalpontSystemCatalog::LONGDOUBLE);
|
wideDecimalOrLongDouble(colAgg, typeAgg[colAgg],
|
||||||
|
precisionAgg, scaleAgg, widthAgg,
|
||||||
|
typeAggDist, scaleAggDist, precisionAggDist, widthAggDist);
|
||||||
csNumAggDist.push_back(8);
|
csNumAggDist.push_back(8);
|
||||||
precisionAggDist.push_back(-1);
|
|
||||||
widthAggDist.push_back(sizeof(long double));
|
|
||||||
scaleAggDist.push_back(0);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2343,11 +2356,10 @@ void TupleAggregateStep::prep1PhaseDistinctAggregate(
|
|||||||
{
|
{
|
||||||
oidsAggDist.push_back(oidsAgg[colAgg]);
|
oidsAggDist.push_back(oidsAgg[colAgg]);
|
||||||
keysAggDist.push_back(retKey);
|
keysAggDist.push_back(retKey);
|
||||||
scaleAggDist.push_back(0);
|
|
||||||
typeAggDist.push_back(CalpontSystemCatalog::LONGDOUBLE);
|
|
||||||
csNumAggDist.push_back(8);
|
csNumAggDist.push_back(8);
|
||||||
precisionAggDist.push_back(-1);
|
wideDecimalOrLongDouble(colAgg, typeAgg[colAgg],
|
||||||
widthAggDist.push_back(sizeof(long double));
|
precisionAgg, scaleAgg, widthAgg,
|
||||||
|
typeAggDist, scaleAggDist, precisionAggDist, widthAggDist);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -4166,11 +4178,10 @@ void TupleAggregateStep::prep2PhasesDistinctAggregate(
|
|||||||
|
|
||||||
oidsAggPm.push_back(oidsProj[colProj]);
|
oidsAggPm.push_back(oidsProj[colProj]);
|
||||||
keysAggPm.push_back(aggKey);
|
keysAggPm.push_back(aggKey);
|
||||||
typeAggPm.push_back(CalpontSystemCatalog::LONGDOUBLE);
|
|
||||||
csNumAggPm.push_back(8);
|
csNumAggPm.push_back(8);
|
||||||
precisionAggPm.push_back(-1);
|
wideDecimalOrLongDouble(colProj, typeProj[colProj],
|
||||||
widthAggPm.push_back(sizeof(long double));
|
precisionProj, scaleProj, width,
|
||||||
scaleAggPm.push_back(0);
|
typeAggPm, scaleAggPm, precisionAggPm, widthAggPm);
|
||||||
colAggPm++;
|
colAggPm++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4546,11 +4557,10 @@ void TupleAggregateStep::prep2PhasesDistinctAggregate(
|
|||||||
|
|
||||||
oidsAggDist.push_back(oidsAggUm[colUm]);
|
oidsAggDist.push_back(oidsAggUm[colUm]);
|
||||||
keysAggDist.push_back(retKey);
|
keysAggDist.push_back(retKey);
|
||||||
typeAggDist.push_back(CalpontSystemCatalog::LONGDOUBLE);
|
|
||||||
csNumAggDist.push_back(8);
|
csNumAggDist.push_back(8);
|
||||||
precisionAggDist.push_back(-1);
|
wideDecimalOrLongDouble(colUm, typeAggPm[colUm],
|
||||||
widthAggDist.push_back(sizeof(long double));
|
precisionAggPm, scaleAggPm, widthAggPm,
|
||||||
scaleAggDist.push_back(0);
|
typeAggDist, scaleAggDist, precisionAggDist, widthAggDist);
|
||||||
}
|
}
|
||||||
// PM: put the count column for avg next to the sum
|
// PM: put the count column for avg next to the sum
|
||||||
// let fall through to add a count column for average function
|
// let fall through to add a count column for average function
|
||||||
@ -4614,11 +4624,10 @@ void TupleAggregateStep::prep2PhasesDistinctAggregate(
|
|||||||
{
|
{
|
||||||
oidsAggDist.push_back(oidsAggUm[colUm]);
|
oidsAggDist.push_back(oidsAggUm[colUm]);
|
||||||
keysAggDist.push_back(retKey);
|
keysAggDist.push_back(retKey);
|
||||||
scaleAggDist.push_back(0);
|
|
||||||
typeAggDist.push_back(CalpontSystemCatalog::LONGDOUBLE);
|
|
||||||
csNumAggDist.push_back(8);
|
csNumAggDist.push_back(8);
|
||||||
precisionAggDist.push_back(-1);
|
wideDecimalOrLongDouble(colUm, typeAggUm[colUm],
|
||||||
widthAggDist.push_back(sizeof(long double));
|
precisionAggUm, scaleAggUm, widthAggUm,
|
||||||
|
typeAggDist, scaleAggDist, precisionAggDist, widthAggDist);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -342,7 +342,7 @@ bool nonConstFunc(Item_func* ifp)
|
|||||||
***********************************************************/
|
***********************************************************/
|
||||||
void getColNameFromItem(std::ostringstream& ostream, Item* item)
|
void getColNameFromItem(std::ostringstream& ostream, Item* item)
|
||||||
{
|
{
|
||||||
// Item_func doesn't have proper db.table.field values
|
// Item_func doesn't have proper db.table.field values
|
||||||
// inherited from Item_ident. TBD what is the valid output.
|
// inherited from Item_ident. TBD what is the valid output.
|
||||||
// !!!dynamic_cast fails compilation
|
// !!!dynamic_cast fails compilation
|
||||||
ostream << "'";
|
ostream << "'";
|
||||||
@ -506,7 +506,7 @@ bool sortItemIsInGrouping(Item* sort_item, ORDER* groupcol)
|
|||||||
{
|
{
|
||||||
Item* group_item = *(groupcol->item);
|
Item* group_item = *(groupcol->item);
|
||||||
found = (group_item->eq(sort_item, false)) ? true : false;
|
found = (group_item->eq(sort_item, false)) ? true : false;
|
||||||
// Detect aggregation functions first then traverse
|
// Detect aggregation functions first then traverse
|
||||||
// if sort field is a Func and group field
|
// if sort field is a Func and group field
|
||||||
// is either Field or Func
|
// is either Field or Func
|
||||||
// Consider nonConstFunc() check here
|
// Consider nonConstFunc() check here
|
||||||
@ -524,9 +524,9 @@ bool sortItemIsInGrouping(Item* sort_item, ORDER* groupcol)
|
|||||||
/*@brief buildAggFrmTempField- build aggr func from extSELECT list item*/
|
/*@brief buildAggFrmTempField- build aggr func from extSELECT list item*/
|
||||||
/***********************************************************
|
/***********************************************************
|
||||||
* DESCRIPTION:
|
* DESCRIPTION:
|
||||||
* Server adds additional aggregation items to extended SELECT list and
|
* Server adds additional aggregation items to extended SELECT list and
|
||||||
* references them in projection and HAVING. This f() finds
|
* references them in projection and HAVING. This f() finds
|
||||||
* corresponding item in extSelAggColsItems and builds
|
* corresponding item in extSelAggColsItems and builds
|
||||||
* ReturnedColumn using the item.
|
* ReturnedColumn using the item.
|
||||||
* PARAMETERS:
|
* PARAMETERS:
|
||||||
* item Item* used to build aggregation
|
* item Item* used to build aggregation
|
||||||
@ -585,7 +585,7 @@ ReturnedColumn* buildAggFrmTempField(Item* item, gp_walk_info& gwi)
|
|||||||
* searches for semantically equal SF in the list of already
|
* searches for semantically equal SF in the list of already
|
||||||
* applied equi predicates.
|
* applied equi predicates.
|
||||||
* TODO
|
* TODO
|
||||||
* We must move find_select_handler to either future or
|
* We must move find_select_handler to either future or
|
||||||
* later execution phase.
|
* later execution phase.
|
||||||
* PARAMETERS:
|
* PARAMETERS:
|
||||||
* gwi main structure
|
* gwi main structure
|
||||||
@ -2289,7 +2289,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
|
|||||||
ConstantColumn* nlhs1 = new ConstantColumn("", ConstantColumn::NULLDATA);
|
ConstantColumn* nlhs1 = new ConstantColumn("", ConstantColumn::NULLDATA);
|
||||||
nlhs1->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
|
nlhs1->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
|
||||||
sop.reset(new PredicateOperator("isnull"));
|
sop.reset(new PredicateOperator("isnull"));
|
||||||
sop->setOpType(lhs->resultType(), rhs->resultType());
|
sop->setOpType(lhs->resultType(), rhs->resultType());
|
||||||
sfn1 = new SimpleFilter(sop, rhs, nlhs1);
|
sfn1 = new SimpleFilter(sop, rhs, nlhs1);
|
||||||
sfn1->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
|
sfn1->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
|
||||||
ParseTree* ptpl = new ParseTree(sfn1);
|
ParseTree* ptpl = new ParseTree(sfn1);
|
||||||
@ -2307,7 +2307,7 @@ bool buildPredicateItem(Item_func* ifp, gp_walk_info* gwip)
|
|||||||
ptpn->right(ptpr);
|
ptpn->right(ptpr);
|
||||||
// a = b
|
// a = b
|
||||||
sop.reset(new PredicateOperator("="));
|
sop.reset(new PredicateOperator("="));
|
||||||
sop->setOpType(lhs->resultType(), rhs->resultType());
|
sop->setOpType(lhs->resultType(), rhs->resultType());
|
||||||
sfo = new SimpleFilter(sop, lhs->clone(), rhs->clone());
|
sfo = new SimpleFilter(sop, lhs->clone(), rhs->clone());
|
||||||
sfo->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
|
sfo->timeZone(gwip->thd->variables.time_zone->get_name()->ptr());
|
||||||
// OR with the NULL comparison tree
|
// OR with the NULL comparison tree
|
||||||
@ -3158,7 +3158,7 @@ CalpontSystemCatalog::ColType colType_MysqlToIDB (const Item* item)
|
|||||||
ct.colDataType = CalpontSystemCatalog::VARCHAR;
|
ct.colDataType = CalpontSystemCatalog::VARCHAR;
|
||||||
|
|
||||||
// MCOL-4758 the longest TEXT we deal with is 16777215 so
|
// MCOL-4758 the longest TEXT we deal with is 16777215 so
|
||||||
// limit to that.
|
// limit to that.
|
||||||
if (item->max_length < 16777215)
|
if (item->max_length < 16777215)
|
||||||
ct.colWidth = item->max_length;
|
ct.colWidth = item->max_length;
|
||||||
else
|
else
|
||||||
@ -3444,7 +3444,7 @@ ReturnedColumn* buildReturnedColumn(
|
|||||||
gwi.fatalParseError = true;
|
gwi.fatalParseError = true;
|
||||||
gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_SELECT_SUB);
|
gwi.parseErrorText = IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORT_SELECT_SUB);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
gwi.fatalParseError = true;
|
gwi.fatalParseError = true;
|
||||||
gwi.parseErrorText = "Unknown REF item";
|
gwi.parseErrorText = "Unknown REF item";
|
||||||
@ -3541,7 +3541,7 @@ ReturnedColumn* buildReturnedColumn(
|
|||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
rc->charsetNumber(item->collation.collation->number);
|
rc->charsetNumber(item->collation.collation->number);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3725,9 +3725,7 @@ ArithmeticColumn* buildArithmeticColumn(
|
|||||||
const CalpontSystemCatalog::ColType& leftColType = pt->left()->data()->resultType();
|
const CalpontSystemCatalog::ColType& leftColType = pt->left()->data()->resultType();
|
||||||
const CalpontSystemCatalog::ColType& rightColType = pt->right()->data()->resultType();
|
const CalpontSystemCatalog::ColType& rightColType = pt->right()->data()->resultType();
|
||||||
|
|
||||||
// Only tinker with the type if all columns involved are decimal
|
if (datatypes::isDecimal(leftColType.colDataType) || datatypes::isDecimal(rightColType.colDataType))
|
||||||
if (datatypes::isDecimalOperands(mysqlType.colDataType,
|
|
||||||
leftColType.colDataType, rightColType.colDataType))
|
|
||||||
{
|
{
|
||||||
int32_t leftColWidth = leftColType.colWidth;
|
int32_t leftColWidth = leftColType.colWidth;
|
||||||
int32_t rightColWidth = rightColType.colWidth;
|
int32_t rightColWidth = rightColType.colWidth;
|
||||||
@ -3742,6 +3740,8 @@ ArithmeticColumn* buildArithmeticColumn(
|
|||||||
int32_t scale1 = leftColType.scale;
|
int32_t scale1 = leftColType.scale;
|
||||||
int32_t scale2 = rightColType.scale;
|
int32_t scale2 = rightColType.scale;
|
||||||
|
|
||||||
|
mysqlType.precision = datatypes::INT128MAXPRECISION;
|
||||||
|
|
||||||
if (funcName == "/" &&
|
if (funcName == "/" &&
|
||||||
(mysqlType.scale - (scale1 - scale2)) > datatypes::INT128MAXPRECISION)
|
(mysqlType.scale - (scale1 - scale2)) > datatypes::INT128MAXPRECISION)
|
||||||
{
|
{
|
||||||
@ -4276,7 +4276,7 @@ ReturnedColumn* buildFunctionColumn(
|
|||||||
fc->resultType(ct);
|
fc->resultType(ct);
|
||||||
}
|
}
|
||||||
fc->expressionId(ci->expressionId++);
|
fc->expressionId(ci->expressionId++);
|
||||||
// A few functions use a different collation than that found in
|
// A few functions use a different collation than that found in
|
||||||
// the base ifp class
|
// the base ifp class
|
||||||
if (funcName == "locate" ||
|
if (funcName == "locate" ||
|
||||||
funcName == "find_in_set" ||
|
funcName == "find_in_set" ||
|
||||||
@ -4421,7 +4421,7 @@ FunctionColumn* buildCaseFunction(Item_func* item, gp_walk_info& gwi, bool& nonS
|
|||||||
if ((item->functype() == Item_func::CASE_SEARCHED_FUNC) &&
|
if ((item->functype() == Item_func::CASE_SEARCHED_FUNC) &&
|
||||||
(i < arg_offset))
|
(i < arg_offset))
|
||||||
{
|
{
|
||||||
// MCOL-1472 Nested CASE with an ISNULL predicate. We don't want the predicate
|
// MCOL-1472 Nested CASE with an ISNULL predicate. We don't want the predicate
|
||||||
// to pull off of rcWorkStack, so we set this inCaseStmt flag to tell it
|
// to pull off of rcWorkStack, so we set this inCaseStmt flag to tell it
|
||||||
// not to.
|
// not to.
|
||||||
gwi.inCaseStmt = true;
|
gwi.inCaseStmt = true;
|
||||||
@ -4539,7 +4539,7 @@ ConstantColumn* buildDecimalColumn(Item* item, gp_walk_info& gwi)
|
|||||||
bool specialPrecision = false;
|
bool specialPrecision = false;
|
||||||
|
|
||||||
// handle the case when the constant value is 0.12345678901234567890123456789012345678
|
// handle the case when the constant value is 0.12345678901234567890123456789012345678
|
||||||
// In this case idp->decimal_precision() = 39, but we can
|
// In this case idp->decimal_precision() = 39, but we can
|
||||||
if (((i + 1) < str->length()) &&
|
if (((i + 1) < str->length()) &&
|
||||||
str->ptr()[i] == '0' && str->ptr()[i + 1] == '.')
|
str->ptr()[i] == '0' && str->ptr()[i + 1] == '.')
|
||||||
specialPrecision = true;
|
specialPrecision = true;
|
||||||
@ -4735,7 +4735,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi)
|
|||||||
|
|
||||||
// Argument_count() is the # of formal parms to the agg fcn. Columnstore
|
// Argument_count() is the # of formal parms to the agg fcn. Columnstore
|
||||||
// only supports 1 argument except UDAnF, COUNT(DISTINC) and GROUP_CONCAT
|
// only supports 1 argument except UDAnF, COUNT(DISTINC) and GROUP_CONCAT
|
||||||
if (isp->argument_count() != 1
|
if (isp->argument_count() != 1
|
||||||
&& isp->sum_func() != Item_sum::COUNT_DISTINCT_FUNC
|
&& isp->sum_func() != Item_sum::COUNT_DISTINCT_FUNC
|
||||||
&& isp->sum_func() != Item_sum::GROUP_CONCAT_FUNC
|
&& isp->sum_func() != Item_sum::GROUP_CONCAT_FUNC
|
||||||
&& isp->sum_func() != Item_sum::UDF_SUM_FUNC)
|
&& isp->sum_func() != Item_sum::UDF_SUM_FUNC)
|
||||||
@ -4813,7 +4813,7 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi)
|
|||||||
{
|
{
|
||||||
Item* ord_col = *(*order_item)->item;
|
Item* ord_col = *(*order_item)->item;
|
||||||
|
|
||||||
if (ord_col->type() == Item::CONST_ITEM
|
if (ord_col->type() == Item::CONST_ITEM
|
||||||
&& ord_col->cmp_type() == INT_RESULT)
|
&& ord_col->cmp_type() == INT_RESULT)
|
||||||
{
|
{
|
||||||
Item_int* id = (Item_int*)ord_col;
|
Item_int* id = (Item_int*)ord_col;
|
||||||
@ -5058,6 +5058,19 @@ ReturnedColumn* buildAggregateColumn(Item* item, gp_walk_info& gwi)
|
|||||||
ct.precision = precision;
|
ct.precision = precision;
|
||||||
ct.scale = scale;
|
ct.scale = scale;
|
||||||
}
|
}
|
||||||
|
else if (datatypes::hasUnderlyingWideDecimalForSumAndAvg(ct.colDataType))
|
||||||
|
{
|
||||||
|
uint32_t precision = datatypes::INT128MAXPRECISION;
|
||||||
|
uint32_t scale = ct.scale;
|
||||||
|
ct.colDataType = CalpontSystemCatalog::DECIMAL;
|
||||||
|
ct.colWidth = datatypes::MAXDECIMALWIDTH;
|
||||||
|
if (isAvg)
|
||||||
|
{
|
||||||
|
datatypes::Decimal::setScalePrecision4Avg(precision, scale);
|
||||||
|
}
|
||||||
|
ct.scale = scale;
|
||||||
|
ct.precision = precision;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ct.colDataType = CalpontSystemCatalog::LONGDOUBLE;
|
ct.colDataType = CalpontSystemCatalog::LONGDOUBLE;
|
||||||
@ -5164,7 +5177,7 @@ because it has multiple arguments.";
|
|||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < gwi.returnedCols.size(); i++)
|
for (uint32_t i = 0; i < gwi.returnedCols.size(); i++)
|
||||||
{
|
{
|
||||||
if (*ac == gwi.returnedCols[i].get()
|
if (*ac == gwi.returnedCols[i].get()
|
||||||
&& ac->alias() == gwi.returnedCols[i].get()->alias())
|
&& ac->alias() == gwi.returnedCols[i].get()->alias())
|
||||||
ac->expressionId(gwi.returnedCols[i]->expressionId());
|
ac->expressionId(gwi.returnedCols[i]->expressionId());
|
||||||
}
|
}
|
||||||
@ -5922,7 +5935,7 @@ void gp_walk(const Item* item, void* arg)
|
|||||||
{
|
{
|
||||||
boost::shared_ptr<SimpleColumn> scsp(sc->clone());
|
boost::shared_ptr<SimpleColumn> scsp(sc->clone());
|
||||||
gwip->scsp = scsp;
|
gwip->scsp = scsp;
|
||||||
|
|
||||||
if (col->type() == Item::FIELD_ITEM)
|
if (col->type() == Item::FIELD_ITEM)
|
||||||
{
|
{
|
||||||
const auto &field_name = string(((Item_field*)item)->field_name.str);
|
const auto &field_name = string(((Item_field*)item)->field_name.str);
|
||||||
@ -6155,8 +6168,8 @@ void gp_walk(const Item* item, void* arg)
|
|||||||
* functions or arithmetic expressions for vtable post process.
|
* functions or arithmetic expressions for vtable post process.
|
||||||
*/
|
*/
|
||||||
void parse_item (Item* item, vector<Item_field*>& field_vec,
|
void parse_item (Item* item, vector<Item_field*>& field_vec,
|
||||||
bool& hasNonSupportItem,
|
bool& hasNonSupportItem,
|
||||||
uint16_t& parseInfo,
|
uint16_t& parseInfo,
|
||||||
gp_walk_info* gwi)
|
gp_walk_info* gwi)
|
||||||
{
|
{
|
||||||
Item::Type itype = item->type();
|
Item::Type itype = item->type();
|
||||||
@ -6226,7 +6239,7 @@ void parse_item (Item* item, vector<Item_field*>& field_vec,
|
|||||||
|
|
||||||
// special handling for count(*). This should not be treated as constant.
|
// special handling for count(*). This should not be treated as constant.
|
||||||
if (isp->argument_count() == 1 &&
|
if (isp->argument_count() == 1 &&
|
||||||
( sfitempp[0]->type() == Item::CONST_ITEM &&
|
( sfitempp[0]->type() == Item::CONST_ITEM &&
|
||||||
(sfitempp[0]->cmp_type() == INT_RESULT ||
|
(sfitempp[0]->cmp_type() == INT_RESULT ||
|
||||||
sfitempp[0]->cmp_type() == STRING_RESULT ||
|
sfitempp[0]->cmp_type() == STRING_RESULT ||
|
||||||
sfitempp[0]->cmp_type() == REAL_RESULT ||
|
sfitempp[0]->cmp_type() == REAL_RESULT ||
|
||||||
@ -6250,7 +6263,7 @@ void parse_item (Item* item, vector<Item_field*>& field_vec,
|
|||||||
ReturnedColumn* rc = NULL;
|
ReturnedColumn* rc = NULL;
|
||||||
if (gwi)
|
if (gwi)
|
||||||
rc = buildAggFrmTempField(ref, *gwi);
|
rc = buildAggFrmTempField(ref, *gwi);
|
||||||
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
Item_field* ifp = reinterpret_cast<Item_field*>(*(ref->ref));
|
Item_field* ifp = reinterpret_cast<Item_field*>(*(ref->ref));
|
||||||
@ -6476,7 +6489,7 @@ int processFrom(bool &isUnion,
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
string viewName = getViewName(table_ptr);
|
string viewName = getViewName(table_ptr);
|
||||||
if (lower_case_table_names)
|
if (lower_case_table_names)
|
||||||
{
|
{
|
||||||
@ -7173,7 +7186,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
setExecutionParams(gwi, csep);
|
setExecutionParams(gwi, csep);
|
||||||
|
|
||||||
gwi.subSelectType = csep->subType();
|
gwi.subSelectType = csep->subType();
|
||||||
uint32_t sessionID = csep->sessionID();
|
uint32_t sessionID = csep->sessionID();
|
||||||
gwi.sessionid = sessionID;
|
gwi.sessionid = sessionID;
|
||||||
@ -7478,7 +7491,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex,
|
|||||||
{
|
{
|
||||||
Message::Args args;
|
Message::Args args;
|
||||||
args.add(ifp->func_name());
|
args.add(ifp->func_name());
|
||||||
gwi.parseErrorText =
|
gwi.parseErrorText =
|
||||||
IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORTED_FUNCTION, args);
|
IDBErrorInfo::instance()->errorMsg(ERR_NON_SUPPORTED_FUNCTION, args);
|
||||||
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;
|
||||||
@ -7521,7 +7534,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex,
|
|||||||
}
|
}
|
||||||
// MCOL-2178 This switch doesn't handl
|
// MCOL-2178 This switch doesn't handl
|
||||||
// ROW_
|
// ROW_
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
IDEBUG(cerr << "Warning unsupported cmp_type() in projection" << endl);
|
IDEBUG(cerr << "Warning unsupported cmp_type() in projection" << endl);
|
||||||
//noop
|
//noop
|
||||||
@ -7651,7 +7664,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
@ -8141,7 +8154,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex,
|
|||||||
if ((*(ordercol->item))->type() == Item::WINDOW_FUNC_ITEM)
|
if ((*(ordercol->item))->type() == Item::WINDOW_FUNC_ITEM)
|
||||||
gwi.hasWindowFunc = true;
|
gwi.hasWindowFunc = true;
|
||||||
// MCOL-2166 Looking for this sorting item in GROUP_BY items list.
|
// MCOL-2166 Looking for this sorting item in GROUP_BY items list.
|
||||||
// Shouldn't look into this if query doesn't have GROUP BY or
|
// Shouldn't look into this if query doesn't have GROUP BY or
|
||||||
// aggregations
|
// aggregations
|
||||||
if(select_lex.agg_func_used() && select_lex.group_list.first
|
if(select_lex.agg_func_used() && select_lex.group_list.first
|
||||||
&& !sortItemIsInGrouping(*ordercol->item,
|
&& !sortItemIsInGrouping(*ordercol->item,
|
||||||
@ -8180,9 +8193,9 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex,
|
|||||||
Item* ord_item = *(ordercol->item);
|
Item* ord_item = *(ordercol->item);
|
||||||
|
|
||||||
// ignore not_used column on order by.
|
// ignore not_used column on order by.
|
||||||
if ((ord_item->type() == Item::CONST_ITEM
|
if ((ord_item->type() == Item::CONST_ITEM
|
||||||
&& ord_item->cmp_type() == INT_RESULT)
|
&& ord_item->cmp_type() == INT_RESULT)
|
||||||
&& ord_item->full_name()
|
&& ord_item->full_name()
|
||||||
&& !strcmp(ord_item->full_name(), "Not_used"))
|
&& !strcmp(ord_item->full_name(), "Not_used"))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -8325,7 +8338,7 @@ int getSelectPlan(gp_walk_info& gwi, SELECT_LEX& select_lex,
|
|||||||
for (; ordercol; ordercol = ordercol->next)
|
for (; ordercol; ordercol = ordercol->next)
|
||||||
{
|
{
|
||||||
Item* ord_item = *(ordercol->item);
|
Item* ord_item = *(ordercol->item);
|
||||||
|
|
||||||
if (ord_item->name.length)
|
if (ord_item->name.length)
|
||||||
{
|
{
|
||||||
// for union order by 1 case. For unknown reason, it doesn't show in_field_list
|
// for union order by 1 case. For unknown reason, it doesn't show in_field_list
|
||||||
@ -8681,7 +8694,7 @@ ConstantColumn* buildConstColFromFilter(SimpleColumn* originalSC,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
op = simpFilter->op();
|
op = simpFilter->op();
|
||||||
execplan::ReturnedColumn* rc = dynamic_cast<execplan::ReturnedColumn*>(simpleCol);
|
execplan::ReturnedColumn* rc = dynamic_cast<execplan::ReturnedColumn*>(simpleCol);
|
||||||
|
|
||||||
// The filter could have any kind of op
|
// The filter could have any kind of op
|
||||||
if ( originalSC->sameColumn(rc) )
|
if ( originalSC->sameColumn(rc) )
|
||||||
@ -9183,7 +9196,7 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
|||||||
boost::shared_ptr<ReturnedColumn> spac(ac);
|
boost::shared_ptr<ReturnedColumn> spac(ac);
|
||||||
gwi.returnedCols.push_back(spac);
|
gwi.returnedCols.push_back(spac);
|
||||||
// This item could be used in projection or HAVING later.
|
// This item could be used in projection or HAVING later.
|
||||||
gwi.extSelAggColsItems.push_back(item);
|
gwi.extSelAggColsItems.push_back(item);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -9973,9 +9986,9 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
|||||||
bool nonAggField = true;
|
bool nonAggField = true;
|
||||||
|
|
||||||
// ignore not_used column on order by.
|
// ignore not_used column on order by.
|
||||||
if ((ord_item->type() == Item::CONST_ITEM
|
if ((ord_item->type() == Item::CONST_ITEM
|
||||||
&& ord_item->cmp_type() == INT_RESULT)
|
&& ord_item->cmp_type() == INT_RESULT)
|
||||||
&& ord_item->full_name()
|
&& ord_item->full_name()
|
||||||
&& !strcmp(ord_item->full_name(), "Not_used"))
|
&& !strcmp(ord_item->full_name(), "Not_used"))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -10360,13 +10373,13 @@ int getGroupPlan(gp_walk_info& gwi, SELECT_LEX& select_lex, SCSEP& csep, cal_gro
|
|||||||
// LIMIT and OFFSET are extracted from TABLE_LIST elements.
|
// LIMIT and OFFSET are extracted from TABLE_LIST elements.
|
||||||
// All of JOIN-ed tables contain relevant limit and offset.
|
// All of JOIN-ed tables contain relevant limit and offset.
|
||||||
uint64_t limit = (uint64_t)-1;
|
uint64_t limit = (uint64_t)-1;
|
||||||
if (gi.groupByTables->select_lex->limit_params.select_limit &&
|
if (gi.groupByTables->select_lex->limit_params.select_limit &&
|
||||||
( limit = static_cast<Item_int*>(gi.groupByTables->select_lex->limit_params.select_limit)->val_int() ) &&
|
( limit = static_cast<Item_int*>(gi.groupByTables->select_lex->limit_params.select_limit)->val_int() ) &&
|
||||||
limit != (uint64_t)-1 )
|
limit != (uint64_t)-1 )
|
||||||
{
|
{
|
||||||
csep->limitNum(limit);
|
csep->limitNum(limit);
|
||||||
}
|
}
|
||||||
else if (csep->hasOrderBy())
|
else if (csep->hasOrderBy())
|
||||||
{
|
{
|
||||||
// We use LimitedOrderBy so set the limit to
|
// We use LimitedOrderBy so set the limit to
|
||||||
// go through the check in addOrderByAndLimit
|
// go through the check in addOrderByAndLimit
|
||||||
|
@ -1278,7 +1278,7 @@ void RowAggregation::doMinMax(const Row& rowIn, int64_t colIn, int64_t colOut, i
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void RowAggregation::doSum(const Row& rowIn, int64_t colIn, int64_t colOut, int funcType)
|
void RowAggregation::doSum(const Row& rowIn, int64_t colIn, int64_t colOut, int funcType)
|
||||||
{
|
{
|
||||||
int colDataType = rowIn.getColType(colIn);
|
datatypes::SystemCatalog::ColDataType colDataType = rowIn.getColType(colIn);
|
||||||
long double valIn = 0;
|
long double valIn = 0;
|
||||||
bool isWideDataType = false;
|
bool isWideDataType = false;
|
||||||
void *wideValInPtr = nullptr;
|
void *wideValInPtr = nullptr;
|
||||||
@ -1328,7 +1328,7 @@ void RowAggregation::doSum(const Row& rowIn, int64_t colIn, int64_t colOut, int
|
|||||||
idbassert(0);
|
idbassert(0);
|
||||||
throw std::logic_error("RowAggregation::doSum(): DECIMAL bad length.");
|
throw std::logic_error("RowAggregation::doSum(): DECIMAL bad length.");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1379,9 +1379,26 @@ void RowAggregation::doSum(const Row& rowIn, int64_t colIn, int64_t colOut, int
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (LIKELY(!isWideDataType))
|
|
||||||
|
bool notFirstValue = !isNull(fRowGroupOut, fRow, colOut);
|
||||||
|
|
||||||
|
if (datatypes::hasUnderlyingWideDecimalForSumAndAvg(colDataType) || isWideDataType)
|
||||||
{
|
{
|
||||||
if (LIKELY(!isNull(fRowGroupOut, fRow, colOut)))
|
if (LIKELY(notFirstValue))
|
||||||
|
{
|
||||||
|
int128_t *valOutPtr = fRow.getBinaryField<int128_t>(colOut);
|
||||||
|
int128_t sum = (isWideDataType) ? *valOutPtr + *reinterpret_cast<int128_t*>(wideValInPtr) : *valOutPtr + valIn;
|
||||||
|
fRow.setBinaryField(&sum, colOut);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int128_t sum = (isWideDataType) ? *reinterpret_cast<int128_t*>(wideValInPtr) : valIn;
|
||||||
|
fRow.setBinaryField(&sum, colOut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (notFirstValue)
|
||||||
{
|
{
|
||||||
long double valOut = fRow.getLongDoubleField(colOut);
|
long double valOut = fRow.getLongDoubleField(colOut);
|
||||||
fRow.setLongDoubleField(valIn+valOut, colOut);
|
fRow.setLongDoubleField(valIn+valOut, colOut);
|
||||||
@ -1390,22 +1407,7 @@ void RowAggregation::doSum(const Row& rowIn, int64_t colIn, int64_t colOut, int
|
|||||||
{
|
{
|
||||||
fRow.setLongDoubleField(valIn, colOut);
|
fRow.setLongDoubleField(valIn, colOut);
|
||||||
}
|
}
|
||||||
}
|
} // end-of long double processing block
|
||||||
else
|
|
||||||
{
|
|
||||||
uint32_t offset = fRow.getOffset(colOut);
|
|
||||||
int128_t* dec = reinterpret_cast<int128_t*>(wideValInPtr);
|
|
||||||
if (LIKELY(!isNull(fRowGroupOut, fRow, colOut)))
|
|
||||||
{
|
|
||||||
int128_t *valOutPtr = fRow.getBinaryField<int128_t>(colOut);
|
|
||||||
int128_t sum = *valOutPtr + *dec;
|
|
||||||
fRow.setBinaryField_offset(&sum, sizeof(sum), offset);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fRow.setBinaryField_offset(dec, sizeof(*dec), offset);
|
|
||||||
}
|
|
||||||
} // end-of isWideDataType block
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -1823,9 +1825,8 @@ void RowAggregation::doAvg(const Row& rowIn, int64_t colIn, int64_t colOut, int6
|
|||||||
if (rowIn.isNullValue(colIn))
|
if (rowIn.isNullValue(colIn))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int colDataType = rowIn.getColType(colIn);
|
datatypes::SystemCatalog::ColDataType colDataType = rowIn.getColType(colIn);
|
||||||
long double valIn = 0;
|
long double valIn = 0;
|
||||||
long double valOut = fRow.getLongDoubleField(colOut);
|
|
||||||
bool isWideDataType = false;
|
bool isWideDataType = false;
|
||||||
void *wideValInPtr = nullptr;
|
void *wideValInPtr = nullptr;
|
||||||
|
|
||||||
@ -1907,8 +1908,6 @@ void RowAggregation::doAvg(const Row& rowIn, int64_t colIn, int64_t colOut, int6
|
|||||||
|
|
||||||
// min(count) = 0
|
// min(count) = 0
|
||||||
uint64_t count = fRow.getUintField(colAux);
|
uint64_t count = fRow.getUintField(colAux);
|
||||||
bool notFirstValue = count > 0;
|
|
||||||
|
|
||||||
// Set count column
|
// Set count column
|
||||||
if (merge)
|
if (merge)
|
||||||
{
|
{
|
||||||
@ -1919,29 +1918,34 @@ void RowAggregation::doAvg(const Row& rowIn, int64_t colIn, int64_t colOut, int6
|
|||||||
fRow.setUintField<8>(count + 1, colAux);
|
fRow.setUintField<8>(count + 1, colAux);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set sum column
|
bool notFirstValue = count > 0;
|
||||||
if (LIKELY(!isWideDataType))
|
|
||||||
|
if (datatypes::hasUnderlyingWideDecimalForSumAndAvg(colDataType) || isWideDataType)
|
||||||
{
|
{
|
||||||
if (LIKELY(notFirstValue))
|
|
||||||
fRow.setLongDoubleField(valIn + valOut, colOut);
|
|
||||||
else // This is the first value
|
|
||||||
fRow.setLongDoubleField(valIn, colOut);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint32_t offset = fRow.getOffset(colOut);
|
|
||||||
int128_t* dec = reinterpret_cast<int128_t*>(wideValInPtr);
|
|
||||||
if (LIKELY(notFirstValue))
|
if (LIKELY(notFirstValue))
|
||||||
{
|
{
|
||||||
int128_t *valOutPtr = fRow.getBinaryField<int128_t>(colOut);
|
int128_t *valOutPtr = fRow.getBinaryField<int128_t>(colOut);
|
||||||
int128_t sum = *valOutPtr + *dec;
|
int128_t sum = (isWideDataType) ? *valOutPtr + *reinterpret_cast<int128_t*>(wideValInPtr) : *valOutPtr + valIn;
|
||||||
fRow.setBinaryField_offset(&sum, sizeof(sum), offset);
|
fRow.setBinaryField(&sum, colOut);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fRow.setBinaryField_offset(dec, sizeof(*dec), offset);
|
int128_t sum = (isWideDataType) ? *reinterpret_cast<int128_t*>(wideValInPtr) : valIn;
|
||||||
|
fRow.setBinaryField(&sum, colOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (LIKELY(notFirstValue))
|
||||||
|
{
|
||||||
|
long double valOut = fRow.getLongDoubleField(colOut);
|
||||||
|
fRow.setLongDoubleField(valIn+valOut, colOut);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fRow.setLongDoubleField(valIn, colOut);
|
||||||
|
}
|
||||||
|
} // end-of long double processing block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3614,7 +3618,7 @@ void RowAggregationUM::doNotNullConstantAggregate(const ConstantAggData& aggData
|
|||||||
{
|
{
|
||||||
fRow.setIntField(strtol(aggData.fConstValue.c_str(), nullptr, 10), colOut);
|
fRow.setIntField(strtol(aggData.fConstValue.c_str(), nullptr, 10), colOut);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// AVG should not be uint32_t result type.
|
// AVG should not be uint32_t result type.
|
||||||
case execplan::CalpontSystemCatalog::UTINYINT:
|
case execplan::CalpontSystemCatalog::UTINYINT:
|
||||||
@ -3777,7 +3781,7 @@ void RowAggregationUM::doNotNullConstantAggregate(const ConstantAggData& aggData
|
|||||||
// TODO: isn't precision loss possible below?
|
// TODO: isn't precision loss possible below?
|
||||||
dbl *= datatypes::scaleDivisor<double>(fRowGroupOut->getScale()[i]);
|
dbl *= datatypes::scaleDivisor<double>(fRowGroupOut->getScale()[i]);
|
||||||
dbl *= rowCnt;
|
dbl *= rowCnt;
|
||||||
|
|
||||||
if ((dbl > 0 && dbl > (double) numeric_limits<int64_t>::max()) ||
|
if ((dbl > 0 && dbl > (double) numeric_limits<int64_t>::max()) ||
|
||||||
(dbl < 0 && dbl < (double) numeric_limits<int64_t>::min()))
|
(dbl < 0 && dbl < (double) numeric_limits<int64_t>::min()))
|
||||||
throw logging::QueryDataExcept(overflowMsg, logging::aggregateDataErr);
|
throw logging::QueryDataExcept(overflowMsg, logging::aggregateDataErr);
|
||||||
@ -4280,9 +4284,8 @@ void RowAggregationUMP2::doAvg(const Row& rowIn, int64_t colIn, int64_t colOut,
|
|||||||
if (rowIn.isNullValue(colIn))
|
if (rowIn.isNullValue(colIn))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int colDataType = rowIn.getColType(colIn);
|
datatypes::SystemCatalog::ColDataType colDataType = rowIn.getColType(colIn);
|
||||||
long double valIn = 0;
|
long double valIn = 0;
|
||||||
long double valOut = fRow.getLongDoubleField(colOut);
|
|
||||||
bool isWideDataType = false;
|
bool isWideDataType = false;
|
||||||
void *wideValInPtr = nullptr;
|
void *wideValInPtr = nullptr;
|
||||||
|
|
||||||
@ -4362,37 +4365,39 @@ void RowAggregationUMP2::doAvg(const Row& rowIn, int64_t colIn, int64_t colOut,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t cnt = fRow.getUintField(colAux);
|
uint64_t count = fRow.getUintField(colAux);
|
||||||
if (LIKELY(!isWideDataType))
|
bool notFirstValue = count > 0;
|
||||||
|
|
||||||
|
if (datatypes::hasUnderlyingWideDecimalForSumAndAvg(colDataType) || isWideDataType)
|
||||||
{
|
{
|
||||||
if (LIKELY(cnt > 0))
|
if (LIKELY(notFirstValue))
|
||||||
{
|
{
|
||||||
fRow.setLongDoubleField(valIn + valOut, colOut);
|
int128_t *valOutPtr = fRow.getBinaryField<int128_t>(colOut);
|
||||||
fRow.setUintField(rowIn.getUintField(colIn + 1) + cnt, colAux);
|
int128_t sum = (isWideDataType) ? *valOutPtr + *reinterpret_cast<int128_t*>(wideValInPtr) : *valOutPtr + valIn;
|
||||||
|
fRow.setUintField(rowIn.getUintField(colIn + 1) + count, colAux);
|
||||||
|
fRow.setBinaryField(&sum, colOut);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fRow.setLongDoubleField(valIn, colOut);
|
int128_t sum = (isWideDataType) ? *reinterpret_cast<int128_t*>(wideValInPtr) : valIn;
|
||||||
fRow.setUintField(rowIn.getUintField(colIn + 1), colAux);
|
fRow.setUintField(rowIn.getUintField(colIn + 1), colAux);
|
||||||
|
fRow.setBinaryField(&sum, colOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint32_t offset = fRow.getOffset(colOut);
|
if (LIKELY(notFirstValue))
|
||||||
int128_t* dec = reinterpret_cast<int128_t*>(wideValInPtr);
|
|
||||||
if (LIKELY(cnt > 0))
|
|
||||||
{
|
{
|
||||||
int128_t *valOutPtr = fRow.getBinaryField<int128_t>(colOut);
|
long double valOut = fRow.getLongDoubleField(colOut);
|
||||||
int128_t sum = *valOutPtr + *dec;
|
fRow.setUintField(rowIn.getUintField(colIn + 1) + count, colAux);
|
||||||
fRow.setBinaryField_offset(&sum, sizeof(sum), offset);
|
fRow.setLongDoubleField(valIn+valOut, colOut);
|
||||||
fRow.setUintField(rowIn.getUintField(colIn + 1) + cnt, colAux);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fRow.setBinaryField_offset(dec, sizeof(*dec), offset);
|
|
||||||
fRow.setUintField(rowIn.getUintField(colIn + 1), colAux);
|
fRow.setUintField(rowIn.getUintField(colIn + 1), colAux);
|
||||||
|
fRow.setLongDoubleField(valIn, colOut);
|
||||||
}
|
}
|
||||||
}
|
} // end-of long double processing block
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user