use std::cmp::Ordering;
use crate::sql_value::SqlValue;
impl PartialEq for SqlValue {
fn eq(&self, other: &Self) -> bool {
use SqlValue::*;
match (self, other) {
(Null, Null) => true,
(Null, _) | (_, Null) => false,
(Integer(a), Integer(b)) => a == b,
(Smallint(a), Smallint(b)) => a == b,
(Bigint(a), Bigint(b)) => a == b,
(Unsigned(a), Unsigned(b)) => a == b,
(Float(a), Float(b)) => {
if a.is_nan() && b.is_nan() {
true
} else {
a == b
}
}
(Real(a), Real(b)) => {
if a.is_nan() && b.is_nan() {
true
} else {
a == b
}
}
(Double(a), Double(b)) | (Numeric(a), Numeric(b)) => {
if a.is_nan() && b.is_nan() {
true
} else {
a == b
}
}
(Character(a), Character(b)) => a == b,
(Varchar(a), Varchar(b)) => a == b,
(Character(a), Varchar(b)) | (Varchar(a), Character(b)) => a == b,
(Boolean(a), Boolean(b)) => a == b,
(Date(a), Date(b)) => a == b,
(Time(a), Time(b)) => a == b,
(Timestamp(a), Timestamp(b)) => a == b,
(Interval(a), Interval(b)) => a == b,
(Vector(a), Vector(b)) => a == b,
(Blob(a), Blob(b)) => a == b,
_ => false,
}
}
}
#[allow(clippy::non_canonical_partial_ord_impl)]
impl PartialOrd for SqlValue {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
use SqlValue::*;
match (self, other) {
(Null, _) | (_, Null) => None,
(Integer(a), Integer(b)) => a.partial_cmp(b),
(Smallint(a), Smallint(b)) => a.partial_cmp(b),
(Bigint(a), Bigint(b)) => a.partial_cmp(b),
(Unsigned(a), Unsigned(b)) => a.partial_cmp(b),
(Float(a), Float(b)) => a.partial_cmp(b),
(Real(a), Real(b)) => a.partial_cmp(b),
(Double(a), Double(b)) => a.partial_cmp(b),
(Character(a), Character(b)) => a.partial_cmp(b),
(Varchar(a), Varchar(b)) => a.partial_cmp(b),
(Character(a), Varchar(b)) | (Varchar(a), Character(b)) => a.partial_cmp(b),
(Numeric(a), Numeric(b)) => a.partial_cmp(b),
(Boolean(a), Boolean(b)) => a.partial_cmp(b),
(Date(a), Date(b)) => a.partial_cmp(b),
(Time(a), Time(b)) => a.partial_cmp(b),
(Timestamp(a), Timestamp(b)) => a.partial_cmp(b),
(Interval(a), Interval(b)) => a.partial_cmp(b),
(Vector(a), Vector(b)) => a.partial_cmp(b),
(Blob(a), Blob(b)) => a.partial_cmp(b),
_ => None,
}
}
}
impl Eq for SqlValue {}
impl Ord for SqlValue {
fn cmp(&self, other: &Self) -> Ordering {
use SqlValue::*;
match (self, other) {
(Null, Null) => return Ordering::Equal,
(Null, _) => return Ordering::Less,
(_, Null) => return Ordering::Greater,
_ => {}
}
if let Some(ordering) = self.partial_cmp(other) {
return ordering;
}
match (self, other) {
(Float(a), Float(b)) => {
if a.is_nan() && b.is_nan() {
Ordering::Equal
} else if a.is_nan() {
Ordering::Greater
} else {
Ordering::Less }
}
(Real(a), Real(b)) => {
if a.is_nan() && b.is_nan() {
Ordering::Equal
} else if a.is_nan() {
Ordering::Greater
} else {
Ordering::Less
}
}
(Double(a), Double(b)) | (Numeric(a), Numeric(b)) => {
if a.is_nan() && b.is_nan() {
Ordering::Equal
} else if a.is_nan() {
Ordering::Greater
} else {
Ordering::Less
}
}
_ => {
fn type_tag(val: &SqlValue) -> u8 {
match val {
Integer(_) => 1,
Smallint(_) => 2,
Bigint(_) => 3,
Unsigned(_) => 4,
Numeric(_) => 5,
Float(_) => 6,
Real(_) => 7,
Double(_) => 8,
Character(_) => 9,
Varchar(_) => 10,
Boolean(_) => 11,
Date(_) => 12,
Time(_) => 13,
Timestamp(_) => 14,
Interval(_) => 15,
Vector(_) => 16,
Blob(_) => 17,
Null => 0, }
}
type_tag(self).cmp(&type_tag(other))
}
}
}
}