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 5092 MODA uses wrong column width for some types (#2450)
* MCOL-5092 Ensure column width is correct for datatype Change MODA return type to STRING Modify MODA to handle every numeric type * MCOL-5162 MODA to support char and varchar with collation support Fixes to the aggregate bit functions When we fixed the storage sign issue for MCOL-5092, it uncovered a problem in the bit aggregates (bit_and, bit_or and bit_xor). These aggregates should always return UBIGINT, but they relied on the type of the argument column, which gave bad results.
This commit is contained in:
@ -5,7 +5,10 @@
|
||||
#include <string.h>
|
||||
#include <unordered_map>
|
||||
#include <algorithm>
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <charconv>
|
||||
#include "boost/lexical_cast.hpp"
|
||||
#include "idb_mysql.h"
|
||||
|
||||
namespace
|
||||
@ -48,7 +51,7 @@ struct moda_data
|
||||
} // namespace
|
||||
|
||||
template <class TYPE, class CONTAINER>
|
||||
char* moda(CONTAINER& container, struct moda_data* data)
|
||||
void moda(CONTAINER& container, struct moda_data* data)
|
||||
{
|
||||
TYPE avg = (TYPE)data->fCount ? data->fSum / data->fCount : 0;
|
||||
TYPE val = 0.0;
|
||||
@ -73,8 +76,6 @@ char* moda(CONTAINER& container, struct moda_data* data)
|
||||
}
|
||||
|
||||
data->result = std::to_string(val);
|
||||
|
||||
return const_cast<char*>(data->result.c_str());
|
||||
}
|
||||
|
||||
extern "C"
|
||||
@ -82,18 +83,22 @@ extern "C"
|
||||
#ifdef _MSC_VER
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
my_bool moda_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
|
||||
my_bool moda_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
|
||||
{
|
||||
struct moda_data* data;
|
||||
|
||||
if (args->arg_count != 1)
|
||||
{
|
||||
strcpy(message, "moda() requires one argument");
|
||||
strcpy(message, "moda() requires exactly one argument");
|
||||
return 1;
|
||||
}
|
||||
if (!isNumeric(args->arg_type[0], args->attributes[0]))
|
||||
{
|
||||
strcpy(message, "moda() with a non-numeric argument");
|
||||
return 1;
|
||||
if (args->arg_type[0] != STRING_RESULT)
|
||||
{
|
||||
strcpy(message, "moda() with an invalid argument");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
data = new moda_data;
|
||||
@ -107,7 +112,7 @@ extern "C"
|
||||
#ifdef _MSC_VER
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void moda_deinit(UDF_INIT* initid)
|
||||
void moda_deinit(UDF_INIT* initid)
|
||||
{
|
||||
struct moda_data* data = (struct moda_data*)initid->ptr;
|
||||
data->clear();
|
||||
@ -117,8 +122,8 @@ extern "C"
|
||||
#ifdef _MSC_VER
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void moda_clear(UDF_INIT* initid, char* is_null __attribute__((unused)),
|
||||
char* message __attribute__((unused)))
|
||||
void moda_clear(UDF_INIT* initid, char* is_null __attribute__((unused)),
|
||||
char* message __attribute__((unused)))
|
||||
{
|
||||
struct moda_data* data = (struct moda_data*)initid->ptr;
|
||||
data->clear();
|
||||
@ -127,7 +132,7 @@ extern "C"
|
||||
#ifdef _MSC_VER
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void moda_add(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* message __attribute__((unused)))
|
||||
void moda_add(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* message __attribute__((unused)))
|
||||
{
|
||||
// Test for NULL
|
||||
if (args->args[0] == 0)
|
||||
@ -169,7 +174,7 @@ extern "C"
|
||||
#ifdef _MSC_VER
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
void moda_remove(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* message __attribute__((unused)))
|
||||
void moda_remove(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* message __attribute__((unused)))
|
||||
{
|
||||
// Test for NULL
|
||||
if (args->args[0] == 0)
|
||||
@ -210,18 +215,25 @@ extern "C"
|
||||
#ifdef _MSC_VER
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
char* moda(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error __attribute__((unused)))
|
||||
//char* moda(UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error __attribute__((unused)))
|
||||
char* moda(UDF_INIT * initid, UDF_ARGS * args, char* result, ulong* res_length, char* is_null, char* error __attribute__((unused)))
|
||||
{
|
||||
struct moda_data* data = (struct moda_data*)initid->ptr;
|
||||
switch (args->arg_type[0])
|
||||
{
|
||||
case INT_RESULT: return moda<int64_t>(data->mapINT, data);
|
||||
case REAL_RESULT: return moda<double>(data->mapREAL, data);
|
||||
case INT_RESULT:
|
||||
moda<int64_t>(data->mapINT, data);
|
||||
break;
|
||||
case REAL_RESULT:
|
||||
moda<double>(data->mapREAL, data);
|
||||
break;
|
||||
case DECIMAL_RESULT:
|
||||
case STRING_RESULT: return moda<long double>(data->mapDECIMAL, data);
|
||||
case STRING_RESULT:
|
||||
moda<long double>(data->mapDECIMAL, data);
|
||||
break;
|
||||
default: return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
*res_length = data->result.size();
|
||||
return const_cast<char*>(data->result.c_str());
|
||||
}
|
||||
} // Extern "C"
|
||||
|
Reference in New Issue
Block a user