1 | #include "duckdb/parser/expression/columnref_expression.hpp" |
2 | |
3 | #include "duckdb/common/field_writer.hpp" |
4 | #include "duckdb/common/types/hash.hpp" |
5 | #include "duckdb/common/string_util.hpp" |
6 | #include "duckdb/parser/qualified_name.hpp" |
7 | |
8 | #include "duckdb/common/serializer/format_serializer.hpp" |
9 | #include "duckdb/common/serializer/format_deserializer.hpp" |
10 | |
11 | namespace duckdb { |
12 | |
13 | ColumnRefExpression::ColumnRefExpression(string column_name, string table_name) |
14 | : ColumnRefExpression(table_name.empty() ? vector<string> {std::move(column_name)} |
15 | : vector<string> {std::move(table_name), std::move(column_name)}) { |
16 | } |
17 | |
18 | ColumnRefExpression::ColumnRefExpression(string column_name) |
19 | : ColumnRefExpression(vector<string> {std::move(column_name)}) { |
20 | } |
21 | |
22 | ColumnRefExpression::ColumnRefExpression(vector<string> column_names_p) |
23 | : ParsedExpression(ExpressionType::COLUMN_REF, ExpressionClass::COLUMN_REF), |
24 | column_names(std::move(column_names_p)) { |
25 | #ifdef DEBUG |
26 | for (auto &col_name : column_names) { |
27 | D_ASSERT(!col_name.empty()); |
28 | } |
29 | #endif |
30 | } |
31 | |
32 | bool ColumnRefExpression::IsQualified() const { |
33 | return column_names.size() > 1; |
34 | } |
35 | |
36 | const string &ColumnRefExpression::GetColumnName() const { |
37 | D_ASSERT(column_names.size() <= 4); |
38 | return column_names.back(); |
39 | } |
40 | |
41 | const string &ColumnRefExpression::GetTableName() const { |
42 | D_ASSERT(column_names.size() >= 2 && column_names.size() <= 4); |
43 | if (column_names.size() == 4) { |
44 | return column_names[2]; |
45 | } |
46 | if (column_names.size() == 3) { |
47 | return column_names[1]; |
48 | } |
49 | return column_names[0]; |
50 | } |
51 | |
52 | string ColumnRefExpression::GetName() const { |
53 | return !alias.empty() ? alias : column_names.back(); |
54 | } |
55 | |
56 | string ColumnRefExpression::ToString() const { |
57 | string result; |
58 | for (idx_t i = 0; i < column_names.size(); i++) { |
59 | if (i > 0) { |
60 | result += "." ; |
61 | } |
62 | result += KeywordHelper::WriteOptionallyQuoted(text: column_names[i]); |
63 | } |
64 | return result; |
65 | } |
66 | |
67 | bool ColumnRefExpression::Equal(const ColumnRefExpression &a, const ColumnRefExpression &b) { |
68 | if (a.column_names.size() != b.column_names.size()) { |
69 | return false; |
70 | } |
71 | for (idx_t i = 0; i < a.column_names.size(); i++) { |
72 | if (!StringUtil::CIEquals(l1: a.column_names[i], l2: b.column_names[i])) { |
73 | return false; |
74 | } |
75 | } |
76 | return true; |
77 | } |
78 | |
79 | hash_t ColumnRefExpression::Hash() const { |
80 | hash_t result = ParsedExpression::Hash(); |
81 | for (auto &column_name : column_names) { |
82 | result = CombineHash(left: result, right: StringUtil::CIHash(str: column_name)); |
83 | } |
84 | return result; |
85 | } |
86 | |
87 | unique_ptr<ParsedExpression> ColumnRefExpression::Copy() const { |
88 | auto copy = make_uniq<ColumnRefExpression>(args: column_names); |
89 | copy->CopyProperties(other: *this); |
90 | return std::move(copy); |
91 | } |
92 | |
93 | void ColumnRefExpression::Serialize(FieldWriter &writer) const { |
94 | writer.WriteList<string>(elements: column_names); |
95 | } |
96 | |
97 | unique_ptr<ParsedExpression> ColumnRefExpression::Deserialize(ExpressionType type, FieldReader &reader) { |
98 | auto column_names = reader.ReadRequiredList<string>(); |
99 | auto expression = make_uniq<ColumnRefExpression>(args: std::move(column_names)); |
100 | return std::move(expression); |
101 | } |
102 | |
103 | void ColumnRefExpression::FormatSerialize(FormatSerializer &serializer) const { |
104 | ParsedExpression::FormatSerialize(serializer); |
105 | serializer.WriteProperty(tag: "column_names" , value: column_names); |
106 | } |
107 | |
108 | unique_ptr<ParsedExpression> ColumnRefExpression::FormatDeserialize(ExpressionType type, |
109 | FormatDeserializer &deserializer) { |
110 | auto column_names = deserializer.ReadProperty<vector<string>>(tag: "column_names" ); |
111 | auto expression = make_uniq<ColumnRefExpression>(args: std::move(column_names)); |
112 | return std::move(expression); |
113 | } |
114 | |
115 | } // namespace duckdb |
116 | |