1#include "duckdb/parser/statement/delete_statement.hpp"
2#include "duckdb/planner/binder.hpp"
3#include "duckdb/planner/expression_binder/where_binder.hpp"
4#include "duckdb/planner/operator/logical_delete.hpp"
5#include "duckdb/planner/operator/logical_filter.hpp"
6#include "duckdb/planner/operator/logical_get.hpp"
7#include "duckdb/planner/bound_tableref.hpp"
8
9using namespace duckdb;
10using namespace std;
11
12BoundStatement Binder::Bind(DeleteStatement &stmt) {
13 BoundStatement result;
14
15 // visit the table reference
16 auto bound_table = Bind(*stmt.table);
17 if (bound_table->type != TableReferenceType::BASE_TABLE) {
18 throw BinderException("Can only delete from base table!");
19 }
20 auto root = CreatePlan(*bound_table);
21 auto &get = (LogicalGet &)*root;
22 assert(root->type == LogicalOperatorType::GET && get.table);
23
24 if (!get.table->temporary) {
25 // delete from persistent table: not read only!
26 this->read_only = false;
27 }
28 // project any additional columns required for the condition
29 unique_ptr<Expression> condition;
30 if (stmt.condition) {
31 WhereBinder binder(*this, context);
32 condition = binder.Bind(stmt.condition);
33
34 PlanSubqueries(&condition, &root);
35 auto filter = make_unique<LogicalFilter>(move(condition));
36 filter->AddChild(move(root));
37 root = move(filter);
38 }
39 // create the delete node
40 auto del = make_unique<LogicalDelete>(get.table);
41 del->AddChild(move(root));
42
43 // set up the delete expression
44 del->expressions.push_back(
45 make_unique<BoundColumnRefExpression>(TypeId::INT64, ColumnBinding(get.table_index, get.column_ids.size())));
46 get.column_ids.push_back(COLUMN_IDENTIFIER_ROW_ID);
47
48 result.plan = move(del);
49 result.names = {"Count"};
50 result.types = {SQLType::BIGINT};
51 return result;
52}
53