Skip to content

Commit

Permalink
Implement i8 and detect types correctly in MySQL (#454)
Browse files Browse the repository at this point in the history
* Update dependencies

* Add support for i8 subtype

* Add and fix MySQL tests

* Revert local testing, add note

* Cleanup

* Handle mediumtext in MySQL gracefully

* blobs

* Use correct dependencies from upstream

* Undo temporary local testing change

* Lint
  • Loading branch information
tom-stytch authored Sep 25, 2024
1 parent 7b8c892 commit fdbecd2
Show file tree
Hide file tree
Showing 13 changed files with 251 additions and 147 deletions.
8 changes: 8 additions & 0 deletions core/src/graph/number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ macro_rules! any_range_int_impl {
}
}

any_range_int_impl! { u8 }
any_range_int_impl! { u16 }
any_range_int_impl! { u32 }
any_range_int_impl! { u64 }
Expand Down Expand Up @@ -219,6 +220,7 @@ macro_rules! standard_int_range_step_impl {
}
}

standard_int_range_step_impl! { i8, i16, u8}
standard_int_range_step_impl! { i16, i32, u16}
standard_int_range_step_impl! { i32, i64, u32 }
standard_int_range_step_impl! { u32, u32, u32 }
Expand Down Expand Up @@ -480,6 +482,12 @@ number_node!(
I16Categorical as categorical,
Incrementing as incrementing,
) for i16,
RandomI8 (
I8Range<StandardIntRangeStep<u8, i16>> as range,
I8Constant as constant,
I8Categorical as categorical,
Incrementing as incrementing,
) for i8,
);

#[cfg(test)]
Expand Down
9 changes: 9 additions & 0 deletions core/src/schema/content/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ impl<'de> Deserialize<'de> for ArrayContent {
r.low .unwrap_or_default() .into(),
).map_err(A::Error::custom)?
},
Content::Number(NumberContent::I8(number_content::I8::Range(r))) => {
if r.high.is_none() {
return Err(A::Error::custom("missing high value for array length range"));
}

is_positive(
r.low .unwrap_or_default() .into(),
).map_err(A::Error::custom)?
},
Content::SameAs(_) => {},
Content::Null(_) => return Err(de::Error::custom("array length is missing. Try adding '\"length\": [number]' to the array type where '[number]' is a positive integer")),
Content::Empty(_) => return Err(de::Error::custom("array length is not a constant or number type. Try replacing the '\"length\": {}' with '\"length\": [number]' where '[number]' is a positive integer")),
Expand Down
29 changes: 27 additions & 2 deletions core/src/schema/content/number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::hash::{Hash, Hasher};

use super::Categorical;

use crate::graph::number::{RandomF32, RandomI16, RandomI32, RandomU32};
use crate::graph::number::{RandomF32, RandomI16, RandomI32, RandomI8, RandomU32};
use serde::{ser::Serializer, Serialize};

