1#include "duckdb/main/relation/setop_relation.hpp"
2#include "duckdb/main/client_context.hpp"
3#include "duckdb/parser/query_node/set_operation_node.hpp"
4#include "duckdb/parser/result_modifier.hpp"
5
6namespace duckdb {
7
8SetOpRelation::SetOpRelation(shared_ptr<Relation> left_p, shared_ptr<Relation> right_p, SetOperationType setop_type_p)
9 : Relation(left_p->context, RelationType::SET_OPERATION_RELATION), left(std::move(left_p)),
10 right(std::move(right_p)), setop_type(setop_type_p) {
11 if (left->context.GetContext() != right->context.GetContext()) {
12 throw Exception("Cannot combine LEFT and RIGHT relations of different connections!");
13 }
14 context.GetContext()->TryBindRelation(relation&: *this, result_columns&: this->columns);
15}
16
17unique_ptr<QueryNode> SetOpRelation::GetQueryNode() {
18 auto result = make_uniq<SetOperationNode>();
19 if (setop_type == SetOperationType::EXCEPT || setop_type == SetOperationType::INTERSECT) {
20 result->modifiers.push_back(x: make_uniq<DistinctModifier>());
21 }
22 result->left = left->GetQueryNode();
23 result->right = right->GetQueryNode();
24 result->setop_type = setop_type;
25 return std::move(result);
26}
27
28string SetOpRelation::GetAlias() {
29 return left->GetAlias();
30}
31
32const vector<ColumnDefinition> &SetOpRelation::Columns() {
33 return this->columns;
34}
35
36string SetOpRelation::ToString(idx_t depth) {
37 string str = RenderWhitespace(depth);
38 switch (setop_type) {
39 case SetOperationType::UNION:
40 str += "Union";
41 break;
42 case SetOperationType::EXCEPT:
43 str += "Except";
44 break;
45 case SetOperationType::INTERSECT:
46 str += "Intersect";
47 break;
48 default:
49 throw InternalException("Unknown setop type");
50 }
51 return str + "\n" + left->ToString(depth: depth + 1) + right->ToString(depth: depth + 1);
52}
53
54} // namespace duckdb
55