Repository: apache/arrow
File: cpp/src/parquet/arrow/generate_fuzz_corpus.cc (C++)

Code before:
      Encoding::BYTE_STREAM_SPLIT};

  std::vector<ColumnWithEncodings> columns;

  random::RandomArrayGenerator gen(42);
  auto name_gen = Column::NameGenerator();

  for (const double true_probability : {0.0, 0.001, 0.01, 0.5, 0.999}) {
    columns.push_back(
        {{name_gen(), gen.Boolean(length, true_probability, null_probability)},
         kBooleanEncodings});
  }

  columns.push_back(
      {{name_gen(), gen.Int32(length, -100, 100, null_probability)}, kIntEncodings});
  columns.push_back(
      {{name_gen(), gen.Int32(length, kMin<int32_t>, kMax<int32_t>, null_probability)},
       kIntEncodings});
  columns.push_back({{name_gen(), gen.Int64(length, -100'000, 100'000, null_probability)},
                     kIntEncodings});
  columns.push_back(
      {{name_gen(), gen.Int64(length, kMin<int64_t>, kMax<int64_t>, null_probability)},
       kIntEncodings});

  // XXX should we add INT96? It's deprecated, only supports PLAIN and is featured in
  // the parquet-testing files.

  // NOTE: will need to vary NaNs if there are encodings for which that matters (ALP?)
  columns.push_back(
      {{name_gen(), gen.Float32(length, -1.0, 1.0, null_probability)}, kFloatEncodings});
  columns.push_back(
      {{name_gen(), gen.Float32(length, kMin<float>, kMax<float>, null_probability)},
       kFloatEncodings});
  columns.push_back(
      {{name_gen(), gen.Float64(length, -1.0, 1.0, null_probability)}, kFloatEncodings});
  columns.push_back(
      {{name_gen(), gen.Float64(length, kMin<double>, kMax<double>, null_probability)},
       kFloatEncodings});

  columns.push_back(
      {{name_gen(), gen.Float16(length, Float16(-1.0), Float16(1.0), null_probability)},
       kFixedLenByteArrayEncodings});

  columns.push_back({{name_gen(), gen.String(length, /*min_length=*/0,
                                             /*max_length=*/20, null_probability)},
                     kByteArrayEncodings});
  columns.push_back({{name_gen(), gen.String(length, /*min_length=*/12,
                                             /*max_length=*/14, null_probability)},
                     kByteArrayEncodings});
  columns.push_back({{name_gen(), gen.String(length, /*min_length=*/100,
                                             /*max_length=*/200, null_probability)},

Review comment (bug):
I guess it depends on the reason for having the fuzz tests. If the goal is to find bugs that could be security risks then it probably does make sense to include INT96 unless there are plans to completely remove support for it any time soon.

Code after:
  const EncodingVector kBooleanEncodings = {Encoding::PLAIN, Encoding::RLE};
  const EncodingVector kByteArrayEncodings = {Encoding::PLAIN, Encoding::RLE_DICTIONARY,
                                              Encoding::DELTA_LENGTH_BYTE_ARRAY,
                                              Encoding::DELTA_BYTE_ARRAY};
  const EncodingVector kFixedLenByteArrayEncodings = {
      Encoding::PLAIN, Encoding::RLE_DICTIONARY, Encoding::DELTA_BYTE_ARRAY,
      Encoding::BYTE_STREAM_SPLIT};
  const EncodingVector kInt96Encodings = {Encoding::PLAIN};

  std::vector<ColumnWithEncodings> columns;

  random::RandomArrayGenerator gen(42);
  auto name_gen = Column::NameGenerator();

  for (const double true_probability : {0.0, 0.001, 0.01, 0.5, 0.999}) {
    columns.push_back(
        {{name_gen(), gen.Boolean(length, true_probability, null_probability)},
         kBooleanEncodings});
  }

  // Generate integer columns with different ranges to trigger delta encoding modes
  columns.push_back(
      {{name_gen(), gen.Int32(length, -100, 100, null_probability)}, kIntEncodings});
  columns.push_back(
      {{name_gen(), gen.Int32(length, kMin<int32_t>, kMax<int32_t>, null_probability)},
       kIntEncodings});
  columns.push_back({{name_gen(), gen.Int64(length, -100'000, 100'000, null_probability)},
                     kIntEncodings});
  columns.push_back(
      {{name_gen(), gen.Int64(length, kMin<int64_t>, kMax<int64_t>, null_probability)},
       kIntEncodings});

  // This won't necessarily span all 96 bits of precision, but PLAIN encoding allows
  // the fuzzer to do its thing on the values.
  for (auto unit : {TimeUnit::SECOND, TimeUnit::MILLI, TimeUnit::MICRO, TimeUnit::NANO}) {
    ARROW_ASSIGN_OR_RAISE(
        auto array, gen.Int64(length, kMin<int64_t>, kMax<int64_t>, null_probability)
                        ->View(timestamp(unit)));
    columns.push_back({{name_gen(), array}, kInt96Encodings});
  }

  // NOTE: will need to vary NaNs if there are encodings for which that matters (ALP?)
  columns.push_back(
      {{name_gen(), gen.Float32(length, -1.0, 1.0, null_probability)}, kFloatEncodings});
  columns.push_back(
      {{name_gen(), gen.Float32(length, kMin<float>, kMax<float>, null_probability)},
       kFloatEncodings});
  columns.push_back(
      {{name_gen(), gen.Float64(length, -1.0, 1.0, null_probability)}, kFloatEncodings});
  columns.push_back(
      {{name_gen(), gen.Float64(length, kMin<double>, kMax<double>, null_probability)},