Repository: risingwavelabs/risingwave
File: src/connector/src/parser/mysql.rs (Rust)

Code before:
            match mysql_row.take_opt::<Option<Vec<u8>>, _>(mysql_datum_index) {
                None => bail!(
                    "no value found at column: {}, index: {}",
                    column_name,
                    mysql_datum_index
                ),
                Some(Ok(val)) => match val {
                    None => Ok(None),
                    Some(val) => match val.as_slice() {
                        [0] => Ok(Some(ScalarImpl::from(false))),
                        [1] => Ok(Some(ScalarImpl::from(true))),
                        _ => Err(anyhow!("invalid value for boolean: {:?}", val)),
                    },
                },
                Some(Err(e)) => Err(anyhow::Error::new(e)
                    .context("failed to deserialize MySQL value into rust value")
                    .context(format!(
                        "column: {}, index: {}, rust_type: Vec<u8>",
                        column_name, mysql_datum_index,
                    ))),
            }
        }
        DataType::Int16 => {
            handle_data_type_with_signed!(mysql_row, mysql_datum_index, column_name, i16, u16)
        }
        DataType::Int32 => {
            handle_data_type_with_signed!(mysql_row, mysql_datum_index, column_name, i32, u32)
        }
        DataType::Int64 => {
            handle_data_type_with_signed!(mysql_row, mysql_datum_index, column_name, i64, u64)
        }
        DataType::Float32 => {
            handle_data_type!(mysql_row, mysql_datum_index, column_name, f32)
        }
        DataType::Float64 => {
            handle_data_type!(mysql_row, mysql_datum_index, column_name, f64)
        }
        DataType::Decimal => {
            handle_data_type!(
                mysql_row,
                mysql_datum_index,
                column_name,
                RustDecimal,
                Decimal
            )
        }
        DataType::Varchar => {
            handle_data_type!(mysql_row, mysql_datum_index, column_name, String)
        }
        DataType::Date => {
            handle_data_type!(mysql_row, mysql_datum_index, column_name, NaiveDate, Date)

Review comment (suggestion):
Answering my own question here https://github.com/risingwavelabs/risingwave/pull/23278#discussion_r2371770686
> How does upcast work here?

Before this PR, when a MySQL u16 is declared as RisingWave i32, we would get it as `i32`.

After this PR, when a MySQL u16 is declared as RisingWave i32, we would get it as `u32` and then transform into `i32`.

These relies on the fact that `mysql_async` allows getting MySQL u16 as `i32` and `u32`

Code after:
            }
            // Bit(1)
            match mysql_row.take_opt::<Option<Vec<u8>>, _>(mysql_datum_index) {
                None => bail!(
                    "no value found at column: {}, index: {}",
                    column_name,
                    mysql_datum_index
                ),
                Some(Ok(val)) => match val {
                    None => Ok(None),
                    Some(val) => match val.as_slice() {
                        [0] => Ok(Some(ScalarImpl::from(false))),
                        [1] => Ok(Some(ScalarImpl::from(true))),
                        _ => Err(anyhow!("invalid value for boolean: {:?}", val)),
                    },
                },
                Some(Err(e)) => Err(anyhow::Error::new(e)
                    .context("failed to deserialize MySQL value into rust value")
                    .context(format!(
                        "column: {}, index: {}, rust_type: Vec<u8>",
                        column_name, mysql_datum_index,
                    ))),
            }
        }
        DataType::Int16 => {
            handle_data_type_with_signed!(mysql_row, mysql_datum_index, column_name, i16, u16)
        }
        DataType::Int32 => {
            handle_data_type_with_signed!(mysql_row, mysql_datum_index, column_name, i32, u32)
        }
        DataType::Int64 => {
            handle_data_type_with_signed!(mysql_row, mysql_datum_index, column_name, i64, u64)
        }
        DataType::Float32 => {
            handle_data_type!(mysql_row, mysql_datum_index, column_name, f32)
        }
        DataType::Float64 => {
            handle_data_type!(mysql_row, mysql_datum_index, column_name, f64)
        }
        DataType::Decimal => {
            handle_data_type!(
                mysql_row,
                mysql_datum_index,
                column_name,
                RustDecimal,
                Decimal
            )
        }
        DataType::Varchar => {
            handle_data_type!(mysql_row, mysql_datum_index, column_name, String)
        }