Repository: gluesql/gluesql
Pull request #209 (2021-04-24 01:39:22)

Remove implicit CAST from Evaluated to bool,
Only explicit boolean values are accepted; Value::Bool or Literal::Boolean.
Making the rule as simple as possible, no truthy or falsy value policy.

related to https://github.com/gluesql/gluesql/pull/208

e.g.
```sql
SELECT * FROM TableA WHERE "1"; -- not accepted
```


Patch:
diff --git a/src/executor/evaluate/error.rs b/src/executor/evaluate/error.rs
index 34d2547e..6249aca2 100644
--- a/src/executor/evaluate/error.rs
+++ b/src/executor/evaluate/error.rs
@@ -30,6 +30,9 @@ pub enum EvaluateError {
     #[error("value not found: {0}")]
     ValueNotFound(String),
 
+    #[error("only boolean value is accepted: {0}")]
+    BooleanTypeRequired(String),
+
     #[error("unsupported compound identifier {0}")]
     UnsupportedCompoundIdentifier(String),
 
diff --git a/src/executor/evaluate/evaluated.rs b/src/executor/evaluate/evaluated.rs
index d2d70400..6b25a579 100644
--- a/src/executor/evaluate/evaluated.rs
+++ b/src/executor/evaluate/evaluated.rs
@@ -1,7 +1,7 @@
 use {
+    super::error::EvaluateError,
     crate::{
-        data::value::TryFromLiteral,
-        data::{Literal, Value},
+        data::{value::TryFromLiteral, Literal, Value},
         result::{Error, Result},
     },
     sqlparser::ast::DataType,
@@ -45,9 +45,17 @@ impl TryInto<bool> for Evaluated<'_> {
     type Error = Error;
 
     fn try_into(self) -> Result<bool> {
-        let value: Value = self.try_into()?;
-
-        value.try_into()
+        match self {
+            Evaluated::Literal(Literal::Boolean(v)) => Ok(v),
+            Evaluated::Literal(v) => {
+                Err(EvaluateError::BooleanTypeRequired(format!("{:?}", v)).into())
+            }
+            Evaluated::Value(Cow::Owned(Value::Bool(v))) => Ok(v),
+            Evaluated::Value(Cow::Borrowed(Value::Bool(v))) => Ok(*v),
+            Evaluated::Value(v) => {
+                Err(EvaluateError::BooleanTypeRequired(format!("{:?}", v)).into())
+            }
+        }
     }
 }
 


Test patch:
diff --git a/src/tests/arithmetic.rs b/src/tests/arithmetic.rs
index 4e3ad476..64c6401f 100644
--- a/src/tests/arithmetic.rs
+++ b/src/tests/arithmetic.rs
@@ -98,12 +98,24 @@ test_case!(arithmetic, async move {
         ),
         (
             LiteralError::UnsupportedBinaryArithmetic(
-                format!("{:?}", data::Literal::Boolean(true)),
-                format!("{:?}", data::Literal::Number(Cow::Owned("1".to_owned()))),
+                format!("{:?}", Literal::Boolean(true)),
+                format!("{:?}", Literal::Number(Cow::Owned("1".to_owned()))),
             )
             .into(),
             "SELECT * FROM Arith WHERE TRUE + 1 = 1",
         ),
+        (
+            EvaluateError::BooleanTypeRequired(format!(
+                "{:?}",
+                Literal::Text(Cow::Owned("hello".to_owned()))
+            ))
+            .into(),
+            r#"SELECT * FROM Arith WHERE TRUE AND "hello""#,
+        ),
+        (
+            EvaluateError::BooleanTypeRequired(format!("{:?}", Value::Str("A".to_owned()))).into(),
+            "SELECT * FROM Arith WHERE name AND id",
+        ),
     ];
 
     for (error, sql) in test_cases.into_iter() {