Skip to content

Commit e44a49b

Browse files
authored
feat: add Int8 data type support (#9)
1 parent 4bec997 commit e44a49b

3 files changed

Lines changed: 166 additions & 109 deletions

File tree

src/common/mod.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub mod value_generator;
3232
/// inside `GeneartedValue` type.
3333
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3434
pub enum FuzzerDataType {
35+
Int8,
3536
Int32,
3637
Int64,
3738
UInt32,
@@ -57,6 +58,7 @@ impl FuzzerDataType {
5758
/// Convert fuzzer data type to DataFusion data type
5859
pub fn to_datafusion_type(&self) -> DataType {
5960
match self {
61+
FuzzerDataType::Int8 => DataType::Int8,
6062
FuzzerDataType::Int32 => DataType::Int32,
6163
FuzzerDataType::Int64 => DataType::Int64,
6264
FuzzerDataType::UInt32 => DataType::UInt32,
@@ -90,6 +92,7 @@ impl FuzzerDataType {
9092
/// Convert DataFusion data type to fuzzer data type (if supported)
9193
pub fn from_datafusion_type(data_type: &DataType) -> Option<Self> {
9294
match data_type {
95+
DataType::Int8 => Some(FuzzerDataType::Int8),
9396
DataType::Int32 => Some(FuzzerDataType::Int32),
9497
DataType::Int64 => Some(FuzzerDataType::Int64),
9598
DataType::UInt32 => Some(FuzzerDataType::UInt32),
@@ -119,6 +122,7 @@ impl FuzzerDataType {
119122
/// Get the display name for column naming
120123
pub fn display_name(&self) -> &'static str {
121124
match self {
125+
FuzzerDataType::Int8 => "int8",
122126
FuzzerDataType::Int32 => "int32",
123127
FuzzerDataType::Int64 => "int64",
124128
FuzzerDataType::UInt32 => "uint32",
@@ -137,7 +141,8 @@ impl FuzzerDataType {
137141

138142
pub fn is_numeric(&self) -> bool {
139143
match self {
140-
FuzzerDataType::Int32
144+
FuzzerDataType::Int8
145+
| FuzzerDataType::Int32
141146
| FuzzerDataType::Int64
142147
| FuzzerDataType::UInt32
143148
| FuzzerDataType::UInt64
@@ -159,7 +164,8 @@ impl FuzzerDataType {
159164
| FuzzerDataType::Time64Nanosecond
160165
| FuzzerDataType::Timestamp
161166
| FuzzerDataType::IntervalMonthDayNano => true,
162-
FuzzerDataType::Int32
167+
FuzzerDataType::Int8
168+
| FuzzerDataType::Int32
163169
| FuzzerDataType::Int64
164170
| FuzzerDataType::UInt32
165171
| FuzzerDataType::UInt64
@@ -180,6 +186,7 @@ impl FuzzerDataType {
180186
/// Convert to SQL type string for CREATE TABLE statements
181187
pub fn to_sql_type(&self) -> &'static str {
182188
match self {
189+
FuzzerDataType::Int8 => "TINYINT",
183190
FuzzerDataType::Int32 => "INT",
184191
FuzzerDataType::Int64 => "BIGINT",
185192
FuzzerDataType::UInt32 => "INT UNSIGNED",
@@ -215,6 +222,7 @@ static AVAILABLE_DATA_TYPES: OnceLock<Vec<FuzzerDataType>> = OnceLock::new();
215222
pub fn init_available_data_types() {
216223
AVAILABLE_DATA_TYPES.get_or_init(|| {
217224
vec![
225+
FuzzerDataType::Int8,
218226
FuzzerDataType::Int32,
219227
FuzzerDataType::Int64,
220228
FuzzerDataType::UInt32,
@@ -377,6 +385,21 @@ mod tests {
377385
use super::*;
378386
use crate::common::rng::rng_from_seed;
379387

388+
#[test]
389+
fn test_int8_type_properties() {
390+
let int8_type = FuzzerDataType::Int8;
391+
392+
assert_eq!(int8_type.to_datafusion_type(), DataType::Int8);
393+
assert_eq!(
394+
FuzzerDataType::from_datafusion_type(&DataType::Int8),
395+
Some(FuzzerDataType::Int8)
396+
);
397+
assert_eq!(int8_type.display_name(), "int8");
398+
assert_eq!(int8_type.to_sql_type(), "TINYINT");
399+
assert!(int8_type.is_numeric());
400+
assert!(!int8_type.is_time());
401+
}
402+
380403
#[test]
381404
fn test_simplified_decimal_type() {
382405
// Test that the simplified Decimal type works correctly

src/common/value_generator.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::sync::Arc;
66
/// Raw value representation for generated data
77
#[derive(Debug, Clone)]
88
pub enum GeneratedValue {
9+
Int8(i8),
910
Int32(i32),
1011
Int64(i64),
1112
UInt32(u32),
@@ -60,6 +61,11 @@ pub fn generate_value(
6061
}
6162

6263
match fuzzer_type {
64+
FuzzerDataType::Int8 => {
65+
let value = rng.random_range(config.int_range.0 as i8..=config.int_range.1 as i8);
66+
GeneratedValue::Int8(value)
67+
}
68+
6369
FuzzerDataType::Int32 => {
6470
let value = rng.random_range(config.int_range.0..=config.int_range.1);
6571
GeneratedValue::Int32(value)
@@ -190,6 +196,7 @@ impl GeneratedValue {
190196
/// Convert to SQL string representation
191197
pub fn to_sql_string(&self) -> String {
192198
match self {
199+
GeneratedValue::Int8(v) => v.to_string(),
193200
GeneratedValue::Int32(v) => v.to_string(),
194201
GeneratedValue::Int64(v) => v.to_string(),
195202
GeneratedValue::UInt32(v) => v.to_string(),
@@ -341,6 +348,7 @@ impl GeneratedValue {
341348
use datafusion::scalar::ScalarValue;
342349

343350
match self {
351+
GeneratedValue::Int8(v) => ScalarValue::Int8(Some(*v)),
344352
GeneratedValue::Int32(v) => ScalarValue::Int32(Some(*v)),
345353
GeneratedValue::Int64(v) => ScalarValue::Int64(Some(*v)),
346354
GeneratedValue::UInt32(v) => ScalarValue::UInt32(Some(*v)),
@@ -509,6 +517,32 @@ mod tests {
509517
use super::*;
510518
use crate::common::rng::rng_from_seed;
511519

520+
#[test]
521+
fn test_int8_value_generation_and_conversions() {
522+
let mut rng = rng_from_seed(42);
523+
let config = ValueGenerationConfig {
524+
nullable: false,
525+
int_range: (-128, 127),
526+
..ValueGenerationConfig::default()
527+
};
528+
529+
for _ in 0..100 {
530+
let value = generate_value(&mut rng, &FuzzerDataType::Int8, &config);
531+
532+
match &value {
533+
GeneratedValue::Int8(v) => {
534+
assert!((-128..=127).contains(v));
535+
assert_eq!(value.to_sql_string(), v.to_string());
536+
assert_eq!(
537+
value.to_scalar_value(),
538+
datafusion::scalar::ScalarValue::Int8(Some(*v))
539+
);
540+
}
541+
other => panic!("Expected Int8 value, got: {other:?}"),
542+
}
543+
}
544+
}
545+
512546
#[test]
513547
fn test_cached_config_in_runtime_context() {
514548
// Test that RuntimeContext has the expected cached config

0 commit comments

Comments
 (0)