Pre: ensure that constant floats end up as floats in SQL, never integers.

This commit is contained in:
Richard Newman 2017-06-13 17:26:53 -07:00
parent 8ec24f01f6
commit 5d5e85bcba
2 changed files with 15 additions and 4 deletions

View file

@ -226,7 +226,7 @@ fn test_unknown_attribute_double_value() {
// In general, doubles _could_ be 1.0, which might match a boolean or a ref. Set tag = 5 to
// make sure we only match numbers.
assert_eq!(sql, "SELECT DISTINCT `datoms00`.e AS `?x` FROM `datoms` AS `datoms00` WHERE `datoms00`.v = 9.95 AND `datoms00`.value_type_tag = 5");
assert_eq!(sql, "SELECT DISTINCT `datoms00`.e AS `?x` FROM `datoms` AS `datoms00` WHERE `datoms00`.v = 9.95e0 AND `datoms00`.value_type_tag = 5");
assert_eq!(args, vec![]);
}
@ -295,7 +295,7 @@ fn test_numeric_gte_known_attribute() {
let schema = prepopulated_typed_schema(ValueType::Double);
let query = r#"[:find ?x :where [?x :foo/bar ?y] [(>= ?y 12.9)]]"#;
let SQLQuery { sql, args } = translate(&schema, query);
assert_eq!(sql, "SELECT DISTINCT `datoms00`.e AS `?x` FROM `datoms` AS `datoms00` WHERE `datoms00`.a = 99 AND `datoms00`.v >= 12.9");
assert_eq!(sql, "SELECT DISTINCT `datoms00`.e AS `?x` FROM `datoms` AS `datoms00` WHERE `datoms00`.a = 99 AND `datoms00`.v >= 1.29e1");
assert_eq!(args, vec![]);
}

View file

@ -160,7 +160,14 @@ impl QueryBuilder for SQLiteQueryBuilder {
&Ref(entid) => self.push_sql(entid.to_string().as_str()),
&Boolean(v) => self.push_sql(if v { "1" } else { "0" }),
&Long(v) => self.push_sql(v.to_string().as_str()),
&Double(OrderedFloat(v)) => self.push_sql(v.to_string().as_str()),
&Double(OrderedFloat(v)) => {
// Rust's floats print without a trailing '.' in some cases.
// https://github.com/rust-lang/rust/issues/30967
// We format with 'e' -- scientific notation -- so that SQLite treats them as
// floats and not integers. This is most noticeable for fulltext scores, which
// will currently (2017-06) always be 0, and need to round-trip as doubles.
self.push_sql(format!("{:e}", v).as_str());
},
&Instant(dt) => {
self.push_sql(format!("{}", dt.to_micros()).as_str()); // TODO: argument instead?
},
@ -260,9 +267,13 @@ mod tests {
s.push_static_arg(string_arg("frobnicate"));
s.push_sql(" OR ");
s.push_static_arg(string_arg("swoogle"));
s.push_sql(" OR ");
s.push_identifier("bar").unwrap();
s.push_sql(" = ");
s.push_typed_value(&TypedValue::Double(1.0.into())).unwrap();
let q = s.finish();
assert_eq!(q.sql.as_str(), "SELECT `foo` WHERE `bar` = $v0 OR $v1");
assert_eq!(q.sql.as_str(), "SELECT `foo` WHERE `bar` = $v0 OR $v1 OR `bar` = 1e0");
assert_eq!(q.args,
vec![("$v0".to_string(), string_arg("frobnicate")),
("$v1".to_string(), string_arg("swoogle"))]);