1#include "duckdb/execution/operator/scan/physical_table_scan.hpp"
2
3#include <utility>
4
5#include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp"
6#include "duckdb/transaction/transaction.hpp"
7#include "duckdb/planner/expression/bound_conjunction_expression.hpp"
8
9using namespace duckdb;
10using namespace std;
11
12class PhysicalTableScanOperatorState : public PhysicalOperatorState {
13public:
14 PhysicalTableScanOperatorState(Expression &expr)
15 : PhysicalOperatorState(nullptr), initialized(false), executor(expr) {
16 }
17 PhysicalTableScanOperatorState() : PhysicalOperatorState(nullptr), initialized(false) {
18 }
19 //! Whether or not the scan has been initialized
20 bool initialized;
21 //! The current position in the scan
22 TableScanState scan_offset;
23 //! Execute filters inside the table
24 ExpressionExecutor executor;
25};
26
27PhysicalTableScan::PhysicalTableScan(LogicalOperator &op, TableCatalogEntry &tableref, DataTable &table,
28 vector<column_t> column_ids, vector<unique_ptr<Expression>> filter,
29 unordered_map<idx_t, vector<TableFilter>> table_filters)
30 : PhysicalOperator(PhysicalOperatorType::SEQ_SCAN, op.types), tableref(tableref), table(table),
31 column_ids(move(column_ids)), table_filters(move(table_filters)) {
32 if (filter.size() > 1) {
33 //! create a big AND out of the expressions
34 auto conjunction = make_unique<BoundConjunctionExpression>(ExpressionType::CONJUNCTION_AND);
35 for (auto &expr : filter) {
36 conjunction->children.push_back(move(expr));
37 }
38 expression = move(conjunction);
39 } else if (filter.size() == 1) {
40 expression = move(filter[0]);
41 }
42}
43void PhysicalTableScan::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
44 auto state = reinterpret_cast<PhysicalTableScanOperatorState *>(state_);
45 if (column_ids.empty()) {
46 return;
47 }
48 auto &transaction = Transaction::GetTransaction(context);
49 if (!state->initialized) {
50 table.InitializeScan(transaction, state->scan_offset, column_ids, &table_filters);
51 state->initialized = true;
52 }
53 table.Scan(transaction, chunk, state->scan_offset, table_filters);
54}
55
56string PhysicalTableScan::ExtraRenderInformation() const {
57 if (expression) {
58 return tableref.name + " " + expression->ToString();
59 } else {
60 return tableref.name;
61 }
62}
63
64unique_ptr<PhysicalOperatorState> PhysicalTableScan::GetOperatorState() {
65 if (expression) {
66 return make_unique<PhysicalTableScanOperatorState>(*expression);
67 } else {
68 return make_unique<PhysicalTableScanOperatorState>();
69 }
70}
71