-
-
Notifications
You must be signed in to change notification settings - Fork 500
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hashable Value #1254
Comments
@ikrivosheev what's your thought on this design? |
@tyt2y3 can you explain, why we need |
The use case in SeaORM / Seaography was that we'd basically want to group objects by primary keys. Say we have 1->N relationship for Entity A & B, and we selected a list of : A.id, B.* and we now want to use a HashMap to group all B belonging to A by primary key. Right now we convert the primary key to string, which works, but is inefficient. |
@tyt2y3, now i understand, thank you! Well, why do you want to implement this in SeaQuery? I think this can be a part of SeaORM. If we want to change something in the future it will be easier do this in SeaORM. And SeaORM can also control this. |
Yeah can live in SeaORM as well. No preference on that. |
Why we just don't implement Hash for Value ? impl std::hash::Hash for Value {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
match self {
Self::Bool(value) => {
value.hash(state)
},
Self::TinyInt(value) => {
value.hash(state)
},
Self::SmallInt(value) => {
value.hash(state)
},
Self::Int(value) => {
value.hash(state)
},
Self::BigInt(value) => {
value.hash(state)
},
Self::TinyUnsigned(value) => {
value.hash(state)
},
Self::SmallUnsigned(value) => {
value.hash(state)
},
Self::Unsigned(value) => {
value.hash(state)
},
Self::BigUnsigned(value) => {
value.hash(state)
},
Self::Float(value) => {
let value = format!("{:?}", value);
value.hash(state)
},
Self::Double(value) => {
let value = format!("{:?}", value);
value.hash(state)
},
Self::String(value) => {
value.hash(state)
},
Self::Char(value) => {
value.hash(state)
},
Self::Bytes(value) => {
value.hash(state)
},
#[cfg(feature = "with-json")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-json")))]
Self::Json(value) => {
value.hash(state)
},
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDate(value) => {
value.hash(state)
},
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoTime(value) => {
value.hash(state)
},
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTime(value) => {
value.hash(state)
},
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTimeUtc(value) => {
value.hash(state)
},
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTimeLocal(value) => {
value.hash(state)
},
#[cfg(feature = "with-chrono")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-chrono")))]
Self::ChronoDateTimeWithTimeZone(value) => {
value.hash(state)
},
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeDate(value) => {
value.hash(state)
},
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeTime(value) => {
value.hash(state)
},
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeDateTime(value) => {
value.hash(state)
},
#[cfg(feature = "with-time")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-time")))]
Self::TimeDateTimeWithTimeZone(value) => {
value.hash(state)
},
#[cfg(feature = "with-uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-uuid")))]
Self::Uuid(value) => {
value.hash(state)
},
#[cfg(feature = "with-rust_decimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-rust_decimal")))]
Self::Decimal(value) => {
value.hash(state)
},
#[cfg(feature = "with-bigdecimal")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-bigdecimal")))]
Self::BigDecimal(value) => {
value.hash(state)
},
#[cfg(feature = "postgres-array")]
#[cfg_attr(docsrs, doc(cfg(feature = "postgres-array")))]
Self::Array(value) => {
value.hash(state)
},
#[cfg(feature = "with-ipnetwork")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-ipnetwork")))]
Self::IpNetwork(value) => {
value.hash(state)
},
#[cfg(feature = "with-mac_address")]
#[cfg_attr(docsrs, doc(cfg(feature = "with-mac_address")))]
Self::MacAddress(value) => {
value.hash(state)
},
}
}
} The f32 and f64 needs some work |
That would do, although we can only put this inside sea-query (because of orphan rule) |
Should I open a pull request? |
And we'd need to impl |
Sometimes (#1238) we need to use the
Value
as HashKey, but we cannot implHash
andEq
forValue
. The only thing preventing this is f32/f64.So I propose we make a new enum with a subset of Value variants (and also cannot be null). To reduce the maintainence burden, I think realistically we only need to consider the Rust built-in types (with the exception of UUID because it is likely to be used as primary key):
and a few conversion functions:
The text was updated successfully, but these errors were encountered: