Improve performance of internal value conversion

This commit is contained in:
Tobie Morgan Hitchcock 2022-04-07 15:44:55 +01:00
parent 27a01bec08
commit a41e52098b
2 changed files with 64 additions and 36 deletions
lib/src
doc
sql/value

View file

@ -5,7 +5,6 @@ use crate::dbs::Statement;
use crate::dbs::Transaction;
use crate::doc::Document;
use crate::err::Error;
use crate::sql::kind::Kind;
use crate::sql::permission::Permission;
use crate::sql::value::Value;
@ -38,33 +37,7 @@ impl<'a> Document<'a> {
}
// Check for a TYPE clause
if let Some(kind) = &fd.kind {
val = match kind {
Kind::Any => val,
Kind::Bool => val.make_bool(),
Kind::Int => val.make_int(),
Kind::Float => val.make_float(),
Kind::Decimal => val.make_decimal(),
Kind::Number => val.make_number(),
Kind::String => val.make_strand(),
Kind::Datetime => val.make_datetime(),
Kind::Duration => val.make_duration(),
Kind::Array => match val {
Value::Array(_) => val,
_ => Value::None,
},
Kind::Object => match val {
Value::Object(_) => val,
_ => Value::None,
},
Kind::Record(t) => match val.is_type_record(t) {
true => val,
_ => Value::None,
},
Kind::Geometry(t) => match val.is_type_geometry(t) {
true => val,
_ => Value::None,
},
}
val = val.convert_to(kind);
}
// Check for a ASSERT clause
if let Some(expr) = &fd.assert {

View file

@ -14,6 +14,7 @@ use crate::sql::function::{function, Function};
use crate::sql::geometry::{geometry, Geometry};
use crate::sql::id::Id;
use crate::sql::idiom::{idiom, Idiom};
use crate::sql::kind::Kind;
use crate::sql::model::{model, Model};
use crate::sql::number::{number, Number};
use crate::sql::object::{object, Object};
@ -669,35 +670,89 @@ impl Value {
// -----------------------------------
pub fn make_bool(self) -> Value {
self.is_truthy().into()
match self {
Value::True | Value::False => self,
_ => self.is_truthy().into(),
}
}
pub fn make_int(self) -> Value {
self.as_int().into()
match self {
Value::Number(Number::Int(_)) => self,
_ => self.as_int().into(),
}
}
pub fn make_float(self) -> Value {
self.as_float().into()
match self {
Value::Number(Number::Float(_)) => self,
_ => self.as_float().into(),
}
}
pub fn make_decimal(self) -> Value {
self.as_decimal().into()
match self {
Value::Number(Number::Decimal(_)) => self,
_ => self.as_decimal().into(),
}
}
pub fn make_number(self) -> Value {
self.as_number().into()
match self {
Value::Number(_) => self,
_ => self.as_number().into(),
}
}
pub fn make_strand(self) -> Value {
self.as_strand().into()
match self {
Value::Strand(_) => self,
_ => self.as_strand().into(),
}
}
pub fn make_datetime(self) -> Value {
self.as_datetime().into()
match self {
Value::Datetime(_) => self,
_ => self.as_datetime().into(),
}
}
pub fn make_duration(self) -> Value {
self.as_duration().into()
match self {
Value::Duration(_) => self,
_ => self.as_duration().into(),
}
}
pub fn convert_to(self, kind: &Kind) -> Value {
match kind {
Kind::Any => self,
Kind::Bool => self.make_bool(),
Kind::Int => self.make_int(),
Kind::Float => self.make_float(),
Kind::Decimal => self.make_decimal(),
Kind::Number => self.make_number(),
Kind::String => self.make_strand(),
Kind::Datetime => self.make_datetime(),
Kind::Duration => self.make_duration(),
Kind::Array => match self {
Value::Array(_) => self,
_ => Value::None,
},
Kind::Object => match self {
Value::Object(_) => self,
_ => Value::None,
},
Kind::Record(t) => match self.is_type_record(t) {
true => self,
_ => Value::None,
},
Kind::Geometry(t) => match self.is_type_geometry(t) {
true => self,
_ => Value::None,
},
}
}
// -----------------------------------