From 0057d5fad5a1f6296576f6d420b7c0f63b86adae Mon Sep 17 00:00:00 2001 From: jmrojas2332 Date: Thu, 13 Feb 2020 23:28:28 +0000 Subject: [PATCH] MCOL-3760 + Fix multiple rands in statement with or without ORDER BY --- utils/funcexp/func_rand.cpp | 42 ++++++++++++++++++++++++++++++++++ utils/funcexp/functor_export.h | 10 +++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/utils/funcexp/func_rand.cpp b/utils/funcexp/func_rand.cpp index e1bf30539..c02137568 100644 --- a/utils/funcexp/func_rand.cpp +++ b/utils/funcexp/func_rand.cpp @@ -53,6 +53,7 @@ double Func_rand::getRand() fSeed1 += 23; fSeed2 = (fSeed1 + fSeed2 + 33) % maxValue; + fSeeds[fSeedIndex] = std::make_pair(fSeed1, fSeed2); return (((double) fSeed1) / (double)maxValue); } @@ -70,6 +71,37 @@ 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 == 0) + { + // 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) { @@ -82,6 +114,13 @@ 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 &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 @@ -94,6 +133,9 @@ double Func_rand::getDoubleVal(rowgroup::Row& row, 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)); } } diff --git a/utils/funcexp/functor_export.h b/utils/funcexp/functor_export.h index 3d7405cc2..ad885296e 100644 --- a/utils/funcexp/functor_export.h +++ b/utils/funcexp/functor_export.h @@ -26,6 +26,8 @@ #include "functor.h" +#include +#include namespace funcexp { @@ -36,13 +38,15 @@ namespace funcexp class Func_rand : public Func { public: - Func_rand() : Func("rand"), fSeed1(0), fSeed2(0), fSeedSet(false) {} + Func_rand() : Func("rand"), fSeed1(0), fSeed2(0), fSeedSet(false), fMultipleSeedsSet(false), fFirstRow(nullptr){} virtual ~Func_rand() {} double getRand(); void seedSet(bool seedSet) { fSeedSet = seedSet; + fMultipleSeedsSet = seedSet; + fFirstRow = nullptr; } execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType); @@ -79,6 +83,10 @@ private: uint64_t fSeed1; uint64_t fSeed2; bool fSeedSet; + bool fMultipleSeedsSet; + uint8_t* fFirstRow; + uint16_t fSeedIndex; + std::vector > fSeeds; };