| 1 | #include "duckdb/parser/expression/star_expression.hpp" |
| 2 | |
| 3 | #include "duckdb/common/exception.hpp" |
| 4 | #include "duckdb/common/field_writer.hpp" |
| 5 | |
| 6 | #include "duckdb/common/serializer/format_serializer.hpp" |
| 7 | #include "duckdb/common/serializer/format_deserializer.hpp" |
| 8 | |
| 9 | namespace duckdb { |
| 10 | |
| 11 | StarExpression::StarExpression(string relation_name_p) |
| 12 | : ParsedExpression(ExpressionType::STAR, ExpressionClass::STAR), relation_name(std::move(relation_name_p)) { |
| 13 | } |
| 14 | |
| 15 | string StarExpression::ToString() const { |
| 16 | if (expr) { |
| 17 | D_ASSERT(columns); |
| 18 | return "COLUMNS(" + expr->ToString() + ")" ; |
| 19 | } |
| 20 | string result; |
| 21 | if (columns) { |
| 22 | result += "COLUMNS(" ; |
| 23 | } |
| 24 | result += relation_name.empty() ? "*" : relation_name + ".*" ; |
| 25 | if (!exclude_list.empty()) { |
| 26 | result += " EXCLUDE (" ; |
| 27 | bool first_entry = true; |
| 28 | for (auto &entry : exclude_list) { |
| 29 | if (!first_entry) { |
| 30 | result += ", " ; |
| 31 | } |
| 32 | result += entry; |
| 33 | first_entry = false; |
| 34 | } |
| 35 | result += ")" ; |
| 36 | } |
| 37 | if (!replace_list.empty()) { |
| 38 | result += " REPLACE (" ; |
| 39 | bool first_entry = true; |
| 40 | for (auto &entry : replace_list) { |
| 41 | if (!first_entry) { |
| 42 | result += ", " ; |
| 43 | } |
| 44 | result += entry.second->ToString(); |
| 45 | result += " AS " ; |
| 46 | result += entry.first; |
| 47 | first_entry = false; |
| 48 | } |
| 49 | result += ")" ; |
| 50 | } |
| 51 | if (columns) { |
| 52 | result += ")" ; |
| 53 | } |
| 54 | return result; |
| 55 | } |
| 56 | |
| 57 | bool StarExpression::Equal(const StarExpression &a, const StarExpression &b) { |
| 58 | if (a.relation_name != b.relation_name || a.exclude_list != b.exclude_list) { |
| 59 | return false; |
| 60 | } |
| 61 | if (a.columns != b.columns) { |
| 62 | return false; |
| 63 | } |
| 64 | if (a.replace_list.size() != b.replace_list.size()) { |
| 65 | return false; |
| 66 | } |
| 67 | for (auto &entry : a.replace_list) { |
| 68 | auto other_entry = b.replace_list.find(x: entry.first); |
| 69 | if (other_entry == b.replace_list.end()) { |
| 70 | return false; |
| 71 | } |
| 72 | if (!entry.second->Equals(other: *other_entry->second)) { |
| 73 | return false; |
| 74 | } |
| 75 | } |
| 76 | if (!ParsedExpression::Equals(left: a.expr, right: b.expr)) { |
| 77 | return false; |
| 78 | } |
| 79 | return true; |
| 80 | } |
| 81 | |
| 82 | void StarExpression::Serialize(FieldWriter &writer) const { |
| 83 | auto &serializer = writer.GetSerializer(); |
| 84 | |
| 85 | writer.WriteString(val: relation_name); |
| 86 | |
| 87 | // in order to write the exclude_list/replace_list as single fields we directly use the field writers' internal |
| 88 | // serializer |
| 89 | writer.WriteField<uint32_t>(element: exclude_list.size()); |
| 90 | for (auto &exclusion : exclude_list) { |
| 91 | serializer.WriteString(val: exclusion); |
| 92 | } |
| 93 | writer.WriteField<uint32_t>(element: replace_list.size()); |
| 94 | for (auto &entry : replace_list) { |
| 95 | serializer.WriteString(val: entry.first); |
| 96 | entry.second->Serialize(serializer); |
| 97 | } |
| 98 | writer.WriteField<bool>(element: columns); |
| 99 | writer.WriteOptional(element: expr); |
| 100 | } |
| 101 | |
| 102 | unique_ptr<ParsedExpression> StarExpression::Deserialize(ExpressionType type, FieldReader &reader) { |
| 103 | auto &source = reader.GetSource(); |
| 104 | |
| 105 | auto result = make_uniq<StarExpression>(); |
| 106 | result->relation_name = reader.ReadRequired<string>(); |
| 107 | auto exclusion_count = reader.ReadRequired<uint32_t>(); |
| 108 | for (idx_t i = 0; i < exclusion_count; i++) { |
| 109 | result->exclude_list.insert(x: source.Read<string>()); |
| 110 | } |
| 111 | auto replace_count = reader.ReadRequired<uint32_t>(); |
| 112 | for (idx_t i = 0; i < replace_count; i++) { |
| 113 | auto name = source.Read<string>(); |
| 114 | auto expr = ParsedExpression::Deserialize(source); |
| 115 | result->replace_list.insert(x: make_pair(x&: name, y: std::move(expr))); |
| 116 | } |
| 117 | result->columns = reader.ReadField<bool>(default_value: false); |
| 118 | result->expr = reader.ReadOptional<ParsedExpression>(default_value: nullptr); |
| 119 | return std::move(result); |
| 120 | } |
| 121 | |
| 122 | unique_ptr<ParsedExpression> StarExpression::Copy() const { |
| 123 | auto copy = make_uniq<StarExpression>(args: relation_name); |
| 124 | copy->exclude_list = exclude_list; |
| 125 | for (auto &entry : replace_list) { |
| 126 | copy->replace_list[entry.first] = entry.second->Copy(); |
| 127 | } |
| 128 | copy->columns = columns; |
| 129 | copy->expr = expr ? expr->Copy() : nullptr; |
| 130 | copy->CopyProperties(other: *this); |
| 131 | return std::move(copy); |
| 132 | } |
| 133 | |
| 134 | void StarExpression::FormatSerialize(FormatSerializer &serializer) const { |
| 135 | ParsedExpression::FormatSerialize(serializer); |
| 136 | serializer.WriteProperty(tag: "relation_name" , value: relation_name); |
| 137 | serializer.WriteProperty(tag: "exclude_list" , value: exclude_list); |
| 138 | serializer.WriteProperty(tag: "replace_list" , value: replace_list); |
| 139 | serializer.WriteProperty(tag: "columns" , value: columns); |
| 140 | serializer.WriteOptionalProperty(tag: "expr" , ptr: expr); |
| 141 | } |
| 142 | |
| 143 | unique_ptr<ParsedExpression> StarExpression::FormatDeserialize(ExpressionType type, FormatDeserializer &deserializer) { |
| 144 | auto result = make_uniq<StarExpression>(); |
| 145 | deserializer.ReadProperty(tag: "relation_name" , ret&: result->relation_name); |
| 146 | deserializer.ReadProperty(tag: "exclude_list" , ret&: result->exclude_list); |
| 147 | deserializer.ReadProperty(tag: "replace_list" , ret&: result->replace_list); |
| 148 | deserializer.ReadProperty(tag: "columns" , ret&: result->columns); |
| 149 | deserializer.ReadOptionalProperty(tag: "expr" , ret&: result->expr); |
| 150 | return std::move(result); |
| 151 | } |
| 152 | |
| 153 | } // namespace duckdb |
| 154 | |