@@ -75,27 +75,10 @@ VariantData ExpressionNode::compute(ProcessingUnit& seg) const {
75
75
const ankerl::unordered_dense::map<std::string, DataType>& column_types) const {
76
76
// Default to BitSetTag
77
77
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" );
99
82
if (is_unary_operation (operation_type_)) {
100
83
switch (operation_type_) {
101
84
case OperationType::ABS:
@@ -135,41 +118,15 @@ VariantData ExpressionNode::compute(ProcessingUnit& seg) const {
135
118
}
136
119
} else {
137
120
// 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);
166
123
switch (operation_type_) {
167
124
case OperationType::ADD:
168
125
case OperationType::SUB:
169
126
case OperationType::MUL:
170
127
case OperationType::DIV:
171
128
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" );
173
130
details::visit_type (std::get<DataType>(left_type), [this , &res, right_type](auto left_tag) {
174
131
using left_type_info = ScalarTypeInfo<decltype (left_tag)>;
175
132
details::visit_type (std::get<DataType>(right_type), [this , &res](auto right_tag) {
@@ -213,7 +170,7 @@ VariantData ExpressionNode::compute(ProcessingUnit& seg) const {
213
170
case OperationType::GT:
214
171
case OperationType::GE:
215
172
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" );
217
174
user_input::check<ErrorCode::E_INVALID_USER_ARGUMENT>(
218
175
(is_numeric_type (std::get<DataType>(left_type)) && is_numeric_type (std::get<DataType>(right_type))) ||
219
176
(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 {
224
181
case OperationType::ISIN:
225
182
case OperationType::ISNOTIN:
226
183
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 ) {
229
186
user_input::check<ErrorCode::E_INVALID_USER_ARGUMENT>(
230
187
(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))),
231
188
" Incompatible data types provided in set membership operator {}, {}" ,
@@ -246,4 +203,38 @@ VariantData ExpressionNode::compute(ProcessingUnit& seg) const {
246
203
return res;
247
204
}
248
205
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
+
249
240
} // namespace arcticdb
0 commit comments