1#include "duckdb/planner/expression/bound_case_expression.hpp"
2#include "duckdb/parser/expression/case_expression.hpp"
3#include "duckdb/common/field_writer.hpp"
4
5namespace duckdb {
6
7BoundCaseExpression::BoundCaseExpression(LogicalType type)
8 : Expression(ExpressionType::CASE_EXPR, ExpressionClass::BOUND_CASE, std::move(type)) {
9}
10
11BoundCaseExpression::BoundCaseExpression(unique_ptr<Expression> when_expr, unique_ptr<Expression> then_expr,
12 unique_ptr<Expression> else_expr_p)
13 : Expression(ExpressionType::CASE_EXPR, ExpressionClass::BOUND_CASE, then_expr->return_type),
14 else_expr(std::move(else_expr_p)) {
15 BoundCaseCheck check;
16 check.when_expr = std::move(when_expr);
17 check.then_expr = std::move(then_expr);
18 case_checks.push_back(x: std::move(check));
19}
20
21string BoundCaseExpression::ToString() const {
22 return CaseExpression::ToString<BoundCaseExpression, Expression>(entry: *this);
23}
24
25bool BoundCaseExpression::Equals(const BaseExpression &other_p) const {
26 if (!Expression::Equals(other: other_p)) {
27 return false;
28 }
29 auto &other = other_p.Cast<BoundCaseExpression>();
30 if (case_checks.size() != other.case_checks.size()) {
31 return false;
32 }
33 for (idx_t i = 0; i < case_checks.size(); i++) {
34 if (!Expression::Equals(left: *case_checks[i].when_expr, right: *other.case_checks[i].when_expr)) {
35 return false;
36 }
37 if (!Expression::Equals(left: *case_checks[i].then_expr, right: *other.case_checks[i].then_expr)) {
38 return false;
39 }
40 }
41 if (!Expression::Equals(left: *else_expr, right: *other.else_expr)) {
42 return false;
43 }
44 return true;
45}
46
47unique_ptr<Expression> BoundCaseExpression::Copy() {
48 auto new_case = make_uniq<BoundCaseExpression>(args&: return_type);
49 for (auto &check : case_checks) {
50 BoundCaseCheck new_check;
51 new_check.when_expr = check.when_expr->Copy();
52 new_check.then_expr = check.then_expr->Copy();
53 new_case->case_checks.push_back(x: std::move(new_check));
54 }
55 new_case->else_expr = else_expr->Copy();
56
57 new_case->CopyProperties(other&: *this);
58 return std::move(new_case);
59}
60
61void BoundCaseCheck::Serialize(Serializer &serializer) const {
62 FieldWriter writer(serializer);
63 writer.WriteSerializable(element: *when_expr);
64 writer.WriteSerializable(element: *then_expr);
65 writer.Finalize();
66}
67
68BoundCaseCheck BoundCaseCheck::Deserialize(Deserializer &source, PlanDeserializationState &state) {
69 FieldReader reader(source);
70 auto when_expr = reader.ReadRequiredSerializable<Expression>(args&: state);
71 auto then_expr = reader.ReadRequiredSerializable<Expression>(args&: state);
72 reader.Finalize();
73 BoundCaseCheck result;
74 result.when_expr = std::move(when_expr);
75 result.then_expr = std::move(then_expr);
76 return result;
77}
78
79void BoundCaseExpression::Serialize(FieldWriter &writer) const {
80 writer.WriteSerializable(element: return_type);
81 writer.WriteRegularSerializableList(elements: case_checks);
82 writer.WriteSerializable(element: *else_expr);
83}
84
85unique_ptr<Expression> BoundCaseExpression::Deserialize(ExpressionDeserializationState &state, FieldReader &reader) {
86 auto return_type = reader.ReadRequiredSerializable<LogicalType, LogicalType>();
87 auto case_checks = reader.ReadRequiredSerializableList<BoundCaseCheck, BoundCaseCheck>(args&: state.gstate);
88 auto else_expr = reader.ReadRequiredSerializable<Expression>(args&: state.gstate);
89
90 auto result = make_uniq<BoundCaseExpression>(args&: return_type);
91 result->else_expr = std::move(else_expr);
92 result->case_checks = std::move(case_checks);
93 return std::move(result);
94}
95
96} // namespace duckdb
97