mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2025-12-22 22:20:02 +00:00
fix: fill NULL based on row_count (#765)
* fix: fill NULL based on row_count Signed-off-by: Ruihang Xia <waynestxia@gmail.com> * simplify code Signed-off-by: Ruihang Xia <waynestxia@gmail.com> * fix: replace set_len with resize Signed-off-by: Ruihang Xia <waynestxia@gmail.com> Signed-off-by: Ruihang Xia <waynestxia@gmail.com>
This commit is contained in:
@@ -186,6 +186,7 @@ impl SelectResultDisplayer<'_> {
|
||||
ColumnDataType::from_i32(col.datatype).unwrap(),
|
||||
col.values.clone().unwrap(),
|
||||
col.null_mask.clone(),
|
||||
row_count,
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@@ -50,6 +50,7 @@ where
|
||||
type Item = String;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
// iter the null_mask first
|
||||
if let Some(is_null) = self.null_iter.next() {
|
||||
if *is_null.as_ref() {
|
||||
Some(NULL_DATA_PLACEHOLDER.to_string())
|
||||
@@ -63,7 +64,7 @@ where
|
||||
}
|
||||
|
||||
macro_rules! build_nullable_iter {
|
||||
($null_iter:ident, $data_iter:expr) => {
|
||||
($null_iter:ident, $data_iter:expr, $row_count:ident) => {
|
||||
NullableColumnIter {
|
||||
null_iter: $null_iter,
|
||||
data_iter: $data_iter,
|
||||
@@ -76,42 +77,85 @@ pub fn values_to_string(
|
||||
data_type: ColumnDataType,
|
||||
values: Values,
|
||||
null_mask: Vec<u8>,
|
||||
row_count: usize,
|
||||
) -> Vec<String> {
|
||||
let bit_vec = BitVec::from_vec(null_mask);
|
||||
let mut bit_vec = BitVec::from_vec(null_mask);
|
||||
bit_vec.resize(row_count, false);
|
||||
let null_iter = bit_vec.iter();
|
||||
match data_type {
|
||||
ColumnDataType::Int64 => build_nullable_iter!(null_iter, values.i64_values.into_iter()),
|
||||
ColumnDataType::Float64 => build_nullable_iter!(null_iter, values.f64_values.into_iter()),
|
||||
ColumnDataType::String => build_nullable_iter!(null_iter, values.string_values.into_iter()),
|
||||
ColumnDataType::Boolean => build_nullable_iter!(null_iter, values.bool_values.into_iter()),
|
||||
ColumnDataType::Int8 => build_nullable_iter!(null_iter, values.i8_values.into_iter()),
|
||||
ColumnDataType::Int16 => build_nullable_iter!(null_iter, values.i16_values.into_iter()),
|
||||
ColumnDataType::Int32 => build_nullable_iter!(null_iter, values.i32_values.into_iter()),
|
||||
ColumnDataType::Uint8 => build_nullable_iter!(null_iter, values.u8_values.into_iter()),
|
||||
ColumnDataType::Uint16 => build_nullable_iter!(null_iter, values.u16_values.into_iter()),
|
||||
ColumnDataType::Uint32 => build_nullable_iter!(null_iter, values.u32_values.into_iter()),
|
||||
ColumnDataType::Uint64 => build_nullable_iter!(null_iter, values.u64_values.into_iter()),
|
||||
ColumnDataType::Float32 => build_nullable_iter!(null_iter, values.f32_values.into_iter()),
|
||||
ColumnDataType::Int64 => {
|
||||
build_nullable_iter!(null_iter, values.i64_values.into_iter(), row_count)
|
||||
}
|
||||
ColumnDataType::Float64 => {
|
||||
build_nullable_iter!(null_iter, values.f64_values.into_iter(), row_count)
|
||||
}
|
||||
ColumnDataType::String => {
|
||||
build_nullable_iter!(null_iter, values.string_values.into_iter(), row_count)
|
||||
}
|
||||
ColumnDataType::Boolean => {
|
||||
build_nullable_iter!(null_iter, values.bool_values.into_iter(), row_count)
|
||||
}
|
||||
ColumnDataType::Int8 => {
|
||||
build_nullable_iter!(null_iter, values.i8_values.into_iter(), row_count)
|
||||
}
|
||||
ColumnDataType::Int16 => {
|
||||
build_nullable_iter!(null_iter, values.i16_values.into_iter(), row_count)
|
||||
}
|
||||
ColumnDataType::Int32 => {
|
||||
build_nullable_iter!(null_iter, values.i32_values.into_iter(), row_count)
|
||||
}
|
||||
ColumnDataType::Uint8 => {
|
||||
build_nullable_iter!(null_iter, values.u8_values.into_iter(), row_count)
|
||||
}
|
||||
ColumnDataType::Uint16 => {
|
||||
build_nullable_iter!(null_iter, values.u16_values.into_iter(), row_count)
|
||||
}
|
||||
ColumnDataType::Uint32 => {
|
||||
build_nullable_iter!(null_iter, values.u32_values.into_iter(), row_count)
|
||||
}
|
||||
ColumnDataType::Uint64 => {
|
||||
build_nullable_iter!(null_iter, values.u64_values.into_iter(), row_count)
|
||||
}
|
||||
ColumnDataType::Float32 => {
|
||||
build_nullable_iter!(null_iter, values.f32_values.into_iter(), row_count)
|
||||
}
|
||||
ColumnDataType::Binary => build_nullable_iter!(
|
||||
null_iter,
|
||||
values
|
||||
.binary_values
|
||||
.into_iter()
|
||||
.map(|val| format!("{:?}", val))
|
||||
.map(|val| format!("{:?}", val)),
|
||||
row_count
|
||||
),
|
||||
ColumnDataType::Datetime => build_nullable_iter!(null_iter, values.i64_values.into_iter()),
|
||||
ColumnDataType::Date => build_nullable_iter!(null_iter, values.i32_values.into_iter()),
|
||||
ColumnDataType::Datetime => {
|
||||
build_nullable_iter!(null_iter, values.i64_values.into_iter(), row_count)
|
||||
}
|
||||
ColumnDataType::Date => {
|
||||
build_nullable_iter!(null_iter, values.i32_values.into_iter(), row_count)
|
||||
}
|
||||
ColumnDataType::TimestampSecond => {
|
||||
build_nullable_iter!(null_iter, values.ts_second_values.into_iter())
|
||||
build_nullable_iter!(null_iter, values.ts_second_values.into_iter(), row_count)
|
||||
}
|
||||
ColumnDataType::TimestampMillisecond => {
|
||||
build_nullable_iter!(null_iter, values.ts_millisecond_values.into_iter())
|
||||
build_nullable_iter!(
|
||||
null_iter,
|
||||
values.ts_millisecond_values.into_iter(),
|
||||
row_count
|
||||
)
|
||||
}
|
||||
ColumnDataType::TimestampMicrosecond => {
|
||||
build_nullable_iter!(null_iter, values.ts_microsecond_values.into_iter())
|
||||
build_nullable_iter!(
|
||||
null_iter,
|
||||
values.ts_microsecond_values.into_iter(),
|
||||
row_count
|
||||
)
|
||||
}
|
||||
ColumnDataType::TimestampNanosecond => {
|
||||
build_nullable_iter!(null_iter, values.ts_nanosecond_values.into_iter())
|
||||
build_nullable_iter!(
|
||||
null_iter,
|
||||
values.ts_nanosecond_values.into_iter(),
|
||||
row_count
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -183,7 +227,7 @@ mod test {
|
||||
..Default::default()
|
||||
};
|
||||
let null_mask = vec![0b00100000, 0b00000010];
|
||||
let result = values_to_string(data_type, values, null_mask);
|
||||
let result = values_to_string(data_type, values, null_mask, 10);
|
||||
let expected: Vec<String> = ["1", "2", "3", "4", "5", "NULL", "7", "8", "9", "NULL"]
|
||||
.into_iter()
|
||||
.map(String::from)
|
||||
@@ -191,4 +235,55 @@ mod test {
|
||||
|
||||
assert_eq!(result, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_display_nullable_column_exceed_length() {
|
||||
let data_type = ColumnDataType::Int64;
|
||||
let values = Values {
|
||||
i64_values: vec![1, 2, 3, 4, 5, 7, 8, 9],
|
||||
..Default::default()
|
||||
};
|
||||
let null_mask = vec![0b00100000, 0b11111110, 0b0001111];
|
||||
let result = values_to_string(data_type, values, null_mask, 20);
|
||||
let expected: Vec<String> = [
|
||||
"1", "2", "3", "4", "5", "NULL", "7", "8", "9", "NULL", "NULL", "NULL", "NULL", "NULL",
|
||||
"NULL", "NULL", "NULL", "NULL", "NULL", "NULL",
|
||||
]
|
||||
.into_iter()
|
||||
.map(String::from)
|
||||
.collect();
|
||||
|
||||
assert_eq!(result, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_display_nullable_column_no_vacancy() {
|
||||
let data_type = ColumnDataType::Int64;
|
||||
let values = Values {
|
||||
i64_values: vec![1, 2, 3, 4, 5, 7, 8, 9],
|
||||
..Default::default()
|
||||
};
|
||||
let null_mask = vec![0b00000000, 0b00000000];
|
||||
let result = values_to_string(data_type, values, null_mask, 8);
|
||||
let expected: Vec<String> = ["1", "2", "3", "4", "5", "7", "8", "9"]
|
||||
.into_iter()
|
||||
.map(String::from)
|
||||
.collect();
|
||||
|
||||
assert_eq!(result, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_display_nullable_column_shorter_length() {
|
||||
let data_type = ColumnDataType::Int64;
|
||||
let values = Values {
|
||||
i64_values: vec![1, 2, 3, 4, 5, 7, 8, 9],
|
||||
..Default::default()
|
||||
};
|
||||
let null_mask = vec![0b00000000, 0b00000000];
|
||||
let result = values_to_string(data_type, values, null_mask, 1);
|
||||
let expected: Vec<String> = ["1"].into_iter().map(String::from).collect();
|
||||
|
||||
assert_eq!(result, expected);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user