Skip to content

Commit

Permalink
tidb_query: fix converting bytes to bool (tikv#7486)
Browse files Browse the repository at this point in the history
Signed-off-by: zhongzc <zhongzc_arch@outlook.com>
  • Loading branch information
zhongzc committed Apr 20, 2020
1 parent 7887c24 commit 4175d68
Showing 1 changed file with 64 additions and 3 deletions.
67 changes: 64 additions & 3 deletions components/tidb_query_datatype/src/codec/data_type/mod.rs
Expand Up @@ -13,9 +13,9 @@ pub use crate::codec::mysql::{Decimal, Duration, Json, JsonType, Time as DateTim
pub use self::scalar::{ScalarValue, ScalarValueRef};
pub use self::vector::{VectorValue, VectorValueExt};

use crate::{EvalType, FieldTypeTp};
use crate::EvalType;

use crate::codec::convert::ToInt;
use crate::codec::convert::ConvertTo;
use crate::expr::EvalContext;
use tidb_query_common::error::Result;

Expand Down Expand Up @@ -43,7 +43,7 @@ impl AsMySQLBool for Real {
impl AsMySQLBool for Bytes {
#[inline]
fn as_mysql_bool(&self, context: &mut EvalContext) -> Result<bool> {
Ok(!self.is_empty() && self.to_int(context, FieldTypeTp::LongLong)? != 0)
Ok(!self.is_empty() && ConvertTo::<f64>::convert(self, context)? != 0f64)
}
}

Expand Down Expand Up @@ -122,3 +122,64 @@ impl_evaluable_type! { Bytes }
impl_evaluable_type! { DateTime }
impl_evaluable_type! { Duration }
impl_evaluable_type! { Json }

#[cfg(test)]
mod tests {
use super::*;
use std::f64;

#[test]
fn test_bytes_to_bool() {
let tests: Vec<(&'static [u8], Option<bool>)> = vec![
(b"", Some(false)),
(b" 23", Some(true)),
(b"-1", Some(true)),
(b"1.11", Some(true)),
(b"1.11.00", None),
(b"xx", None),
(b"0x00", None),
(b"11.xx", None),
(b"xx.11", None),
(
b".0000000000000000000000000000000000000000000000000000001",
Some(true),
),
];

let mut ctx = EvalContext::default();
for (i, (v, expect)) in tests.into_iter().enumerate() {
let rb: Result<bool> = v.to_vec().as_mysql_bool(&mut ctx);
match expect {
Some(val) => {
assert_eq!(rb.unwrap(), val);
}
None => {
assert!(
rb.is_err(),
"index: {}, {:?} should not be converted, but got: {:?}",
i,
v,
rb
);
}
}
}

// test overflow
let mut ctx = EvalContext::default();
let val: Result<bool> = f64::INFINITY
.to_string()
.as_bytes()
.to_vec()
.as_mysql_bool(&mut ctx);
assert!(val.is_err());

let mut ctx = EvalContext::default();
let val: Result<bool> = f64::NEG_INFINITY
.to_string()
.as_bytes()
.to_vec()
.as_mysql_bool(&mut ctx);
assert!(val.is_err());
}
}

0 comments on commit 4175d68

Please sign in to comment.