iceberg-cpp
Loading...
Searching...
No Matches
table_scan.h
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#pragma once
21
24
25#include <functional>
26#include <memory>
27#include <optional>
28#include <string>
29#include <unordered_map>
30#include <unordered_set>
31#include <vector>
32
34#include "iceberg/result.h"
36#include "iceberg/type_fwd.h"
39
40namespace iceberg {
41
43class ICEBERG_EXPORT ScanTask {
44 public:
45 enum class Kind : uint8_t {
46 kFileScanTask,
47 kChangelogScanTask,
48 };
49
51 virtual Kind kind() const = 0;
52
54 virtual int64_t size_bytes() const = 0;
55
57 virtual int32_t files_count() const = 0;
58
60 virtual int64_t estimated_row_count() const = 0;
61
62 virtual ~ScanTask();
63};
64
66class ICEBERG_EXPORT FileScanTask : public ScanTask {
67 public:
73 explicit FileScanTask(std::shared_ptr<DataFile> data_file,
74 std::vector<std::shared_ptr<DataFile>> delete_files = {},
75 std::shared_ptr<Expression> filter = nullptr);
76
78 const std::shared_ptr<DataFile>& data_file() const { return data_file_; }
79
81 const std::vector<std::shared_ptr<DataFile>>& delete_files() const {
82 return delete_files_;
83 }
84
86 const std::shared_ptr<Expression>& residual_filter() const { return residual_filter_; }
87
88 Kind kind() const override { return Kind::kFileScanTask; }
89 int64_t size_bytes() const override;
90 int32_t files_count() const override;
91 int64_t estimated_row_count() const override;
92
93 private:
94 std::shared_ptr<DataFile> data_file_;
95 std::vector<std::shared_ptr<DataFile>> delete_files_;
96 std::shared_ptr<Expression> residual_filter_;
97};
98
99enum class ChangelogOperation : uint8_t {
100 kInsert,
101 kDelete,
102 kUpdateBefore,
103 kUpdateAfter,
104};
105
107class ICEBERG_EXPORT ChangelogScanTask : public ScanTask {
108 public:
116 ChangelogScanTask(int32_t change_ordinal, int64_t commit_snapshot_id,
117 std::shared_ptr<DataFile> data_file,
118 std::vector<std::shared_ptr<DataFile>> delete_files = {},
119 std::shared_ptr<Expression> residual_filter = nullptr);
120
121 Kind kind() const override { return Kind::kChangelogScanTask; }
122
123 int64_t size_bytes() const override;
124 int32_t files_count() const override;
125 int64_t estimated_row_count() const override;
126
127 virtual ChangelogOperation operation() const = 0;
128
130 int32_t change_ordinal() const { return change_ordinal_; }
131
133 int64_t commit_snapshot_id() const { return commit_snapshot_id_; }
134
136 const std::shared_ptr<Expression>& residual_filter() const { return residual_filter_; }
137
138 protected:
139 int32_t change_ordinal_;
140 int64_t commit_snapshot_id_;
141 std::shared_ptr<DataFile> data_file_;
142 std::vector<std::shared_ptr<DataFile>> delete_files_;
143 std::shared_ptr<Expression> residual_filter_;
144};
145
164class ICEBERG_EXPORT AddedRowsScanTask : public ChangelogScanTask {
165 public:
166 using ChangelogScanTask::ChangelogScanTask;
167
168 ChangelogOperation operation() const override { return ChangelogOperation::kInsert; }
169
171 const std::shared_ptr<DataFile>& data_file() const { return data_file_; }
172
176 const std::vector<std::shared_ptr<DataFile>>& delete_files() const {
177 return delete_files_;
178 }
179};
180
194class ICEBERG_EXPORT DeletedDataFileScanTask : public ChangelogScanTask {
195 public:
196 using ChangelogScanTask::ChangelogScanTask;
197
198 ChangelogOperation operation() const override { return ChangelogOperation::kDelete; }
199
201 const std::shared_ptr<DataFile>& data_file() const { return data_file_; }
202
207 const std::vector<std::shared_ptr<DataFile>>& existing_deletes() const {
208 return delete_files_;
209 }
210};
211
212namespace internal {
213
214// Internal table scan context used by different scan implementations.
216 std::optional<int64_t> snapshot_id;
217 std::shared_ptr<Expression> filter;
218 bool ignore_residuals{false};
219 bool case_sensitive{true};
220 bool return_column_stats{false};
221 std::unordered_set<int32_t> columns_to_keep_stats;
222 std::vector<std::string> selected_columns;
223 std::shared_ptr<Schema> projected_schema;
224 std::unordered_map<std::string, std::string> options;
225 bool from_snapshot_id_inclusive{false};
226 std::optional<int64_t> from_snapshot_id;
227 std::optional<int64_t> to_snapshot_id;
228 std::string branch{};
229 std::optional<int64_t> min_rows_requested;
230 OptionalExecutor plan_executor;
231 std::string table_name;
232 std::shared_ptr<MetricsReporter> metrics_reporter;
233
234 // Validate the context parameters to see if they have conflicts.
235 [[nodiscard]] Status Validate() const;
236};
237
238} // namespace internal
239
240// Concept to check if a type is an incremental scan
241template <typename T>
242concept IsIncrementalScan = std::is_base_of_v<IncrementalScan<FileScanTask>, T> ||
243 std::is_base_of_v<IncrementalScan<ChangelogScanTask>, T>;
244
246template <typename ScanType = DataTableScan>
247class ICEBERG_TEMPLATE_CLASS_EXPORT TableScanBuilder : public ErrorCollector {
248 public:
252
257 TableScanBuilder& Option(std::string key, std::string value);
258
261 TableScanBuilder& Project(std::shared_ptr<Schema> schema);
262
266 TableScanBuilder& CaseSensitive(bool case_sensitive);
267
272
279 TableScanBuilder& IncludeColumnStats(const std::vector<std::string>& requested_columns);
280
287 TableScanBuilder& Select(const std::vector<std::string>& column_names);
288
291 TableScanBuilder& Filter(std::shared_ptr<Expression> filter);
292
295
304
310
314 TableScanBuilder& UseSnapshot(int64_t snapshot_id);
315
320 TableScanBuilder& UseRef(const std::string& ref);
321
327 TableScanBuilder& AsOfTime(int64_t timestamp_millis);
328
339 TableScanBuilder& FromSnapshot(int64_t from_snapshot_id, bool inclusive = false)
340 requires IsIncrementalScan<ScanType>;
341
352 TableScanBuilder& FromSnapshot(const std::string& ref, bool inclusive = false)
353 requires IsIncrementalScan<ScanType>;
354
363 TableScanBuilder& ToSnapshot(int64_t to_snapshot_id)
364 requires IsIncrementalScan<ScanType>;
365
374 TableScanBuilder& ToSnapshot(const std::string& ref)
375 requires IsIncrementalScan<ScanType>;
376
381 TableScanBuilder& UseBranch(const std::string& branch)
382 requires IsIncrementalScan<ScanType>;
383
388 TableScanBuilder& ReportWith(std::shared_ptr<MetricsReporter> reporter);
389
392 Result<std::unique_ptr<ScanType>> Build();
393
394 protected:
395 TableScanBuilder(std::shared_ptr<TableMetadata> metadata, std::shared_ptr<FileIO> io,
396 std::string table_name,
397 std::shared_ptr<MetricsReporter> metrics_reporter);
398
399 // Return the schema bound to the specified snapshot.
400 Result<std::reference_wrapper<const std::shared_ptr<Schema>>> ResolveSnapshotSchema();
401 Status ResolveColumnStatsSelection();
402
403 std::shared_ptr<TableMetadata> metadata_;
404 std::shared_ptr<FileIO> io_;
405 internal::TableScanContext context_;
406 std::shared_ptr<Schema> snapshot_schema_;
407 std::optional<std::vector<std::string>> requested_column_stats_;
408};
409
411class ICEBERG_EXPORT TableScan {
412 public:
413 virtual ~TableScan();
414
416 const std::shared_ptr<TableMetadata>& metadata() const;
417
420
423
426
428 const std::shared_ptr<FileIO>& io() const;
429
431 const std::shared_ptr<Expression>& filter() const;
432
434 bool is_case_sensitive() const;
435
436 protected:
437 TableScan(std::shared_ptr<TableMetadata> metadata, std::shared_ptr<Schema> schema,
438 std::shared_ptr<FileIO> io, internal::TableScanContext context);
439
441 const;
442
443 virtual const std::vector<std::string>& ScanColumns() const;
444
445 const std::shared_ptr<TableMetadata> metadata_;
446 const std::shared_ptr<Schema> schema_;
447 const std::shared_ptr<FileIO> io_;
448 const internal::TableScanContext context_;
449 mutable std::shared_ptr<Schema> projected_schema_;
450};
451
453class ICEBERG_EXPORT DataTableScan : public TableScan {
454 public:
455 ~DataTableScan() override = default;
456
459 std::shared_ptr<TableMetadata> metadata, std::shared_ptr<Schema> schema,
460 std::shared_ptr<FileIO> io, internal::TableScanContext context);
461
465
466 private:
467 Status ReportScan(const Snapshot& snapshot, const ScanMetrics& scan_metrics) const;
468
469 protected:
470 using TableScan::TableScan;
471};
472
475template <typename ScanTaskType>
477 public:
478 ~IncrementalScan() override = default;
479
480 virtual Result<std::vector<std::shared_ptr<ScanTaskType>>> PlanFiles() const = 0;
481
482 protected:
484 std::optional<int64_t> from_snapshot_id_exclusive,
485 int64_t to_snapshot_id_inclusive) const = 0;
486
487 using TableScan::TableScan;
488
489 // Allow the free function ResolvePlanFiles to access protected members.
490 template <typename T>
491 friend Result<std::vector<std::shared_ptr<T>>> ResolvePlanFiles(
492 const IncrementalScan<T>& scan);
493};
494
496class ICEBERG_EXPORT IncrementalAppendScan : public IncrementalScan<FileScanTask> {
497 public:
500 std::shared_ptr<TableMetadata> metadata, std::shared_ptr<Schema> schema,
501 std::shared_ptr<FileIO> io, internal::TableScanContext context);
502
503 ~IncrementalAppendScan() override = default;
504
505 Result<std::vector<std::shared_ptr<FileScanTask>>> PlanFiles() const override;
506
507 protected:
509 std::optional<int64_t> from_snapshot_id_exclusive,
510 int64_t to_snapshot_id_inclusive) const override;
511
512 using IncrementalScan::IncrementalScan;
513};
514
516class ICEBERG_EXPORT IncrementalChangelogScan
517 : public IncrementalScan<ChangelogScanTask> {
518 public:
521 std::shared_ptr<TableMetadata> metadata, std::shared_ptr<Schema> schema,
522 std::shared_ptr<FileIO> io, internal::TableScanContext context);
523
524 ~IncrementalChangelogScan() override = default;
525
527
528 protected:
530 std::optional<int64_t> from_snapshot_id_exclusive,
531 int64_t to_snapshot_id_inclusive) const override;
532
533 using IncrementalScan::IncrementalScan;
534};
535
536extern template class ICEBERG_EXTERN_TEMPLATE_CLASS_EXPORT
538extern template class ICEBERG_EXTERN_TEMPLATE_CLASS_EXPORT
540extern template class ICEBERG_EXTERN_TEMPLATE_CLASS_EXPORT
542
543} // namespace iceberg
A scan task for inserts generated by adding a data file to the table.
Definition table_scan.h:164
const std::shared_ptr< DataFile > & data_file() const
The data file containing the added rows.
Definition table_scan.h:171
const std::vector< std::shared_ptr< DataFile > > & delete_files() const
A list of delete files to apply when reading the data file in this task.
Definition table_scan.h:176
A scan task for reading changelog entries between snapshots.
Definition table_scan.h:107
int64_t size_bytes() const override
The number of bytes that should be read by this scan task.
int32_t change_ordinal() const
The position of this change in the changelog order (0-based).
Definition table_scan.h:130
int64_t commit_snapshot_id() const
The snapshot ID that committed this change.
Definition table_scan.h:133
int64_t estimated_row_count() const override
The number of rows that should be read by this scan task.
ChangelogScanTask(int32_t change_ordinal, int64_t commit_snapshot_id, std::shared_ptr< DataFile > data_file, std::vector< std::shared_ptr< DataFile > > delete_files={}, std::shared_ptr< Expression > residual_filter=nullptr)
Construct an AddedRowsScanTask.
Kind kind() const override
The kind of scan task.
Definition table_scan.h:121
const std::shared_ptr< Expression > & residual_filter() const
Residual filter to apply after reading.
Definition table_scan.h:136
int32_t files_count() const override
The number of files that should be read by this scan task.
A scan that reads data files and applies delete files to filter rows.
Definition table_scan.h:453
static Result< std::unique_ptr< DataTableScan > > Make(std::shared_ptr< TableMetadata > metadata, std::shared_ptr< Schema > schema, std::shared_ptr< FileIO > io, internal::TableScanContext context)
Constructs a DataTableScan instance.
Result< std::vector< std::shared_ptr< FileScanTask > > > PlanFiles() const
Plans the scan tasks by resolving manifests and data files.
A scan task for deletes generated by removing a data file from the table.
Definition table_scan.h:194
const std::vector< std::shared_ptr< DataFile > > & existing_deletes() const
A list of previously added delete files to apply when reading the data file in this task.
Definition table_scan.h:207
const std::shared_ptr< DataFile > & data_file() const
The data file that was deleted.
Definition table_scan.h:201
Base class for collecting errors in the builder pattern.
Definition error_collector.h:93
Schedules iceberg-cpp internal planning tasks.
Definition executor.h:46
Pluggable module for reading, writing, and deleting files.
Definition file_io.h:128
Task representing a data file and its corresponding delete files.
Definition table_scan.h:66
int64_t estimated_row_count() const override
The number of rows that should be read by this scan task.
int32_t files_count() const override
The number of files that should be read by this scan task.
Kind kind() const override
The kind of scan task.
Definition table_scan.h:88
const std::shared_ptr< DataFile > & data_file() const
The data file that should be read by this scan task.
Definition table_scan.h:78
const std::shared_ptr< Expression > & residual_filter() const
Residual filter to apply after reading.
Definition table_scan.h:86
int64_t size_bytes() const override
The number of bytes that should be read by this scan task.
FileScanTask(std::shared_ptr< DataFile > data_file, std::vector< std::shared_ptr< DataFile > > delete_files={}, std::shared_ptr< Expression > filter=nullptr)
Construct with data file, delete files, and residual filter.
const std::vector< std::shared_ptr< DataFile > > & delete_files() const
Delete files that apply to this data file.
Definition table_scan.h:81
A scan that reads data files added between snapshots (incremental appends).
Definition table_scan.h:496
static Result< std::unique_ptr< IncrementalAppendScan > > Make(std::shared_ptr< TableMetadata > metadata, std::shared_ptr< Schema > schema, std::shared_ptr< FileIO > io, internal::TableScanContext context)
Constructs an IncrementalAppendScan instance.
A scan that reads changelog entries between snapshots.
Definition table_scan.h:517
static Result< std::unique_ptr< IncrementalChangelogScan > > Make(std::shared_ptr< TableMetadata > metadata, std::shared_ptr< Schema > schema, std::shared_ptr< FileIO > io, internal::TableScanContext context)
Constructs an IncrementalChangelogScan instance.
A base template class for incremental scans that read changes between snapshots, and return scan task...
Definition table_scan.h:476
Interface for reporting metrics from Iceberg operations.
Definition metrics_reporter.h:85
Live scan metrics collected during a table scan operation.
Definition scan_report.h:94
An abstract scan task.
Definition table_scan.h:43
virtual int32_t files_count() const =0
The number of files that should be read by this scan task.
virtual int64_t estimated_row_count() const =0
The number of rows that should be read by this scan task.
virtual int64_t size_bytes() const =0
The number of bytes that should be read by this scan task.
virtual Kind kind() const =0
The kind of scan task.
A schema for a Table.
Definition schema.h:51
Builder class for creating TableScan instances.
Definition table_scan.h:247
TableScanBuilder & Option(std::string key, std::string value)
Update property that will override the table's behavior based on the incoming pair....
TableScanBuilder & UseRef(const std::string &ref)
Request this scan to use the given reference.
static Result< std::unique_ptr< TableScanBuilder< ScanType > > > Make(const Table &table)
Constructs a TableScanBuilder for the given table.
TableScanBuilder & IgnoreResiduals()
Request data filtering to files but not to rows in those files.
TableScanBuilder & Select(const std::vector< std::string > &column_names)
Request this scan to read the given data columns.
TableScanBuilder & Filter(std::shared_ptr< Expression > filter)
Set the expression to filter data.
TableScanBuilder & CaseSensitive(bool case_sensitive)
If data columns are selected via Select(), controls whether the match to the schema will be done with...
TableScanBuilder & IncludeColumnStats()
Request this scan to load the column stats with each data file.
TableScanBuilder & IncludeColumnStats(const std::vector< std::string > &requested_columns)
Request this scan to load the column stats for the specific columns with each data file.
TableScanBuilder & AsOfTime(int64_t timestamp_millis)
Request this scan to use the most recent snapshot as of the given time in milliseconds on the branch ...
TableScanBuilder & UseSnapshot(int64_t snapshot_id)
Request this scan to use the given snapshot by ID.
TableScanBuilder & Project(std::shared_ptr< Schema > schema)
Set the projected schema.
TableScanBuilder & FromSnapshot(int64_t from_snapshot_id, bool inclusive=false)
Instructs this scan to look for changes starting from a particular snapshot.
TableScanBuilder & PlanWith(Executor &executor)
Configure an executor for manifest planning.
TableScanBuilder & MinRowsRequested(int64_t num_rows)
Request this scan to return at least the given number of rows.
Represents a configured scan operation on a table.
Definition table_scan.h:411
Result< std::shared_ptr< Schema > > schema() const
Returns the projected schema for the scan.
Result< std::shared_ptr< Snapshot > > snapshot() const
Returns the snapshot to scan. If there is no snapshot, returns nullptr.
const std::shared_ptr< TableMetadata > & metadata() const
Returns the table metadata being scanned.
const std::shared_ptr< FileIO > & io() const
Returns the file I/O instance used for reading files.
const internal::TableScanContext & context() const
Returns the scan context.
bool is_case_sensitive() const
Returns whether this scan is case-sensitive.
const std::shared_ptr< Expression > & filter() const
Returns this scan's filter expression.
Represents an Iceberg table.
Definition table.h:41
Definition table_scan.h:242
Define task executor interfaces.
Define symbol visibility macros for core Iceberg APIs.
Core Apache Iceberg C++ APIs.
Definition arrow_io_util.h:33
std::expected< T, E > Result
Result alias.
Definition result.h:88
STL namespace.
Define Result, Status, and error helpers.
A snapshot of the data in a table at a point in time.
Definition snapshot.h:394
Represents the metadata for an Iceberg table.
Definition table_metadata.h:73
Definition table_scan.h:215