Repository: gluesql/gluesql
Pull request #173 (2021-03-12 13:49:42)

Remove fake unreachable errors in EvaluateError
There were some reachable errors in `evaluate.rs` but marked as `Unreachable-`.
Remove some fake unreachable errors, and replace to reachable named errors.


Patch:
diff --git a/src/executor/evaluate/error.rs b/src/executor/evaluate/error.rs
index 74b4f7ea..cf4cd6ff 100644
--- a/src/executor/evaluate/error.rs
+++ b/src/executor/evaluate/error.rs
@@ -36,11 +36,17 @@ pub enum EvaluateError {
     #[error("unsupported compound identifier {0}")]
     UnsupportedCompoundIdentifier(String),
 
-    #[error("unreachable condition base")]
-    UnreachableConditionBase,
+    #[error("unsupported literal binary arithmetic between {0} and {1}")]
+    UnsupportedLiteralBinaryArithmetic(String, String),
 
-    #[error("unreachable evaluated arithmetic")]
-    UnreachableEvaluatedArithmetic,
+    #[error("unsupported evaluated binary arithmetic between {0} and {1}")]
+    UnsupportedEvaluatedBinaryArithmetic(String, String),
+
+    #[error("unsupported evaluated unary arithmetic of {0}")]
+    UnsupportedEvaluatedUnaryArithmetic(String),
+
+    #[error("unimplemented")]
+    Unimplemented,
 
     #[error("unreachable literal arithmetic")]
     UnreachableLiteralArithmetic,
@@ -48,9 +54,6 @@ pub enum EvaluateError {
     #[error("unreachable empty context")]
     UnreachableEmptyContext,
 
-    #[error("unimplemented")]
-    Unimplemented,
-
     #[error("unreachable named function argument: {0}")]
     UnreachableFunctionArg(String),
 }
diff --git a/src/executor/evaluate/evaluated.rs b/src/executor/evaluate/evaluated.rs
index dde6c0f4..2f853896 100644
--- a/src/executor/evaluate/evaluated.rs
+++ b/src/executor/evaluate/evaluated.rs
@@ -167,10 +167,17 @@ macro_rules! binary_op {
                         _ => Err(EvaluateError::UnreachableLiteralArithmetic.into()),
                     },
                 }.map(Evaluated::Literal),
-                (Literal::Null, Literal::Number(_, false)) | (Literal::Number(_, false), Literal::Null) => {
+                (Literal::Null, Literal::Number(_, false))
+                | (Literal::Number(_, false), Literal::Null)
+                | (Literal::Null, Literal::Null) => {
                     Ok(Evaluated::Literal(Literal::Null))
                 }
-                _ => Err(EvaluateError::UnreachableLiteralArithmetic.into()),
+                _ => Err(
+                    EvaluateError::UnsupportedLiteralBinaryArithmetic(
+                        l.to_string(),
+                        r.to_string()
+                    ).into()
+                ),
             };
 
             let value_binary_op = |l: &data::Value, r: &data::Value| {
@@ -194,11 +201,17 @@ macro_rules! binary_op {
                 (Value(l),      Literal(r))    => value_binary_op(l, &data::Value::try_from(r)?),
                 (Value(l),      ValueRef(r))   => value_binary_op(l, r),
                 (Value(l),      Value(r))      => value_binary_op(l, r),
-                _ => Err(EvaluateError::UnreachableEvaluatedArithmetic.into()),
+                _ => Err(
+                    EvaluateError::UnsupportedEvaluatedBinaryArithmetic(
+                        format!("{:?}", self),
+                        format!("{:?}", other),
+                    ).into()
+                ),
             }
         }
     };
 }
+
 macro_rules! unary_op {
     ($name:ident, $op:tt) => {
         pub fn $name(&self) -> Result<Evaluated<'a>> {
@@ -219,7 +232,9 @@ macro_rules! unary_op {
                 Literal(v) => literal_unary_op(&v).map(Evaluated::Literal),
                 ValueRef(v) => v.$name().map(Evaluated::Value),
                 Value(v) => (&v).$name().map(Evaluated::Value),
-                _ => Err(EvaluateError::UnreachableEvaluatedArithmetic.into()),
+                _ => Err(
+                    EvaluateError::UnsupportedEvaluatedUnaryArithmetic(format!("{:?}", self)).into()
+                ),
             }
         }
     };


Test patch:
diff --git a/src/tests/arithmetic.rs b/src/tests/arithmetic.rs
index 924fdb93..e8f097ea 100644
--- a/src/tests/arithmetic.rs
+++ b/src/tests/arithmetic.rs
@@ -80,6 +80,24 @@ test_case!(arithmetic, async move {
             UpdateError::ColumnNotFound("aaa".to_owned()).into(),
             "UPDATE Arith SET aaa = 1",
         ),
+        (
+            EvaluateError::UnsupportedLiteralBinaryArithmetic("true".to_owned(), "1".to_owned())
+                .into(),
+            "SELECT * FROM Arith WHERE TRUE + 1 = 1",
+        ),
+        (
+            EvaluateError::UnsupportedEvaluatedBinaryArithmetic(
+                r#"StringRef("asdf")"#.to_owned(),
+                r#"LiteralRef(Number("1", false))"#.to_owned(),
+            )
+            .into(),
+            r#"SELECT * FROM Arith WHERE "asdf" + 1 > 1"#,
+        ),
+        (
+            EvaluateError::UnsupportedEvaluatedUnaryArithmetic(r#"StringRef("asdf")"#.to_owned())
+                .into(),
+            r#"SELECT * FROM Arith WHERE -"asdf" = TRUE;"#,
+        ),
     ];
 
     for (error, sql) in test_cases.into_iter() {
diff --git a/src/tests/nullable.rs b/src/tests/nullable.rs
index 5d33f718..4e2dbd90 100644
--- a/src/tests/nullable.rs
+++ b/src/tests/nullable.rs
@@ -115,6 +115,15 @@ CREATE TABLE Test (
                 I64(3)   I64(4)
             ),
         ),
+        (
+            "SELECT id, num FROM Test WHERE (NULL + NULL) IS NULL;",
+            select_with_null!(
+                id   | num;
+                Null   I64(2);
+                I64(1)   I64(9);
+                I64(3)   I64(4)
+            ),
+        ),
         (
             "SELECT id, num FROM Test WHERE \"NULL\" IS NULL",
             select!(id | num),