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
11namespace duckdb {
12
13ColumnRefExpression::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
18ColumnRefExpression::ColumnRefExpression(string column_name)
19 : ColumnRefExpression(vector<string> {std::move(column_name)}) {
20}
21
22ColumnRefExpression::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
32bool ColumnRefExpression::IsQualified() const {
33 return column_names.size() > 1;
34}
35
36const string &ColumnRefExpression::GetColumnName() const {
37 D_ASSERT(column_names.size() <= 4);
38 return column_names.back();
39}
40
41const 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
52string ColumnRefExpression::GetName() const {
53 return !alias.empty() ? alias : column_names.back();
54}
55
56string 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
67bool 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
79hash_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
87unique_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
93void ColumnRefExpression::Serialize(FieldWriter &writer) const {
94 writer.WriteList<string>(elements: column_names);
95}
96
97unique_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
103void ColumnRefExpression::FormatSerialize(FormatSerializer &serializer) const {
104 ParsedExpression::FormatSerialize(serializer);
105 serializer.WriteProperty(tag: "column_names", value: column_names);
106}
107
108unique_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