summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibSQL
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2022-02-11 10:23:20 -0500
committerLinus Groh <mail@linusgroh.de>2022-02-13 21:30:38 +0000
commitbfe1bd9726779fb324fe3f7bc3dde33fd1295fe6 (patch)
treed35ec81edeaf957611e666cb0021d27f13362837 /Userland/Libraries/LibSQL
parentb15db851fed62807a1b595f1130b5ff9dac83a8f (diff)
downloadserenity-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.cpp83
-rw-r--r--Userland/Libraries/LibSQL/Value.h19
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
{