1 | #include "duckdb/parser/column_definition.hpp" |
2 | #include "duckdb/common/field_writer.hpp" |
3 | #include "duckdb/parser/parsed_expression_iterator.hpp" |
4 | #include "duckdb/parser/expression/columnref_expression.hpp" |
5 | #include "duckdb/parser/parsed_data/alter_table_info.hpp" |
6 | #include "duckdb/parser/expression/cast_expression.hpp" |
7 | |
8 | namespace duckdb { |
9 | |
10 | ColumnDefinition::ColumnDefinition(string name_p, LogicalType type_p) |
11 | : name(std::move(name_p)), type(std::move(type_p)) { |
12 | } |
13 | |
14 | ColumnDefinition::ColumnDefinition(string name_p, LogicalType type_p, unique_ptr<ParsedExpression> expression, |
15 | TableColumnType category) |
16 | : name(std::move(name_p)), type(std::move(type_p)), category(category) { |
17 | switch (category) { |
18 | case TableColumnType::STANDARD: { |
19 | default_value = std::move(expression); |
20 | break; |
21 | } |
22 | case TableColumnType::GENERATED: { |
23 | generated_expression = std::move(expression); |
24 | break; |
25 | } |
26 | default: { |
27 | throw InternalException("Type not implemented for TableColumnType" ); |
28 | } |
29 | } |
30 | } |
31 | |
32 | ColumnDefinition ColumnDefinition::Copy() const { |
33 | ColumnDefinition copy(name, type); |
34 | copy.oid = oid; |
35 | copy.storage_oid = storage_oid; |
36 | copy.SetDefaultValue(default_value ? default_value->Copy() : nullptr); |
37 | copy.generated_expression = generated_expression ? generated_expression->Copy() : nullptr; |
38 | copy.compression_type = compression_type; |
39 | copy.category = category; |
40 | return copy; |
41 | } |
42 | |
43 | void ColumnDefinition::Serialize(Serializer &serializer) const { |
44 | FieldWriter writer(serializer); |
45 | writer.WriteString(val: name); |
46 | writer.WriteSerializable(element: type); |
47 | if (Generated()) { |
48 | writer.WriteOptional(element: generated_expression); |
49 | } else { |
50 | writer.WriteOptional(element: default_value); |
51 | } |
52 | writer.WriteField<TableColumnType>(element: category); |
53 | writer.WriteField<duckdb::CompressionType>(element: compression_type); |
54 | writer.Finalize(); |
55 | } |
56 | |
57 | ColumnDefinition ColumnDefinition::Deserialize(Deserializer &source) { |
58 | FieldReader reader(source); |
59 | auto column_name = reader.ReadRequired<string>(); |
60 | auto column_type = reader.ReadRequiredSerializable<LogicalType, LogicalType>(); |
61 | auto expression = reader.ReadOptional<ParsedExpression>(default_value: nullptr); |
62 | auto category = reader.ReadField<TableColumnType>(default_value: TableColumnType::STANDARD); |
63 | auto compression_type = reader.ReadField<duckdb::CompressionType>(default_value: duckdb::CompressionType::COMPRESSION_AUTO); |
64 | reader.Finalize(); |
65 | |
66 | ColumnDefinition result(column_name, column_type, std::move(expression), category); |
67 | result.compression_type = compression_type; |
68 | return result; |
69 | } |
70 | |
71 | const unique_ptr<ParsedExpression> &ColumnDefinition::DefaultValue() const { |
72 | return default_value; |
73 | } |
74 | |
75 | void ColumnDefinition::SetDefaultValue(unique_ptr<ParsedExpression> default_value) { |
76 | this->default_value = std::move(default_value); |
77 | } |
78 | |
79 | const LogicalType &ColumnDefinition::Type() const { |
80 | return type; |
81 | } |
82 | |
83 | LogicalType &ColumnDefinition::TypeMutable() { |
84 | return type; |
85 | } |
86 | |
87 | void ColumnDefinition::SetType(const LogicalType &type) { |
88 | this->type = type; |
89 | } |
90 | |
91 | const string &ColumnDefinition::Name() const { |
92 | return name; |
93 | } |
94 | |
95 | void ColumnDefinition::SetName(const string &name) { |
96 | this->name = name; |
97 | } |
98 | |
99 | const duckdb::CompressionType &ColumnDefinition::CompressionType() const { |
100 | return compression_type; |
101 | } |
102 | |
103 | void ColumnDefinition::SetCompressionType(duckdb::CompressionType compression_type) { |
104 | this->compression_type = compression_type; |
105 | } |
106 | |
107 | const storage_t &ColumnDefinition::StorageOid() const { |
108 | return storage_oid; |
109 | } |
110 | |
111 | LogicalIndex ColumnDefinition::Logical() const { |
112 | return LogicalIndex(oid); |
113 | } |
114 | |
115 | PhysicalIndex ColumnDefinition::Physical() const { |
116 | return PhysicalIndex(storage_oid); |
117 | } |
118 | |
119 | void ColumnDefinition::SetStorageOid(storage_t storage_oid) { |
120 | this->storage_oid = storage_oid; |
121 | } |
122 | |
123 | const column_t &ColumnDefinition::Oid() const { |
124 | return oid; |
125 | } |
126 | |
127 | void ColumnDefinition::SetOid(column_t oid) { |
128 | this->oid = oid; |
129 | } |
130 | |
131 | const TableColumnType &ColumnDefinition::Category() const { |
132 | return category; |
133 | } |
134 | |
135 | bool ColumnDefinition::Generated() const { |
136 | return category == TableColumnType::GENERATED; |
137 | } |
138 | |
139 | //===--------------------------------------------------------------------===// |
140 | // Generated Columns (VIRTUAL) |
141 | //===--------------------------------------------------------------------===// |
142 | |
143 | static void VerifyColumnRefs(ParsedExpression &expr) { |
144 | if (expr.type == ExpressionType::COLUMN_REF) { |
145 | auto &column_ref = expr.Cast<ColumnRefExpression>(); |
146 | if (column_ref.IsQualified()) { |
147 | throw ParserException( |
148 | "Qualified (tbl.name) column references are not allowed inside of generated column expressions" ); |
149 | } |
150 | } |
151 | ParsedExpressionIterator::EnumerateChildren( |
152 | expr, callback: [&](const ParsedExpression &child) { VerifyColumnRefs(expr&: (ParsedExpression &)child); }); |
153 | } |
154 | |
155 | static void InnerGetListOfDependencies(ParsedExpression &expr, vector<string> &dependencies) { |
156 | if (expr.type == ExpressionType::COLUMN_REF) { |
157 | auto columnref = expr.Cast<ColumnRefExpression>(); |
158 | auto &name = columnref.GetColumnName(); |
159 | dependencies.push_back(x: name); |
160 | } |
161 | ParsedExpressionIterator::EnumerateChildren(expr, callback: [&](const ParsedExpression &child) { |
162 | if (expr.type == ExpressionType::LAMBDA) { |
163 | throw NotImplementedException("Lambda functions are currently not supported in generated columns." ); |
164 | } |
165 | InnerGetListOfDependencies(expr&: (ParsedExpression &)child, dependencies); |
166 | }); |
167 | } |
168 | |
169 | void ColumnDefinition::GetListOfDependencies(vector<string> &dependencies) const { |
170 | D_ASSERT(Generated()); |
171 | InnerGetListOfDependencies(expr&: *generated_expression, dependencies); |
172 | } |
173 | |
174 | string ColumnDefinition::GetName() const { |
175 | return name; |
176 | } |
177 | |
178 | LogicalType ColumnDefinition::GetType() const { |
179 | return type; |
180 | } |
181 | |
182 | void ColumnDefinition::SetGeneratedExpression(unique_ptr<ParsedExpression> expression) { |
183 | category = TableColumnType::GENERATED; |
184 | |
185 | if (expression->HasSubquery()) { |
186 | throw ParserException("Expression of generated column \"%s\" contains a subquery, which isn't allowed" , name); |
187 | } |
188 | |
189 | VerifyColumnRefs(expr&: *expression); |
190 | if (type.id() == LogicalTypeId::ANY) { |
191 | generated_expression = std::move(expression); |
192 | return; |
193 | } |
194 | // Always wrap the expression in a cast, that way we can always update the cast when we change the type |
195 | // Except if the type is LogicalType::ANY (no type specified) |
196 | generated_expression = make_uniq_base<ParsedExpression, CastExpression>(args&: type, args: std::move(expression)); |
197 | } |
198 | |
199 | void ColumnDefinition::ChangeGeneratedExpressionType(const LogicalType &type) { |
200 | D_ASSERT(Generated()); |
201 | // First time the type is set, add a cast around the expression |
202 | D_ASSERT(this->type.id() == LogicalTypeId::ANY); |
203 | generated_expression = make_uniq_base<ParsedExpression, CastExpression>(args: type, args: std::move(generated_expression)); |
204 | // Every generated expression should be wrapped in a cast on creation |
205 | // D_ASSERT(generated_expression->type == ExpressionType::OPERATOR_CAST); |
206 | // auto &cast_expr = generated_expression->Cast<CastExpression>(); |
207 | // auto base_expr = std::move(cast_expr.child); |
208 | // generated_expression = make_uniq_base<ParsedExpression, CastExpression>(type, std::move(base_expr)); |
209 | } |
210 | |
211 | const ParsedExpression &ColumnDefinition::GeneratedExpression() const { |
212 | D_ASSERT(Generated()); |
213 | return *generated_expression; |
214 | } |
215 | |
216 | ParsedExpression &ColumnDefinition::GeneratedExpressionMutable() { |
217 | D_ASSERT(Generated()); |
218 | return *generated_expression; |
219 | } |
220 | |
221 | } // namespace duckdb |
222 | |