in src/core/storage/sframe_interface/unity_sarray_binary_operations.cpp [14:82]
void check_operation_feasibility(flex_type_enum left,
flex_type_enum right,
std::string op) {
bool operation_is_feasible = false;
if (op == "+" || op == "-" || op == "*" || op == "/") {
if (left == flex_type_enum::DATETIME && right == flex_type_enum::DATETIME && op == "-") {
operation_is_feasible = true;
} else {
operation_is_feasible = flex_type_has_binary_op(left, right, op[0]) ||
((left == flex_type_enum::FLOAT
|| left == flex_type_enum::INTEGER
|| left == flex_type_enum::VECTOR)
&& (right == flex_type_enum::FLOAT
|| right == flex_type_enum::INTEGER
|| right == flex_type_enum::VECTOR)) ||
((left == flex_type_enum::FLOAT
|| left == flex_type_enum::INTEGER
|| left == flex_type_enum::ND_VECTOR)
&& (right == flex_type_enum::FLOAT
|| right == flex_type_enum::INTEGER
|| right == flex_type_enum::ND_VECTOR));
}
} else if (op == "%") {
operation_is_feasible = left == flex_type_enum::INTEGER &&
right == flex_type_enum::INTEGER;
} else if (op == "**" || op == "//") {
operation_is_feasible = (
(left == flex_type_enum::FLOAT
|| left == flex_type_enum::INTEGER
|| left == flex_type_enum::VECTOR)
&& (right == flex_type_enum::FLOAT
|| right == flex_type_enum::INTEGER
|| right == flex_type_enum::VECTOR));
} else if (op == "<" || op == ">" || op == "<=" || op == ">=") {
// the comparison operators are all compatible. we just need to check
// the < operator
operation_is_feasible = flex_type_has_binary_op(left, right, '<');
} else if (op == "==" || op == "!=") {
// equality comparison is always feasible
operation_is_feasible = true;
} else if (op == "&" || op == "|") {
// boolean operations are always feasible
operation_is_feasible = true;
} else if (op == "in") {
// note that while the op is "in", the direction of the operator is
// [BIGGER_LIST "in" element] rather than ["element" in BIGGER_LIST]
// yes. slightly disconcerting I know. Sorry.
operation_is_feasible = (left == flex_type_enum::STRING && right == flex_type_enum::STRING) ||
(left == flex_type_enum::VECTOR && right == flex_type_enum::FLOAT) ||
(left == flex_type_enum::VECTOR && right == flex_type_enum::INTEGER) ||
(left == flex_type_enum::DICT) ||
(left == flex_type_enum::LIST);
} else if (op == "left_abs") {
// right part of the operator is ignored in this one
operation_is_feasible = (left == flex_type_enum::FLOAT
|| left == flex_type_enum::INTEGER
|| left == flex_type_enum::VECTOR);
} else {
log_and_throw("Invalid scalar operation");
}
if (!operation_is_feasible) {
throw std::string("Unsupported type operation. cannot perform operation ") +
op + " between " +
flex_type_enum_to_name(left) + " and " +
flex_type_enum_to_name(right);
}
}