Coverage Report

Created: 2022-08-24 06:40

/src/duckdb/src/parser/transform/helpers/transform_sample.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "duckdb/parser/transformer.hpp"
2
#include "duckdb/parser/parsed_data/sample_options.hpp"
3
#include "duckdb/parser/expression/constant_expression.hpp"
4
#include "duckdb/common/string_util.hpp"
5
6
namespace duckdb {
7
8
0
static SampleMethod GetSampleMethod(const string &method) {
9
0
  auto lmethod = StringUtil::Lower(method);
10
0
  if (lmethod == "system") {
11
0
    return SampleMethod::SYSTEM_SAMPLE;
12
0
  } else if (lmethod == "bernoulli") {
13
0
    return SampleMethod::BERNOULLI_SAMPLE;
14
0
  } else if (lmethod == "reservoir") {
15
0
    return SampleMethod::RESERVOIR_SAMPLE;
16
0
  } else {
17
0
    throw ParserException("Unrecognized sampling method %s, expected system, bernoulli or reservoir", method);
18
0
  }
19
0
}
20
21
140
unique_ptr<SampleOptions> Transformer::TransformSampleOptions(duckdb_libpgquery::PGNode *options) {
22
140
  if (!options) {
23
140
    return nullptr;
24
140
  }
25
0
  auto result = make_unique<SampleOptions>();
26
0
  auto &sample_options = (duckdb_libpgquery::PGSampleOptions &)*options;
27
0
  auto &sample_size = (duckdb_libpgquery::PGSampleSize &)*sample_options.sample_size;
28
0
  auto sample_value = TransformValue(sample_size.sample_size)->value;
29
0
  result->is_percentage = sample_size.is_percentage;
30
0
  if (sample_size.is_percentage) {
31
    // sample size is given in sample_size: use system sampling
32
0
    auto percentage = sample_value.GetValue<double>();
33
0
    if (percentage < 0 || percentage > 100) {
34
0
      throw ParserException("Sample sample_size %llf out of range, must be between 0 and 100", percentage);
35
0
    }
36
0
    result->sample_size = Value::DOUBLE(percentage);
37
0
    result->method = SampleMethod::SYSTEM_SAMPLE;
38
0
  } else {
39
    // sample size is given in rows: use reservoir sampling
40
0
    auto rows = sample_value.GetValue<int64_t>();
41
0
    if (rows < 0) {
42
0
      throw ParserException("Sample rows %lld out of range, must be bigger than or equal to 0", rows);
43
0
    }
44
0
    result->sample_size = Value::BIGINT(rows);
45
0
    result->method = SampleMethod::RESERVOIR_SAMPLE;
46
0
  }
47
0
  if (sample_options.method) {
48
0
    result->method = GetSampleMethod(sample_options.method);
49
0
  }
50
0
  if (sample_options.has_seed) {
51
0
    result->seed = sample_options.seed;
52
0
  }
53
0
  return result;
54
0
}
55
56
} // namespace duckdb