#[derive(Clone, Copy)]
Expand Down Expand Up @@ -205,6 +205,7 @@ impl NumberContent {
match self {
NumberContent::U32(_) => Ok(Self::u32_default_id()),
NumberContent::U64(_) => Ok(Self::u64_default_id()),
NumberContent::I8(_) => Ok(Self::i8_default_id()),
NumberContent::I16(_) => Ok(Self::i16_default_id()),
NumberContent::I32(_) => Ok(Self::i32_default_id()),
NumberContent::I64(_) => Ok(Self::i64_default_id()),
Expand All @@ -221,6 +222,10 @@ impl NumberContent {
NumberContent::U64(number_content::U64::Id(Id::default()))
}

pub fn i8_default_id() -> Self {
NumberContent::I8(number_content::I8::Id(Id::default()))
}

pub fn i16_default_id() -> Self {
NumberContent::I16(number_content::I16::Id(Id::default()))
}
Expand Down Expand Up @@ -372,7 +377,7 @@ macro_rules! derive_hash {
};
}

derive_hash!(i16, i32, u32, i64, u64, f32, f64);
derive_hash!(i8, i16, i32, u32, i64, u64, f32, f64);

number_content!(
#[derive(PartialEq, Hash)]
Expand All @@ -390,6 +395,13 @@ number_content!(
Id(crate::schema::Id<u64>),
},
#[derive(PartialEq, Hash)]
i8[is_i8, default_i8_range] as I8 {
Range(RangeStep<i8>),
Categorical(Categorical<i8>),
Constant(i8),
Id(crate::schema::Id<i8>),
},
#[derive(PartialEq, Hash)]
i16[is_i16, default_i16_range] as I16 {
Range(RangeStep<i16>),
Categorical(Categorical<i16>),
Expand Down Expand Up @@ -490,6 +502,19 @@ impl Compile for NumberContent {
};
random_f32.into()
}
Self::I8(i8_content) => {
let random_i8 = match i8_content {
number_content::I8::Range(range) => RandomI8::range(*range)?,
number_content::I8::Categorical(categorical_content) => {
RandomI8::categorical(categorical_content.clone())
}
number_content::I8::Constant(val) => RandomI8::constant(*val),
number_content::I8::Id(id) => {
RandomI8::incrementing(Incrementing::new_at(id.start_at.unwrap_or(1)))
}
};
random_i8.into()
}
Self::I16(i16_content) => {
let random_i16 = match i16_content {
number_content::I16::Range(range) => RandomI16::range(*range)?,
Expand Down
20 changes: 19 additions & 1 deletion core/src/schema/inference/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use super::{
Content, DateTimeContent, Id, NumberContent, NumberKindExt, ObjectContent, OneOfContent,
RangeStep, StringContent, ValueKindExt,
};
use crate::graph::prelude::content::number_content::{I16, I32, I64};
use crate::graph::prelude::content::number_content::{I16, I32, I64, I8};
use crate::schema::UniqueContent;
use num::Zero;

Expand Down Expand Up @@ -335,6 +335,17 @@ impl MergeStrategy<number_content::I16, i16> for OptionalMergeStrategy {
}
}

impl MergeStrategy<number_content::I8, i8> for OptionalMergeStrategy {
fn try_merge(self, master: &mut number_content::I8, candidate: &i8) -> Result<()> {
match master {
number_content::I8::Range(range) => self.try_merge(range, candidate),
number_content::I8::Categorical(cat) => self.try_merge(cat, candidate),
number_content::I8::Constant(cst) => self.try_merge(cst, candidate),
I8::Id(id) => self.try_merge(id, candidate),
}
}
}

impl MergeStrategy<NumberContent, Number> for OptionalMergeStrategy {
fn try_merge(self, master: &mut NumberContent, value: &Number) -> Result<()> {
match master {
Expand Down Expand Up @@ -383,6 +394,13 @@ impl MergeStrategy<NumberContent, Number> for OptionalMergeStrategy {
todo!()
}
}
NumberContent::I8(i8_content) => {
if let Some(n) = value.as_i64() {
self.try_merge(i8_content, &(n as i8))
} else {
todo!()
}
}
NumberContent::I16(i16_content) => {
if let Some(n) = value.as_i64() {
self.try_merge(i16_content, &(n as i16))
Expand Down
12 changes: 8 additions & 4 deletions synth/src/datasource/mysql_datasource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use rust_decimal::Decimal;
use sqlx::mysql::{MySqlColumn, MySqlPoolOptions, MySqlRow};
use sqlx::{Column, MySql, Pool, Row, TypeInfo};
use std::collections::BTreeMap;
use synth_core::schema::number_content::{F64, I64, U64};
use synth_core::schema::number_content::{F64, I16, I32, I64, I8, U64};
use synth_core::schema::{
ChronoValueType, DateTimeContent, NumberContent, RangeStep, RegexContent, StringContent,
};
Expand Down Expand Up @@ -88,7 +88,8 @@ impl SqlxDataSource for MySqlDataSource {

fn decode_to_content(&self, column_info: &ColumnInfo) -> Result<Content> {
let content = match column_info.data_type.to_lowercase().as_str() {
"char" | "varchar" | "text" | "binary" | "varbinary" | "enum" | "set" => {
"char" | "varchar" | "text" | "binary" | "varbinary" | "enum" | "set"
| "mediumtext" | "blob" => {
let pattern = "[a-zA-Z0-9]{0, {}}".replace(
"{}",
&format!("{}", column_info.character_maximum_length.unwrap_or(1)),
Expand All @@ -97,9 +98,12 @@ impl SqlxDataSource for MySqlDataSource {
RegexContent::pattern(pattern).context("pattern will always compile")?,
))
}
"int" | "integer" | "tinyint" | "smallint" | "mediumint" | "bigint" => {
Content::Number(NumberContent::I64(I64::Range(RangeStep::default())))
"int" | "integer" | "mediumint" => {
Content::Number(NumberContent::I32(I32::Range(RangeStep::default())))
}
"tinyint" => Content::Number(NumberContent::I8(I8::Range(RangeStep::default()))),
"smallint" => Content::Number(NumberContent::I16(I16::Range(RangeStep::default()))),
"bigint" => Content::Number(NumberContent::I64(I64::Range(RangeStep::default()))),
"serial" => Content::Number(NumberContent::U64(U64::Range(RangeStep::default()))),
"float" | "double" | "numeric" | "decimal" => {
Content::Number(NumberContent::F64(F64::Range(RangeStep::default())))
Expand Down
5 changes: 3 additions & 2 deletions synth/testing_harness/mysql/0_hospital_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ create table patients
date_joined date,
address varchar(255),
phone varchar(20),
ssn varchar(12)
);
ssn varchar(12),
freckles tinyint
);
Loading

0 comments on commit fdbecd2

Please sign in to comment.