/src/duckdb/src/parser/column_definition.cpp
Line | Count | Source |
1 | | #include "duckdb/parser/column_definition.hpp" |
2 | | #include "duckdb/parser/parsed_expression_iterator.hpp" |
3 | | #include "duckdb/parser/expression/columnref_expression.hpp" |
4 | | #include "duckdb/parser/expression/cast_expression.hpp" |
5 | | #include "duckdb/common/exception/parser_exception.hpp" |
6 | | |
7 | | namespace duckdb { |
8 | | |
9 | | ColumnDefinition::ColumnDefinition(string name_p, LogicalType type_p) |
10 | 653k | : name(std::move(name_p)), type(std::move(type_p)) { |
11 | 653k | } |
12 | | |
13 | | ColumnDefinition::ColumnDefinition(string name_p, LogicalType type_p, unique_ptr<ParsedExpression> expression, |
14 | | TableColumnType category) |
15 | 2.97k | : name(std::move(name_p)), type(std::move(type_p)), category(category), expression(std::move(expression)) { |
16 | 2.97k | } |
17 | | |
18 | 1.46k | ColumnDefinition ColumnDefinition::Copy() const { |
19 | 1.46k | ColumnDefinition copy(name, type); |
20 | 1.46k | copy.oid = oid; |
21 | 1.46k | copy.storage_oid = storage_oid; |
22 | 1.46k | copy.expression = expression ? expression->Copy() : nullptr; |
23 | 1.46k | copy.compression_type = compression_type; |
24 | 1.46k | copy.category = category; |
25 | 1.46k | copy.comment = comment; |
26 | 1.46k | copy.tags = tags; |
27 | 1.46k | return copy; |
28 | 1.46k | } |
29 | | |
30 | 0 | const ParsedExpression &ColumnDefinition::DefaultValue() const { |
31 | 0 | if (!HasDefaultValue()) { |
32 | 0 | if (Generated()) { |
33 | 0 | throw InternalException("Calling DefaultValue() on a generated column"); |
34 | 0 | } |
35 | 0 | throw InternalException("DefaultValue() called on a column without a default value"); |
36 | 0 | } |
37 | 0 | return *expression; |
38 | 0 | } |
39 | | |
40 | 3.04k | bool ColumnDefinition::HasDefaultValue() const { |
41 | 3.04k | if (Generated()) { |
42 | 0 | return false; |
43 | 0 | } |
44 | 3.04k | return expression != nullptr; |
45 | 3.04k | } |
46 | | |
47 | 0 | void ColumnDefinition::SetDefaultValue(unique_ptr<ParsedExpression> default_value) { |
48 | 0 | if (Generated()) { |
49 | 0 | throw InternalException("Calling SetDefaultValue() on a generated column"); |
50 | 0 | } |
51 | 0 | this->expression = std::move(default_value); |
52 | 0 | } |
53 | | |
54 | 335k | const LogicalType &ColumnDefinition::Type() const { |
55 | 335k | return type; |
56 | 335k | } |
57 | | |
58 | 4.48k | LogicalType &ColumnDefinition::TypeMutable() { |
59 | 4.48k | return type; |
60 | 4.48k | } |
61 | | |
62 | 0 | void ColumnDefinition::SetType(const LogicalType &type) { |
63 | 0 | this->type = type; |
64 | 0 | } |
65 | | |
66 | 1.31M | const string &ColumnDefinition::Name() const { |
67 | 1.31M | return name; |
68 | 1.31M | } |
69 | 2.39k | void ColumnDefinition::SetName(const string &name) { |
70 | 2.39k | this->name = name; |
71 | 2.39k | } |
72 | | |
73 | 0 | const Value &ColumnDefinition::Comment() const { |
74 | 0 | return comment; |
75 | 0 | } |
76 | | |
77 | 0 | void ColumnDefinition::SetComment(const Value &comment) { |
78 | 0 | this->comment = comment; |
79 | 0 | } |
80 | | |
81 | 2.99k | const duckdb::CompressionType &ColumnDefinition::CompressionType() const { |
82 | 2.99k | return compression_type; |
83 | 2.99k | } |
84 | | |
85 | 0 | void ColumnDefinition::SetCompressionType(duckdb::CompressionType compression_type) { |
86 | 0 | this->compression_type = compression_type; |
87 | 0 | } |
88 | | |
89 | 0 | const storage_t &ColumnDefinition::StorageOid() const { |
90 | 0 | return storage_oid; |
91 | 0 | } |
92 | | |
93 | 159 | LogicalIndex ColumnDefinition::Logical() const { |
94 | 159 | return LogicalIndex(oid); |
95 | 159 | } |
96 | | |
97 | 3 | PhysicalIndex ColumnDefinition::Physical() const { |
98 | 3 | return PhysicalIndex(storage_oid); |
99 | 3 | } |
100 | | |
101 | 655k | void ColumnDefinition::SetStorageOid(storage_t storage_oid) { |
102 | 655k | this->storage_oid = storage_oid; |
103 | 655k | } |
104 | | |
105 | 655k | const column_t &ColumnDefinition::Oid() const { |
106 | 655k | return oid; |
107 | 655k | } |
108 | | |
109 | 655k | void ColumnDefinition::SetOid(column_t oid) { |
110 | 655k | this->oid = oid; |
111 | 655k | } |
112 | | |
113 | 0 | const TableColumnType &ColumnDefinition::Category() const { |
114 | 0 | return category; |
115 | 0 | } |
116 | | |
117 | 667k | bool ColumnDefinition::Generated() const { |
118 | 667k | return category == TableColumnType::GENERATED; |
119 | 667k | } |
120 | | |
121 | | //===--------------------------------------------------------------------===// |
122 | | // Generated Columns (VIRTUAL) |
123 | | //===--------------------------------------------------------------------===// |
124 | | |
125 | 19 | static void VerifyColumnRefs(const ParsedExpression &expr) { |
126 | 19 | ParsedExpressionIterator::VisitExpression<ColumnRefExpression>(expr, [&](const ColumnRefExpression &column_ref) { |
127 | 19 | if (column_ref.IsQualified()) { |
128 | 0 | throw ParserException( |
129 | 0 | "Qualified (tbl.name) column references are not allowed inside of generated column expressions"); |
130 | 0 | } |
131 | 19 | }); |
132 | 19 | } |
133 | | |
134 | 6 | static void InnerGetListOfDependencies(ParsedExpression &expr, vector<string> &dependencies) { |
135 | 6 | if (expr.GetExpressionType() == ExpressionType::COLUMN_REF) { |
136 | 4 | auto columnref = expr.Cast<ColumnRefExpression>(); |
137 | 4 | auto &name = columnref.GetColumnName(); |
138 | 4 | dependencies.push_back(name); |
139 | 4 | } |
140 | 6 | ParsedExpressionIterator::EnumerateChildren(expr, [&](const ParsedExpression &child) { |
141 | 2 | if (expr.GetExpressionType() == ExpressionType::LAMBDA) { |
142 | 0 | throw NotImplementedException("Lambda functions are currently not supported in generated columns."); |
143 | 0 | } |
144 | 2 | InnerGetListOfDependencies((ParsedExpression &)child, dependencies); |
145 | 2 | }); |
146 | 6 | } |
147 | | |
148 | 4 | void ColumnDefinition::GetListOfDependencies(vector<string> &dependencies) const { |
149 | 4 | D_ASSERT(Generated()); |
150 | 4 | InnerGetListOfDependencies(*expression, dependencies); |
151 | 4 | } |
152 | | |
153 | 325k | string ColumnDefinition::GetName() const { |
154 | 325k | return name; |
155 | 325k | } |
156 | | |
157 | 329k | LogicalType ColumnDefinition::GetType() const { |
158 | 329k | return type; |
159 | 329k | } |
160 | | |
161 | 19 | void ColumnDefinition::SetGeneratedExpression(unique_ptr<ParsedExpression> new_expr) { |
162 | 19 | category = TableColumnType::GENERATED; |
163 | | |
164 | 19 | if (new_expr->HasSubquery()) { |
165 | 0 | throw ParserException("Expression of generated column \"%s\" contains a subquery, which isn't allowed", name); |
166 | 0 | } |
167 | | |
168 | 19 | VerifyColumnRefs(*new_expr); |
169 | 19 | if (type.id() == LogicalTypeId::ANY) { |
170 | 13 | expression = std::move(new_expr); |
171 | 13 | return; |
172 | 13 | } |
173 | | // Always wrap the expression in a cast, that way we can always update the cast when we change the type |
174 | | // Except if the type is LogicalType::ANY (no type specified) |
175 | 6 | expression = make_uniq_base<ParsedExpression, CastExpression>(type, std::move(new_expr)); |
176 | 6 | } |
177 | | |
178 | 0 | void ColumnDefinition::ChangeGeneratedExpressionType(const LogicalType &type) { |
179 | 0 | D_ASSERT(Generated()); |
180 | | // First time the type is set, add a cast around the expression |
181 | 0 | D_ASSERT(this->type.id() == LogicalTypeId::ANY); |
182 | 0 | expression = make_uniq_base<ParsedExpression, CastExpression>(type, std::move(expression)); |
183 | | // Every generated expression should be wrapped in a cast on creation |
184 | | // D_ASSERT(generated_expression->type == ExpressionType::OPERATOR_CAST); |
185 | | // auto &cast_expr = generated_expression->Cast<CastExpression>(); |
186 | | // auto base_expr = std::move(cast_expr.child); |
187 | | // generated_expression = make_uniq_base<ParsedExpression, CastExpression>(type, std::move(base_expr)); |
188 | 0 | } |
189 | | |
190 | 8 | const ParsedExpression &ColumnDefinition::GeneratedExpression() const { |
191 | 8 | D_ASSERT(Generated()); |
192 | 8 | return *expression; |
193 | 8 | } |
194 | | |
195 | 0 | ParsedExpression &ColumnDefinition::GeneratedExpressionMutable() { |
196 | 0 | D_ASSERT(Generated()); |
197 | 0 | return *expression; |
198 | 0 | } |
199 | | |
200 | | } // namespace duckdb |