Skip to content

Commit 28c539c

Browse files
authored
refactor: use a macro for logical vs physical type matching (risingwavelabs#8479)
Signed-off-by: Bugen Zhao <[email protected]>
1 parent e51f639 commit 28c539c

File tree

2 files changed

+63
-49
lines changed

2 files changed

+63
-49
lines changed

src/common/src/types/mod.rs

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,29 +1151,50 @@ impl ScalarImpl {
11511151
}
11521152
}
11531153

1154+
/// `for_all_type_pairs` is a macro that records all logical type (`DataType`) variants and their
1155+
/// corresponding physical type (`ScalarImpl`, `ArrayImpl`, or `ArrayBuilderImpl`) variants.
1156+
///
1157+
/// This is useful for checking whether a physical type is compatible with a logical type.
1158+
#[macro_export]
1159+
macro_rules! for_all_type_pairs {
1160+
($macro:ident) => {
1161+
$macro! {
1162+
{ Boolean, Bool },
1163+
{ Int16, Int16 },
1164+
{ Int32, Int32 },
1165+
{ Int64, Int64 },
1166+
{ Float32, Float32 },
1167+
{ Float64, Float64 },
1168+
{ Varchar, Utf8 },
1169+
{ Bytea, Bytea },
1170+
{ Date, NaiveDate },
1171+
{ Time, NaiveTime },
1172+
{ Timestamp, NaiveDateTime },
1173+
{ Timestamptz, Int64 },
1174+
{ Interval, Interval },
1175+
{ Decimal, Decimal },
1176+
{ Jsonb, Jsonb },
1177+
{ List, List },
1178+
{ Struct, Struct }
1179+
}
1180+
};
1181+
}
1182+
1183+
/// Returns whether the `literal` matches the `data_type`.
11541184
pub fn literal_type_match(data_type: &DataType, literal: Option<&ScalarImpl>) -> bool {
11551185
match literal {
1156-
Some(datum) => {
1157-
matches!(
1158-
(data_type, datum),
1159-
(DataType::Boolean, ScalarImpl::Bool(_))
1160-
| (DataType::Int16, ScalarImpl::Int16(_))
1161-
| (DataType::Int32, ScalarImpl::Int32(_))
1162-
| (DataType::Int64, ScalarImpl::Int64(_))
1163-
| (DataType::Float32, ScalarImpl::Float32(_))
1164-
| (DataType::Float64, ScalarImpl::Float64(_))
1165-
| (DataType::Varchar, ScalarImpl::Utf8(_))
1166-
| (DataType::Bytea, ScalarImpl::Bytea(_))
1167-
| (DataType::Date, ScalarImpl::NaiveDate(_))
1168-
| (DataType::Time, ScalarImpl::NaiveTime(_))
1169-
| (DataType::Timestamp, ScalarImpl::NaiveDateTime(_))
1170-
| (DataType::Timestamptz, ScalarImpl::Int64(_))
1171-
| (DataType::Decimal, ScalarImpl::Decimal(_))
1172-
| (DataType::Interval, ScalarImpl::Interval(_))
1173-
| (DataType::Jsonb, ScalarImpl::Jsonb(_))
1174-
| (DataType::Struct { .. }, ScalarImpl::Struct(_))
1175-
| (DataType::List { .. }, ScalarImpl::List(_))
1176-
)
1186+
Some(scalar) => {
1187+
macro_rules! matches {
1188+
($( { $DataType:ident, $PhysicalType:ident }),*) => {
1189+
match (data_type, scalar) {
1190+
$(
1191+
(DataType::$DataType { .. }, ScalarImpl::$PhysicalType(_)) => true,
1192+
(DataType::$DataType { .. }, _) => false, // so that we won't forget to match a new logical type
1193+
)*
1194+
}
1195+
}
1196+
}
1197+
for_all_type_pairs! { matches }
11771198
}
11781199
None => true,
11791200
}

src/common/src/util/schema_check.rs

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,43 +15,36 @@
1515
use itertools::Itertools;
1616

1717
use crate::array::column::Column;
18+
use crate::array::ArrayImpl;
19+
use crate::for_all_type_pairs;
1820
use crate::types::DataType;
1921

2022
/// Check if the schema of `columns` matches the expected `data_types`. Used for debugging.
2123
pub fn schema_check<'a, T, C>(data_types: T, columns: C) -> Result<(), String>
2224
where
23-
T: IntoIterator<Item = &'a DataType> + Clone,
24-
C: IntoIterator<Item = &'a Column> + Clone,
25+
T: IntoIterator<Item = &'a DataType>,
26+
C: IntoIterator<Item = &'a Column>,
2527
{
26-
tracing::event!(
27-
tracing::Level::TRACE,
28-
"input schema = \n{:#?}\nexpected schema = \n{:#?}",
29-
columns
30-
.clone()
31-
.into_iter()
32-
.map(|col| col.array_ref().get_ident())
33-
.collect_vec(),
34-
data_types.clone().into_iter().collect_vec(),
35-
);
36-
37-
for (i, pair) in columns.into_iter().zip_longest(data_types).enumerate() {
38-
let array = pair.as_ref().left().map(|c| c.array_ref());
39-
let builder = pair.as_ref().right().map(|d| d.create_array_builder(0)); // TODO: check `data_type` directly
40-
41-
macro_rules! check_schema {
42-
($( { $variant_name:ident, $suffix_name:ident, $array:ty, $builder:ty } ),*) => {
43-
use crate::array::ArrayBuilderImpl;
44-
use crate::array::ArrayImpl;
45-
46-
match (array, &builder) {
47-
$( (Some(ArrayImpl::$variant_name(_)), Some(ArrayBuilderImpl::$variant_name(_))) => {} ),*
48-
_ => return Err(format!("column {} should be {:?}, while stream chunk gives {:?}",
49-
i, builder.map(|b| b.get_ident()), array.map(|a| a.get_ident()))),
28+
for (i, pair) in data_types
29+
.into_iter()
30+
.zip_longest(columns.into_iter().map(|c| c.array_ref()))
31+
.enumerate()
32+
{
33+
macro_rules! matches {
34+
($( { $DataType:ident, $PhysicalType:ident }),*) => {
35+
match (pair.as_ref().left(), pair.as_ref().right()) {
36+
$( (Some(DataType::$DataType { .. }), Some(ArrayImpl::$PhysicalType(_))) => continue, )*
37+
(data_type, array) => {
38+
let array_ident = array.map(|a| a.get_ident());
39+
return Err(format!(
40+
"column type mismatched at position {i}: expected {data_type:?}, found {array_ident:?}"
41+
));
42+
}
5043
}
51-
};
44+
}
5245
}
5346

54-
for_all_variants! { check_schema };
47+
for_all_type_pairs! { matches }
5548
}
5649

5750
Ok(())

0 commit comments

Comments
 (0)