You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-07-30 19:23:07 +03:00
MCOL-926 Handle NULLs better for UDAF
This commit is contained in:
@ -1850,6 +1850,8 @@ void RowAggregation::doUDAF(const Row& rowIn, int64_t colIn, int64_t colOut, int
|
|||||||
|
|
||||||
mcsv1sdk::ColumnDatum datum;
|
mcsv1sdk::ColumnDatum datum;
|
||||||
|
|
||||||
|
if (!rgContext.isParamNull(0))
|
||||||
|
{
|
||||||
switch (colDataType)
|
switch (colDataType)
|
||||||
{
|
{
|
||||||
case execplan::CalpontSystemCatalog::TINYINT:
|
case execplan::CalpontSystemCatalog::TINYINT:
|
||||||
@ -1917,6 +1919,7 @@ void RowAggregation::doUDAF(const Row& rowIn, int64_t colIn, int64_t colOut, int
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
valsIn.push_back(datum);
|
valsIn.push_back(datum);
|
||||||
|
|
||||||
// The intermediate values are stored in userData referenced by colAux.
|
// The intermediate values are stored in userData referenced by colAux.
|
||||||
@ -3720,11 +3723,22 @@ void RowAggregationUMP2::doUDAF(const Row& rowIn, int64_t colIn, int64_t colOut,
|
|||||||
static_any::any valOut;
|
static_any::any valOut;
|
||||||
mcsv1sdk::mcsv1Context rgContext(rowUDAF->fUDAFContext);
|
mcsv1sdk::mcsv1Context rgContext(rowUDAF->fUDAFContext);
|
||||||
|
|
||||||
// Turn on NULL flags
|
// Get the user data
|
||||||
|
boost::shared_ptr<mcsv1sdk::UserData> userData = rowIn.getUserData(colIn+1);
|
||||||
|
|
||||||
|
// Unlike other aggregates, the data isn't in colIn, so testing it for NULL
|
||||||
|
// there won't help. In case of NULL, userData will be NULL.
|
||||||
std::vector<uint32_t> flags;
|
std::vector<uint32_t> flags;
|
||||||
uint32_t flag = 0;
|
uint32_t flag = 0;
|
||||||
if (isNull(&fRowGroupIn, rowIn, colIn) == true)
|
if (!userData)
|
||||||
|
{
|
||||||
|
if (rgContext.getRunFlag(mcsv1sdk::UDAF_IGNORE_NULLS))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Turn on NULL flags
|
||||||
flag |= mcsv1sdk::PARAM_IS_NULL;
|
flag |= mcsv1sdk::PARAM_IS_NULL;
|
||||||
|
}
|
||||||
flags.push_back(flag);
|
flags.push_back(flag);
|
||||||
rgContext.setDataFlags(&flags);
|
rgContext.setDataFlags(&flags);
|
||||||
|
|
||||||
@ -3733,12 +3747,6 @@ void RowAggregationUMP2::doUDAF(const Row& rowIn, int64_t colIn, int64_t colOut,
|
|||||||
|
|
||||||
// Call the UDAF subEvaluate method
|
// Call the UDAF subEvaluate method
|
||||||
mcsv1sdk::mcsv1_UDAF::ReturnCode rc;
|
mcsv1sdk::mcsv1_UDAF::ReturnCode rc;
|
||||||
boost::shared_ptr<mcsv1sdk::UserData> userData = rowIn.getUserData(colIn+1);
|
|
||||||
if (!userData)
|
|
||||||
{
|
|
||||||
rowUDAF->bInterrupted = true;
|
|
||||||
throw logic_error("UDAF subevaluate : No userData");
|
|
||||||
}
|
|
||||||
rc = rgContext.getFunction()->subEvaluate(&rgContext, userData.get());
|
rc = rgContext.getFunction()->subEvaluate(&rgContext, userData.get());
|
||||||
rgContext.setUserData(NULL);
|
rgContext.setUserData(NULL);
|
||||||
if (rc == mcsv1sdk::mcsv1_UDAF::ERROR)
|
if (rc == mcsv1sdk::mcsv1_UDAF::ERROR)
|
||||||
|
@ -62,7 +62,7 @@ mcsv1_UDAF::ReturnCode ssq::init(mcsv1Context* context,
|
|||||||
context->setColWidth(8);
|
context->setColWidth(8);
|
||||||
context->setScale(context->getScale()*2);
|
context->setScale(context->getScale()*2);
|
||||||
context->setPrecision(19);
|
context->setPrecision(19);
|
||||||
context->setRunFlag(mcsv1sdk::UDAF_IGNORE_NULLS);
|
// context->setRunFlag(mcsv1sdk::UDAF_IGNORE_NULLS);
|
||||||
return mcsv1_UDAF::SUCCESS;
|
return mcsv1_UDAF::SUCCESS;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -85,9 +85,9 @@ mcsv1_UDAF::ReturnCode ssq::nextValue(mcsv1Context* context,
|
|||||||
struct ssq_data* data = (struct ssq_data*)context->getUserData()->data;
|
struct ssq_data* data = (struct ssq_data*)context->getUserData()->data;
|
||||||
DATATYPE val = 0.0;
|
DATATYPE val = 0.0;
|
||||||
|
|
||||||
if (valIn.empty())
|
if (context->isParamNull(0) || valIn.empty())
|
||||||
{
|
{
|
||||||
return mcsv1_UDAF::SUCCESS; // Ought not happen when UDAF_IGNORE_NULLS is on.
|
return mcsv1_UDAF::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valIn.compatible(charTypeId))
|
if (valIn.compatible(charTypeId))
|
||||||
@ -155,6 +155,12 @@ mcsv1_UDAF::ReturnCode ssq::nextValue(mcsv1Context* context,
|
|||||||
|
|
||||||
mcsv1_UDAF::ReturnCode ssq::subEvaluate(mcsv1Context* context, const UserData* userDataIn)
|
mcsv1_UDAF::ReturnCode ssq::subEvaluate(mcsv1Context* context, const UserData* userDataIn)
|
||||||
{
|
{
|
||||||
|
// If we turn off UDAF_IGNORE_NULLS in init(), then NULLS may be sent here in cases of Joins.
|
||||||
|
// When a NULL value is sent here, userDataIn will be NULL, so check for NULLS.
|
||||||
|
if (context->isParamNull(0))
|
||||||
|
{
|
||||||
|
return mcsv1_UDAF::SUCCESS;
|
||||||
|
}
|
||||||
struct ssq_data* outData = (struct ssq_data*)context->getUserData()->data;
|
struct ssq_data* outData = (struct ssq_data*)context->getUserData()->data;
|
||||||
struct ssq_data* inData = (struct ssq_data*)userDataIn->data;
|
struct ssq_data* inData = (struct ssq_data*)userDataIn->data;
|
||||||
outData->sumsq += inData->sumsq;
|
outData->sumsq += inData->sumsq;
|
||||||
|
Reference in New Issue
Block a user