/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 |