Generate a random precision in range [minPrecision, maxPrecision] and a scale in range [0, random precision generated]. @param maximum precision.
| 174 | /// and a scale in range [0, random precision generated]. |
| 175 | /// @param maximum precision. |
| 176 | std::pair<int8_t, int8_t> randPrecisionScale( |
| 177 | FuzzerGenerator& rng, |
| 178 | int8_t minPrecision, |
| 179 | int8_t maxPrecision) { |
| 180 | struct DecimalSpec { |
| 181 | std::optional<int8_t> precision; |
| 182 | std::optional<int8_t> scale; |
| 183 | }; |
| 184 | |
| 185 | using SpecialDecimalSpecs = std::unordered_map<std::string, DecimalSpec>; |
| 186 | SpecialDecimalSpecs specialDecimalSpecs = { |
| 187 | {"MAX_REPRESENTABLE", {maxPrecision, 0}}, |
| 188 | {"MIN_REPRESENTABLE", {maxPrecision, 0}}, |
| 189 | {"VERY_HIGH_PRECISION", {maxPrecision, std::nullopt}}, |
| 190 | {"VERY_LONG_FRACTION", {maxPrecision, maxPrecision}}, |
| 191 | {"LARGEST_PRECISION_LARGEST_SCALE", {maxPrecision, maxPrecision}}, |
| 192 | {"LARGEST_PRECISION_SMALLEST_SCALE", {maxPrecision, 0}}, |
| 193 | {"SMALLEST_PRECISION_LARGEST_SCALE", {minPrecision, minPrecision}}, |
| 194 | {"SMALLEST_PRECISION_SMALLEST_SCALE", {minPrecision, 0}}}; |
| 195 | size_t numSpecialDecimalSpecs = specialDecimalSpecs.size(); |
| 196 | |
| 197 | auto isSpecial = rand<bool>(rng); |
| 198 | if (isSpecial) { |
| 199 | // Randomly select from predefined special precisions and scales. |
| 200 | auto index = rand<size_t>(rng) % numSpecialDecimalSpecs; |
| 201 | auto iteratorSpecialDecimalSpecs = specialDecimalSpecs.begin(); |
| 202 | std::advance(iteratorSpecialDecimalSpecs, index); |
| 203 | const auto& [specialDecimalName, specialDecimalSpec] = |
| 204 | *iteratorSpecialDecimalSpecs; |
| 205 | if (specialDecimalSpec.scale.has_value()) { |
| 206 | return std::make_pair( |
| 207 | *specialDecimalSpec.precision, *specialDecimalSpec.scale); |
| 208 | } |
| 209 | |
| 210 | // If the scale is std::nullopt, generate a scale in range [0, precision]. |
| 211 | auto scale = rand<int8_t>(rng) % (*specialDecimalSpec.precision + 1); |
| 212 | return std::make_pair(*specialDecimalSpec.precision, scale); |
| 213 | } |
| 214 | |
| 215 | // Purely random generation. |
| 216 | // Generate precision in range [min precision, max precision]. |
| 217 | auto precision = |
| 218 | minPrecision + (rand<int8_t>(rng) % (maxPrecision - minPrecision + 1)); |
| 219 | // Generate scale in range [0, precision]. |
| 220 | auto scale = rand<int8_t>(rng) % (precision + 1); |
| 221 | return {precision, scale}; |
| 222 | } |
| 223 | |
| 224 | // Generate a short decimal TypePtr with random / special precision and scale. |
| 225 | inline TypePtr randShortDecimalType(FuzzerGenerator& rng) { |
no test coverage detected