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,71 +1850,74 @@ void RowAggregation::doUDAF(const Row& rowIn, int64_t colIn, int64_t colOut, int
|
||||
|
||||
mcsv1sdk::ColumnDatum datum;
|
||||
|
||||
switch (colDataType)
|
||||
if (!rgContext.isParamNull(0))
|
||||
{
|
||||
case execplan::CalpontSystemCatalog::TINYINT:
|
||||
case execplan::CalpontSystemCatalog::SMALLINT:
|
||||
case execplan::CalpontSystemCatalog::MEDINT:
|
||||
case execplan::CalpontSystemCatalog::INT:
|
||||
case execplan::CalpontSystemCatalog::BIGINT:
|
||||
case execplan::CalpontSystemCatalog::DECIMAL:
|
||||
case execplan::CalpontSystemCatalog::UDECIMAL:
|
||||
switch (colDataType)
|
||||
{
|
||||
datum.dataType = execplan::CalpontSystemCatalog::BIGINT;
|
||||
datum.columnData = rowIn.getIntField(colIn);
|
||||
datum.scale = fRowGroupIn.getScale()[colIn];
|
||||
datum.precision = fRowGroupIn.getPrecision()[colIn];
|
||||
break;
|
||||
}
|
||||
case execplan::CalpontSystemCatalog::UTINYINT:
|
||||
case execplan::CalpontSystemCatalog::USMALLINT:
|
||||
case execplan::CalpontSystemCatalog::UMEDINT:
|
||||
case execplan::CalpontSystemCatalog::UINT:
|
||||
case execplan::CalpontSystemCatalog::UBIGINT:
|
||||
{
|
||||
datum.dataType = execplan::CalpontSystemCatalog::UBIGINT;
|
||||
datum.columnData = rowIn.getUintField(colIn);
|
||||
break;
|
||||
}
|
||||
case execplan::CalpontSystemCatalog::DOUBLE:
|
||||
case execplan::CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
datum.dataType = execplan::CalpontSystemCatalog::DOUBLE;
|
||||
datum.columnData = rowIn.getDoubleField(colIn);
|
||||
break;
|
||||
}
|
||||
case execplan::CalpontSystemCatalog::FLOAT:
|
||||
case execplan::CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
datum.dataType = execplan::CalpontSystemCatalog::FLOAT;
|
||||
datum.columnData = rowIn.getFloatField(colIn);
|
||||
break;
|
||||
}
|
||||
case execplan::CalpontSystemCatalog::DATE:
|
||||
case execplan::CalpontSystemCatalog::DATETIME:
|
||||
{
|
||||
datum.dataType = execplan::CalpontSystemCatalog::UBIGINT;
|
||||
datum.columnData = rowIn.getUintField(colIn);
|
||||
break;
|
||||
}
|
||||
case execplan::CalpontSystemCatalog::CHAR:
|
||||
case execplan::CalpontSystemCatalog::VARCHAR:
|
||||
case execplan::CalpontSystemCatalog::TEXT:
|
||||
case execplan::CalpontSystemCatalog::VARBINARY:
|
||||
case execplan::CalpontSystemCatalog::CLOB:
|
||||
case execplan::CalpontSystemCatalog::BLOB:
|
||||
{
|
||||
datum.dataType = colDataType;
|
||||
datum.columnData = rowIn.getStringField(colIn);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << "RowAggregation " << rgContext.getName() <<
|
||||
": No logic for data type: " << colDataType;
|
||||
throw logging::QueryDataExcept(errmsg.str(), logging::aggregateFuncErr);
|
||||
break;
|
||||
case execplan::CalpontSystemCatalog::TINYINT:
|
||||
case execplan::CalpontSystemCatalog::SMALLINT:
|
||||
case execplan::CalpontSystemCatalog::MEDINT:
|
||||
case execplan::CalpontSystemCatalog::INT:
|
||||
case execplan::CalpontSystemCatalog::BIGINT:
|
||||
case execplan::CalpontSystemCatalog::DECIMAL:
|
||||
case execplan::CalpontSystemCatalog::UDECIMAL:
|
||||
{
|
||||
datum.dataType = execplan::CalpontSystemCatalog::BIGINT;
|
||||
datum.columnData = rowIn.getIntField(colIn);
|
||||
datum.scale = fRowGroupIn.getScale()[colIn];
|
||||
datum.precision = fRowGroupIn.getPrecision()[colIn];
|
||||
break;
|
||||
}
|
||||
case execplan::CalpontSystemCatalog::UTINYINT:
|
||||
case execplan::CalpontSystemCatalog::USMALLINT:
|
||||
case execplan::CalpontSystemCatalog::UMEDINT:
|
||||
case execplan::CalpontSystemCatalog::UINT:
|
||||
case execplan::CalpontSystemCatalog::UBIGINT:
|
||||
{
|
||||
datum.dataType = execplan::CalpontSystemCatalog::UBIGINT;
|
||||
datum.columnData = rowIn.getUintField(colIn);
|
||||
break;
|
||||
}
|
||||
case execplan::CalpontSystemCatalog::DOUBLE:
|
||||
case execplan::CalpontSystemCatalog::UDOUBLE:
|
||||
{
|
||||
datum.dataType = execplan::CalpontSystemCatalog::DOUBLE;
|
||||
datum.columnData = rowIn.getDoubleField(colIn);
|
||||
break;
|
||||
}
|
||||
case execplan::CalpontSystemCatalog::FLOAT:
|
||||
case execplan::CalpontSystemCatalog::UFLOAT:
|
||||
{
|
||||
datum.dataType = execplan::CalpontSystemCatalog::FLOAT;
|
||||
datum.columnData = rowIn.getFloatField(colIn);
|
||||
break;
|
||||
}
|
||||
case execplan::CalpontSystemCatalog::DATE:
|
||||
case execplan::CalpontSystemCatalog::DATETIME:
|
||||
{
|
||||
datum.dataType = execplan::CalpontSystemCatalog::UBIGINT;
|
||||
datum.columnData = rowIn.getUintField(colIn);
|
||||
break;
|
||||
}
|
||||
case execplan::CalpontSystemCatalog::CHAR:
|
||||
case execplan::CalpontSystemCatalog::VARCHAR:
|
||||
case execplan::CalpontSystemCatalog::TEXT:
|
||||
case execplan::CalpontSystemCatalog::VARBINARY:
|
||||
case execplan::CalpontSystemCatalog::CLOB:
|
||||
case execplan::CalpontSystemCatalog::BLOB:
|
||||
{
|
||||
datum.dataType = colDataType;
|
||||
datum.columnData = rowIn.getStringField(colIn);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
std::ostringstream errmsg;
|
||||
errmsg << "RowAggregation " << rgContext.getName() <<
|
||||
": No logic for data type: " << colDataType;
|
||||
throw logging::QueryDataExcept(errmsg.str(), logging::aggregateFuncErr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
valsIn.push_back(datum);
|
||||
@ -3720,11 +3723,22 @@ void RowAggregationUMP2::doUDAF(const Row& rowIn, int64_t colIn, int64_t colOut,
|
||||
static_any::any valOut;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
flags.push_back(flag);
|
||||
rgContext.setDataFlags(&flags);
|
||||
|
||||
@ -3733,12 +3747,6 @@ void RowAggregationUMP2::doUDAF(const Row& rowIn, int64_t colIn, int64_t colOut,
|
||||
|
||||
// Call the UDAF subEvaluate method
|
||||
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());
|
||||
rgContext.setUserData(NULL);
|
||||
if (rc == mcsv1sdk::mcsv1_UDAF::ERROR)
|
||||
|
@ -62,7 +62,7 @@ mcsv1_UDAF::ReturnCode ssq::init(mcsv1Context* context,
|
||||
context->setColWidth(8);
|
||||
context->setScale(context->getScale()*2);
|
||||
context->setPrecision(19);
|
||||
context->setRunFlag(mcsv1sdk::UDAF_IGNORE_NULLS);
|
||||
// context->setRunFlag(mcsv1sdk::UDAF_IGNORE_NULLS);
|
||||
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;
|
||||
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))
|
||||
@ -155,6 +155,12 @@ mcsv1_UDAF::ReturnCode ssq::nextValue(mcsv1Context* context,
|
||||
|
||||
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* inData = (struct ssq_data*)userDataIn->data;
|
||||
outData->sumsq += inData->sumsq;
|
||||
|
Reference in New Issue
Block a user