1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-08-08 14:22:09 +03:00

MCOL-4771 develop fix crash from rand()

The code inserted to handle multiple rand() calls is unneeded and was not thread safe, causing the crash. The code added to make certain function objects use fDynamicFunctor handles the multiple rand() problem.
This commit is contained in:
David Hall
2021-08-09 10:14:49 -05:00
parent 0e55789deb
commit c287c8d90a
2 changed files with 2 additions and 63 deletions

View File

@@ -53,14 +53,6 @@ double Func_rand::getRand()
fSeed1 += 23;
fSeed2 = (fSeed1 + fSeed2 + 33) % maxValue;
if (fSeeds.size() > fSeedIndex)
{
fSeeds[fSeedIndex] = std::make_pair(fSeed1, fSeed2);
}
else
{
fSeeds.push_back(std::make_pair(fSeed1, fSeed2));
}
return (((double) fSeed1) / (double)maxValue);
}
@@ -79,37 +71,6 @@ double Func_rand::getDoubleVal(rowgroup::Row& row,
// NOTE: this function needs to use 32bit ints otherwise it will break for negative values
uint32_t seedParm = 0;
// Still on first row, multiple rands exist in statement. Need an additional seed.
if(fFirstRow == row.getData())
{
fSeedSet = false;
fSeedIndex += 1;
}
else if (fFirstRow == nullptr)
{
// Store first row
fFirstRow = row.getData();
fSeedIndex = 0;
}
else
{
// No longer on first row. Disable additional seeding
if (!fMultipleSeedsSet)
{
fMultipleSeedsSet = true;
fSeedIndex = 0;
}
else
{
fSeedIndex += 1;
if (fSeedIndex == fSeeds.size())
{
fSeedIndex = 0;
}
}
}
// rand with parameter. if the parm is constanct, then a column is attached for fetching
if (parm.size() == 1 || parm.size() == 2)
{
@@ -122,28 +83,17 @@ double Func_rand::getDoubleVal(rowgroup::Row& row,
fSeed1 = (uint32_t)(seedParm * 0x10001L + 55555555L);
fSeed2 = (uint32_t)(seedParm * 0x10000001L);
fSeedSet = true;
fSeeds.push_back(std::make_pair(fSeed1, fSeed2));
}
else
{
const std::pair<uint64_t, uint64_t> &seedPair = fSeeds[fSeedIndex];
fSeed1 = seedPair.first;
fSeed2 = seedPair.second;
}
}
// rand without parameter. thd->rand are passed in. The 3rd is a simple column for fetching
else
{
idbassert(parm.size() == 3);
if (fSeed1 == 0)
if (fSeedSet)
{
fSeed1 = parm[0]->data()->getIntVal(row, isNull);
fSeed2 = parm[1]->data()->getIntVal(row, isNull);
fSeedSet = true;
// Special case: statement such as select rand(), rand(1) so need to keep rand(1) seeded correctly
fSeeds.push_back(std::make_pair(fSeed1, fSeed2));
}
}

View File

@@ -38,17 +38,10 @@ namespace funcexp
class Func_rand : public Func
{
public:
Func_rand() : Func("rand"), fSeed1(0), fSeed2(0), fSeedSet(false), fMultipleSeedsSet(false), fFirstRow(NULL), fSeeds(){}
Func_rand() : Func("rand"), fSeed1(0), fSeed2(0), fSeedSet(false) {}
virtual ~Func_rand() {}
double getRand();
void seedSet(bool seedSet)
{
fSeedSet = seedSet;
fMultipleSeedsSet = seedSet;
fFirstRow = NULL;
fSeeds.clear();
}
execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType);
int64_t getIntVal(rowgroup::Row& row,
@@ -84,10 +77,6 @@ private:
uint64_t fSeed1;
uint64_t fSeed2;
bool fSeedSet;
bool fMultipleSeedsSet;
uint8_t* fFirstRow;
uint16_t fSeedIndex;
std::vector<std::pair<uint64_t, uint64_t> > fSeeds;
};