Skip to content

Commit 4029b74

Browse files
committed
Factor out child type calculation to own method
1 parent 1c7d237 commit 4029b74

File tree

2 files changed

+57
-53
lines changed

2 files changed

+57
-53
lines changed

cpp/arcticdb/processing/expression_node.cpp

+44-53
Original file line numberDiff line numberDiff line change
@@ -75,27 +75,10 @@ VariantData ExpressionNode::compute(ProcessingUnit& seg) const {
7575
const ankerl::unordered_dense::map<std::string, DataType>& column_types) const {
7676
// Default to BitSetTag
7777
std::variant<BitSetTag, DataType> res;
78-
std::variant<BitSetTag, DataType> left_type = util::variant_match(
79-
left_,
80-
[&column_types] (const ColumnName& column_name) -> std::variant<BitSetTag, DataType> {
81-
auto it = column_types.find(column_name.value);
82-
schema::check<ErrorCode::E_COLUMN_DOESNT_EXIST>(it != column_types.end(),
83-
"ProjectClause requires column '{}' to exist in input data"
84-
,column_name.value);
85-
return it->second;
86-
},
87-
[&expression_context] (const ValueName& value_name) -> std::variant<BitSetTag, DataType> {
88-
return expression_context.values_.get_value(value_name.value)->data_type_;
89-
},
90-
[&expression_context, &column_types] (const ExpressionName& expression_name) -> std::variant<BitSetTag, DataType> {
91-
auto expr = expression_context.expression_nodes_.get_value(expression_name.value);
92-
return expr->compute(expression_context, column_types);
93-
},
94-
[] (auto&&) -> std::variant<BitSetTag, DataType> {
95-
internal::raise<ErrorCode::E_ASSERTION_FAILURE>("Unexpected expression argument type");
96-
return {};
97-
}
98-
);
78+
ValueSetState left_value_set_state;
79+
auto left_type = child_return_type(left_, expression_context, column_types, left_value_set_state);
80+
user_input::check<ErrorCode::E_INVALID_USER_ARGUMENT>(left_value_set_state == ValueSetState::NOT_A_SET,
81+
"Unexpected value set operand");
9982
if (is_unary_operation(operation_type_)) {
10083
switch (operation_type_) {
10184
case OperationType::ABS:
@@ -135,41 +118,15 @@ VariantData ExpressionNode::compute(ProcessingUnit& seg) const {
135118
}
136119
} else {
137120
// Binary operation
138-
std::variant<BitSetTag, DataType> right_type;
139-
std::optional<bool> empty_value_set;
140-
right_type = util::variant_match(
141-
right_,
142-
[&column_types] (const ColumnName& column_name) -> std::variant<BitSetTag, DataType> {
143-
auto it = column_types.find(column_name.value);
144-
schema::check<ErrorCode::E_COLUMN_DOESNT_EXIST>(it != column_types.end(),
145-
"ProjectClause requires column '{}' to exist in input data"
146-
,column_name.value);
147-
return it->second;
148-
},
149-
[&expression_context] (const ValueName& value_name) -> std::variant<BitSetTag, DataType> {
150-
return expression_context.values_.get_value(value_name.value)->data_type_;
151-
},
152-
[&expression_context, &empty_value_set] (const ValueSetName& value_set_name) -> std::variant<BitSetTag, DataType> {
153-
auto value_set = expression_context.value_sets_.get_value(value_set_name.value);
154-
empty_value_set = value_set->empty();
155-
return value_set->base_type().data_type();
156-
},
157-
[&expression_context, &column_types] (const ExpressionName& expression_name) -> std::variant<BitSetTag, DataType> {
158-
auto expr = expression_context.expression_nodes_.get_value(expression_name.value);
159-
return expr->compute(expression_context, column_types);
160-
},
161-
[] (auto&&) -> std::variant<BitSetTag, DataType> {
162-
internal::raise<ErrorCode::E_ASSERTION_FAILURE>("Unexpected expression argument type");
163-
return {};
164-
}
165-
);
121+
ValueSetState right_value_set_state;
122+
auto right_type = child_return_type(right_, expression_context, column_types, right_value_set_state);
166123
switch (operation_type_) {
167124
case OperationType::ADD:
168125
case OperationType::SUB:
169126
case OperationType::MUL:
170127
case OperationType::DIV:
171128
user_input::check<ErrorCode::E_INVALID_USER_ARGUMENT>(std::holds_alternative<DataType>(left_type), "Unexpected bitset input to binary arithmetic operator");
172-
user_input::check<ErrorCode::E_INVALID_USER_ARGUMENT>(std::holds_alternative<DataType>(right_type) && !empty_value_set.has_value(), "Unexpected input to binary arithmetic operator");
129+
user_input::check<ErrorCode::E_INVALID_USER_ARGUMENT>(std::holds_alternative<DataType>(right_type) && right_value_set_state == ValueSetState::NOT_A_SET, "Unexpected input to binary arithmetic operator");
173130
details::visit_type(std::get<DataType>(left_type), [this, &res, right_type](auto left_tag) {
174131
using left_type_info = ScalarTypeInfo<decltype(left_tag)>;
175132
details::visit_type(std::get<DataType>(right_type), [this, &res](auto right_tag) {
@@ -213,7 +170,7 @@ VariantData ExpressionNode::compute(ProcessingUnit& seg) const {
213170
case OperationType::GT:
214171
case OperationType::GE:
215172
user_input::check<ErrorCode::E_INVALID_USER_ARGUMENT>(std::holds_alternative<DataType>(left_type), "Unexpected bitset input to binary comparison operator");
216-
user_input::check<ErrorCode::E_INVALID_USER_ARGUMENT>(std::holds_alternative<DataType>(right_type) && !empty_value_set.has_value(), "Unexpected input to binary comparison operator");
173+
user_input::check<ErrorCode::E_INVALID_USER_ARGUMENT>(std::holds_alternative<DataType>(right_type) && right_value_set_state == ValueSetState::NOT_A_SET, "Unexpected input to binary comparison operator");
217174
user_input::check<ErrorCode::E_INVALID_USER_ARGUMENT>(
218175
(is_numeric_type(std::get<DataType>(left_type)) && is_numeric_type(std::get<DataType>(right_type))) ||
219176
(is_bool_type(std::get<DataType>(left_type)) && is_bool_type(std::get<DataType>(right_type))) ||
@@ -224,8 +181,8 @@ VariantData ExpressionNode::compute(ProcessingUnit& seg) const {
224181
case OperationType::ISIN:
225182
case OperationType::ISNOTIN:
226183
user_input::check<ErrorCode::E_INVALID_USER_ARGUMENT>(std::holds_alternative<DataType>(left_type), "Unexpected bitset input to binary comparison operator");
227-
user_input::check<ErrorCode::E_INVALID_USER_ARGUMENT>(std::holds_alternative<DataType>(right_type) && empty_value_set.has_value(), "Unexpected input to binary comparison operator");
228-
if (!*empty_value_set) {
184+
user_input::check<ErrorCode::E_INVALID_USER_ARGUMENT>(std::holds_alternative<DataType>(right_type) && right_value_set_state != ValueSetState::NOT_A_SET, "Unexpected input to binary comparison operator");
185+
if (right_value_set_state == ValueSetState::NON_EMPTY_SET) {
229186
user_input::check<ErrorCode::E_INVALID_USER_ARGUMENT>(
230187
(is_sequence_type(std::get<DataType>(left_type)) && is_sequence_type(std::get<DataType>(right_type))) || (is_numeric_type(std::get<DataType>(left_type)) && is_numeric_type(std::get<DataType>(right_type))),
231188
"Incompatible data types provided in set membership operator {}, {}",
@@ -246,4 +203,38 @@ VariantData ExpressionNode::compute(ProcessingUnit& seg) const {
246203
return res;
247204
}
248205

206+
std::variant<BitSetTag, DataType> ExpressionNode::child_return_type(
207+
const VariantNode& child,
208+
const ExpressionContext& expression_context,
209+
const ankerl::unordered_dense::map<std::string, DataType>& column_types,
210+
ValueSetState& value_set_state) const {
211+
value_set_state = ValueSetState::NOT_A_SET;
212+
return util::variant_match(
213+
child,
214+
[&column_types] (const ColumnName& column_name) -> std::variant<BitSetTag, DataType> {
215+
auto it = column_types.find(column_name.value);
216+
schema::check<ErrorCode::E_COLUMN_DOESNT_EXIST>(it != column_types.end(),
217+
"Clause requires column '{}' to exist in input data"
218+
,column_name.value);
219+
return it->second;
220+
},
221+
[&expression_context] (const ValueName& value_name) -> std::variant<BitSetTag, DataType> {
222+
return expression_context.values_.get_value(value_name.value)->data_type_;
223+
},
224+
[&expression_context, &value_set_state] (const ValueSetName& value_set_name) -> std::variant<BitSetTag, DataType> {
225+
auto value_set = expression_context.value_sets_.get_value(value_set_name.value);
226+
value_set_state = value_set->empty() ? ValueSetState::EMPTY_SET : ValueSetState::NON_EMPTY_SET;
227+
return value_set->base_type().data_type();
228+
},
229+
[&expression_context, &column_types] (const ExpressionName& expression_name) -> std::variant<BitSetTag, DataType> {
230+
auto expr = expression_context.expression_nodes_.get_value(expression_name.value);
231+
return expr->compute(expression_context, column_types);
232+
},
233+
[] (auto&&) -> std::variant<BitSetTag, DataType> {
234+
internal::raise<ErrorCode::E_ASSERTION_FAILURE>("Unexpected expression argument type");
235+
return {};
236+
}
237+
);
238+
}
239+
249240
} //namespace arcticdb

cpp/arcticdb/processing/expression_node.hpp

+13
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,19 @@ struct ExpressionNode {
9595
std::variant<BitSetTag, DataType> compute(
9696
const ExpressionContext& expression_context,
9797
const ankerl::unordered_dense::map<std::string, DataType>& column_types) const;
98+
99+
private:
100+
enum class ValueSetState {
101+
NOT_A_SET,
102+
EMPTY_SET,
103+
NON_EMPTY_SET
104+
};
105+
106+
std::variant<BitSetTag, DataType> child_return_type(
107+
const VariantNode& child,
108+
const ExpressionContext& expression_context,
109+
const ankerl::unordered_dense::map<std::string, DataType>& column_types,
110+
ValueSetState& value_set_state) const;
98111
};
99112

100113
} //namespace arcticdb

0 commit comments

Comments
 (0)