diff options
author | Timothy Flynn <trflynn89@pm.me> | 2022-02-11 10:23:20 -0500 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-02-13 21:30:38 +0000 |
commit | bfe1bd9726779fb324fe3f7bc3dde33fd1295fe6 (patch) | |
tree | d35ec81edeaf957611e666cb0021d27f13362837 /Userland/Libraries/LibSQL | |
parent | b15db851fed62807a1b595f1130b5ff9dac83a8f (diff) | |
download | serenity-bfe1bd9726779fb324fe3f7bc3dde33fd1295fe6.zip |
LibSQL: Convert binary SQL operations to be fallible
Now that expression evaluation can use TRY, we can allow binary operator
methods to fail as well. This also fixes a few instances of converting a
Value to a double when we meant to convert to an integer.
Diffstat (limited to 'Userland/Libraries/LibSQL')
-rw-r--r-- | Userland/Libraries/LibSQL/Value.cpp | 83 | ||||
-rw-r--r-- | Userland/Libraries/LibSQL/Value.h | 19 |
2 files changed, 43 insertions, 59 deletions
diff --git a/Userland/Libraries/LibSQL/Value.cpp b/Userland/Libraries/LibSQL/Value.cpp index e41f6dad51..a90bcda850 100644 --- a/Userland/Libraries/LibSQL/Value.cpp +++ b/Userland/Libraries/LibSQL/Value.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibSQL/AST/AST.h> #include <LibSQL/Serializer.h> #include <LibSQL/Value.h> #include <math.h> @@ -390,135 +391,117 @@ bool Value::operator>=(Value const& other) const return compare(other) >= 0; } -Value Value::add(Value const& other) const +static Result invalid_type_for_numeric_operator(AST::BinaryOperator op) +{ + return { SQLCommand::Unknown, SQLErrorCode::NumericOperatorTypeMismatch, BinaryOperator_name(op) }; +} + +ResultOr<Value> Value::add(Value const& other) const { if (auto double_maybe = to_double(); double_maybe.has_value()) { if (auto other_double_maybe = other.to_double(); other_double_maybe.has_value()) return Value(double_maybe.value() + other_double_maybe.value()); if (auto int_maybe = other.to_int(); int_maybe.has_value()) return Value(double_maybe.value() + (double)int_maybe.value()); - VERIFY_NOT_REACHED(); - } - if (auto int_maybe = to_double(); int_maybe.has_value()) { + } else if (auto int_maybe = to_int(); int_maybe.has_value()) { if (auto other_double_maybe = other.to_double(); other_double_maybe.has_value()) return Value(other_double_maybe.value() + (double)int_maybe.value()); if (auto other_int_maybe = other.to_int(); other_int_maybe.has_value()) return Value(int_maybe.value() + other_int_maybe.value()); - VERIFY_NOT_REACHED(); } - VERIFY_NOT_REACHED(); + return invalid_type_for_numeric_operator(AST::BinaryOperator::Plus); } -Value Value::subtract(Value const& other) const +ResultOr<Value> Value::subtract(Value const& other) const { if (auto double_maybe = to_double(); double_maybe.has_value()) { if (auto other_double_maybe = other.to_double(); other_double_maybe.has_value()) return Value(double_maybe.value() - other_double_maybe.value()); if (auto int_maybe = other.to_int(); int_maybe.has_value()) return Value(double_maybe.value() - (double)int_maybe.value()); - VERIFY_NOT_REACHED(); - } - if (auto int_maybe = to_double(); int_maybe.has_value()) { + } else if (auto int_maybe = to_int(); int_maybe.has_value()) { if (auto other_double_maybe = other.to_double(); other_double_maybe.has_value()) return Value((double)int_maybe.value() - other_double_maybe.value()); if (auto other_int_maybe = other.to_int(); other_int_maybe.has_value()) return Value(int_maybe.value() - other_int_maybe.value()); - VERIFY_NOT_REACHED(); } - VERIFY_NOT_REACHED(); + return invalid_type_for_numeric_operator(AST::BinaryOperator::Minus); } -Value Value::multiply(Value const& other) const +ResultOr<Value> Value::multiply(Value const& other) const { if (auto double_maybe = to_double(); double_maybe.has_value()) { if (auto other_double_maybe = other.to_double(); other_double_maybe.has_value()) return Value(double_maybe.value() * other_double_maybe.value()); if (auto int_maybe = other.to_int(); int_maybe.has_value()) return Value(double_maybe.value() * (double)int_maybe.value()); - VERIFY_NOT_REACHED(); - } - if (auto int_maybe = to_double(); int_maybe.has_value()) { + } else if (auto int_maybe = to_int(); int_maybe.has_value()) { if (auto other_double_maybe = other.to_double(); other_double_maybe.has_value()) return Value((double)int_maybe.value() * other_double_maybe.value()); if (auto other_int_maybe = other.to_int(); other_int_maybe.has_value()) return Value(int_maybe.value() * other_int_maybe.value()); - VERIFY_NOT_REACHED(); } - VERIFY_NOT_REACHED(); + return invalid_type_for_numeric_operator(AST::BinaryOperator::Multiplication); } -Value Value::divide(Value const& other) const +ResultOr<Value> Value::divide(Value const& other) const { if (auto double_maybe = to_double(); double_maybe.has_value()) { if (auto other_double_maybe = other.to_double(); other_double_maybe.has_value()) return Value(double_maybe.value() / other_double_maybe.value()); if (auto int_maybe = other.to_int(); int_maybe.has_value()) return Value(double_maybe.value() / (double)int_maybe.value()); - VERIFY_NOT_REACHED(); - } - - if (auto int_maybe = to_double(); int_maybe.has_value()) { + } else if (auto int_maybe = to_int(); int_maybe.has_value()) { if (auto other_double_maybe = other.to_double(); other_double_maybe.has_value()) return Value((double)int_maybe.value() / other_double_maybe.value()); if (auto other_int_maybe = other.to_int(); other_int_maybe.has_value()) return Value(int_maybe.value() / other_int_maybe.value()); - VERIFY_NOT_REACHED(); } - VERIFY_NOT_REACHED(); + return invalid_type_for_numeric_operator(AST::BinaryOperator::Division); } -Value Value::modulo(Value const& other) const +ResultOr<Value> Value::modulo(Value const& other) const { auto int_maybe_1 = to_int(); auto int_maybe_2 = other.to_int(); - if (!int_maybe_1.has_value() || !int_maybe_2.has_value()) { - // TODO Error handling - VERIFY_NOT_REACHED(); - } + if (!int_maybe_1.has_value() || !int_maybe_2.has_value()) + return invalid_type_for_numeric_operator(AST::BinaryOperator::Modulo); return Value(int_maybe_1.value() % int_maybe_2.value()); } -Value Value::shift_left(Value const& other) const +ResultOr<Value> Value::shift_left(Value const& other) const { auto u32_maybe = to_u32(); auto num_bytes_maybe = other.to_int(); - if (!u32_maybe.has_value() || !num_bytes_maybe.has_value()) { - // TODO Error handling - VERIFY_NOT_REACHED(); - } + if (!u32_maybe.has_value() || !num_bytes_maybe.has_value()) + return invalid_type_for_numeric_operator(AST::BinaryOperator::ShiftLeft); return Value(u32_maybe.value() << num_bytes_maybe.value()); } -Value Value::shift_right(Value const& other) const +ResultOr<Value> Value::shift_right(Value const& other) const { auto u32_maybe = to_u32(); auto num_bytes_maybe = other.to_int(); - if (!u32_maybe.has_value() || !num_bytes_maybe.has_value()) { - // TODO Error handling - VERIFY_NOT_REACHED(); - } + if (!u32_maybe.has_value() || !num_bytes_maybe.has_value()) + return invalid_type_for_numeric_operator(AST::BinaryOperator::ShiftRight); return Value(u32_maybe.value() >> num_bytes_maybe.value()); } -Value Value::bitwise_or(Value const& other) const +ResultOr<Value> Value::bitwise_or(Value const& other) const { auto u32_maybe_1 = to_u32(); auto u32_maybe_2 = other.to_u32(); - if (!u32_maybe_1.has_value() || !u32_maybe_2.has_value()) { - // TODO Error handling - VERIFY_NOT_REACHED(); - } + if (!u32_maybe_1.has_value() || !u32_maybe_2.has_value()) + return invalid_type_for_numeric_operator(AST::BinaryOperator::BitwiseOr); return Value(u32_maybe_1.value() | u32_maybe_2.value()); } -Value Value::bitwise_and(Value const& other) const +ResultOr<Value> Value::bitwise_and(Value const& other) const { auto u32_maybe_1 = to_u32(); auto u32_maybe_2 = other.to_u32(); - if (!u32_maybe_1.has_value() || !u32_maybe_2.has_value()) { - // TODO Error handling - VERIFY_NOT_REACHED(); - } + if (!u32_maybe_1.has_value() || !u32_maybe_2.has_value()) + return invalid_type_for_numeric_operator(AST::BinaryOperator::BitwiseAnd); return Value(u32_maybe_1.value() & u32_maybe_2.value()); } diff --git a/Userland/Libraries/LibSQL/Value.h b/Userland/Libraries/LibSQL/Value.h index 54f1df22d8..382942b00c 100644 --- a/Userland/Libraries/LibSQL/Value.h +++ b/Userland/Libraries/LibSQL/Value.h @@ -12,6 +12,7 @@ #include <AK/String.h> #include <AK/Variant.h> #include <LibSQL/Forward.h> +#include <LibSQL/Result.h> #include <LibSQL/TupleDescriptor.h> #include <LibSQL/Type.h> #include <LibSQL/ValueImpl.h> @@ -118,15 +119,15 @@ public: bool operator>(Value const&) const; bool operator>=(Value const&) const; - Value add(Value const&) const; - Value subtract(Value const&) const; - Value multiply(Value const&) const; - Value divide(Value const&) const; - Value modulo(Value const&) const; - Value shift_left(Value const&) const; - Value shift_right(Value const&) const; - Value bitwise_or(Value const&) const; - Value bitwise_and(Value const&) const; + ResultOr<Value> add(Value const&) const; + ResultOr<Value> subtract(Value const&) const; + ResultOr<Value> multiply(Value const&) const; + ResultOr<Value> divide(Value const&) const; + ResultOr<Value> modulo(Value const&) const; + ResultOr<Value> shift_left(Value const&) const; + ResultOr<Value> shift_right(Value const&) const; + ResultOr<Value> bitwise_or(Value const&) const; + ResultOr<Value> bitwise_and(Value const&) const; [[nodiscard]] TupleElementDescriptor descriptor() const { |