1#include "duckdb/common/field_writer.hpp"
2#include "duckdb/planner/operator/logical_sample.hpp"
3
4namespace duckdb {
5
6LogicalSample::LogicalSample(unique_ptr<SampleOptions> sample_options_p, unique_ptr<LogicalOperator> child)
7 : LogicalOperator(LogicalOperatorType::LOGICAL_SAMPLE), sample_options(std::move(sample_options_p)) {
8 children.push_back(x: std::move(child));
9}
10
11vector<ColumnBinding> LogicalSample::GetColumnBindings() {
12 return children[0]->GetColumnBindings();
13}
14
15idx_t LogicalSample::EstimateCardinality(ClientContext &context) {
16 auto child_cardinality = children[0]->EstimateCardinality(context);
17 if (sample_options->is_percentage) {
18 double sample_cardinality =
19 double(child_cardinality) * (sample_options->sample_size.GetValue<double>() / 100.0);
20 if (sample_cardinality > double(child_cardinality)) {
21 return child_cardinality;
22 }
23 return idx_t(sample_cardinality);
24 } else {
25 auto sample_size = sample_options->sample_size.GetValue<uint64_t>();
26 if (sample_size < child_cardinality) {
27 return sample_size;
28 }
29 }
30 return child_cardinality;
31}
32
33void LogicalSample::ResolveTypes() {
34 types = children[0]->types;
35}
36
37void LogicalSample::Serialize(FieldWriter &writer) const {
38 sample_options->Serialize(serializer&: writer.GetSerializer());
39}
40
41unique_ptr<LogicalOperator> LogicalSample::Deserialize(LogicalDeserializationState &state, FieldReader &reader) {
42 auto sample_options = SampleOptions::Deserialize(source&: reader.GetSource());
43 // TODO(stephwang): review how to pass child LogicalOperator
44 auto result = make_uniq<LogicalSample>(args: std::move(sample_options), args: nullptr);
45 return std::move(result);
46}
47} // namespace duckdb
48