in datafusion/sql/src/planner.rs [557:742]
fn convert_simple_data_type(&self, sql_type: &SQLDataType) -> Result<DataType> {
match sql_type {
SQLDataType::Boolean | SQLDataType::Bool => Ok(DataType::Boolean),
SQLDataType::TinyInt(_) => Ok(DataType::Int8),
SQLDataType::SmallInt(_) | SQLDataType::Int2(_) => Ok(DataType::Int16),
SQLDataType::Int(_) | SQLDataType::Integer(_) | SQLDataType::Int4(_) => {
Ok(DataType::Int32)
}
SQLDataType::BigInt(_) | SQLDataType::Int8(_) => Ok(DataType::Int64),
SQLDataType::TinyIntUnsigned(_) => Ok(DataType::UInt8),
SQLDataType::SmallIntUnsigned(_) | SQLDataType::Int2Unsigned(_) => {
Ok(DataType::UInt16)
}
SQLDataType::IntUnsigned(_)
| SQLDataType::IntegerUnsigned(_)
| SQLDataType::Int4Unsigned(_) => Ok(DataType::UInt32),
SQLDataType::Varchar(length) => {
match (length, self.options.support_varchar_with_length) {
(Some(_), false) => plan_err!(
"does not support Varchar with length, \
please set `support_varchar_with_length` to be true"
),
_ => {
if self.options.map_varchar_to_utf8view {
Ok(DataType::Utf8View)
} else {
Ok(DataType::Utf8)
}
}
}
}
SQLDataType::BigIntUnsigned(_) | SQLDataType::Int8Unsigned(_) => {
Ok(DataType::UInt64)
}
SQLDataType::Float(_) => Ok(DataType::Float32),
SQLDataType::Real | SQLDataType::Float4 => Ok(DataType::Float32),
SQLDataType::Double(ExactNumberInfo::None)
| SQLDataType::DoublePrecision
| SQLDataType::Float8 => Ok(DataType::Float64),
SQLDataType::Double(
ExactNumberInfo::Precision(_) | ExactNumberInfo::PrecisionAndScale(_, _),
) => {
not_impl_err!(
"Unsupported SQL type (precision/scale not supported) {sql_type}"
)
}
SQLDataType::Char(_) | SQLDataType::Text | SQLDataType::String(_) => {
Ok(DataType::Utf8)
}
SQLDataType::Timestamp(precision, tz_info)
if precision.is_none() || [0, 3, 6, 9].contains(&precision.unwrap()) =>
{
let tz = if matches!(tz_info, TimezoneInfo::Tz)
|| matches!(tz_info, TimezoneInfo::WithTimeZone)
{
// Timestamp With Time Zone
// INPUT : [SQLDataType] TimestampTz + [Config] Time Zone
// OUTPUT: [ArrowDataType] Timestamp<TimeUnit, Some(Time Zone)>
self.context_provider.options().execution.time_zone.clone()
} else {
// Timestamp Without Time zone
None
};
let precision = match precision {
Some(0) => TimeUnit::Second,
Some(3) => TimeUnit::Millisecond,
Some(6) => TimeUnit::Microsecond,
None | Some(9) => TimeUnit::Nanosecond,
_ => unreachable!(),
};
Ok(DataType::Timestamp(precision, tz.map(Into::into)))
}
SQLDataType::Date => Ok(DataType::Date32),
SQLDataType::Time(None, tz_info) => {
if matches!(tz_info, TimezoneInfo::None)
|| matches!(tz_info, TimezoneInfo::WithoutTimeZone)
{
Ok(DataType::Time64(TimeUnit::Nanosecond))
} else {
// We don't support TIMETZ and TIME WITH TIME ZONE for now
not_impl_err!("Unsupported SQL type {sql_type:?}")
}
}
SQLDataType::Numeric(exact_number_info)
| SQLDataType::Decimal(exact_number_info) => {
let (precision, scale) = match *exact_number_info {
ExactNumberInfo::None => (None, None),
ExactNumberInfo::Precision(precision) => (Some(precision), None),
ExactNumberInfo::PrecisionAndScale(precision, scale) => {
(Some(precision), Some(scale))
}
};
make_decimal_type(precision, scale)
}
SQLDataType::Bytea => Ok(DataType::Binary),
SQLDataType::Interval => Ok(DataType::Interval(IntervalUnit::MonthDayNano)),
SQLDataType::Struct(fields, _) => {
let fields = fields
.iter()
.enumerate()
.map(|(idx, field)| {
let data_type = self.convert_data_type(&field.field_type)?;
let field_name = match &field.field_name {
Some(ident) => ident.clone(),
None => Ident::new(format!("c{idx}")),
};
Ok(Arc::new(Field::new(
self.ident_normalizer.normalize(field_name),
data_type,
true,
)))
})
.collect::<Result<Vec<_>>>()?;
Ok(DataType::Struct(Fields::from(fields)))
}
SQLDataType::Nvarchar(_)
| SQLDataType::JSON
| SQLDataType::Uuid
| SQLDataType::Binary(_)
| SQLDataType::Varbinary(_)
| SQLDataType::Blob(_)
| SQLDataType::Datetime(_)
| SQLDataType::Regclass
| SQLDataType::Custom(_, _)
| SQLDataType::Array(_)
| SQLDataType::Enum(_, _)
| SQLDataType::Set(_)
| SQLDataType::MediumInt(_)
| SQLDataType::MediumIntUnsigned(_)
| SQLDataType::Character(_)
| SQLDataType::CharacterVarying(_)
| SQLDataType::CharVarying(_)
| SQLDataType::CharacterLargeObject(_)
| SQLDataType::CharLargeObject(_)
| SQLDataType::Timestamp(_, _)
| SQLDataType::Time(Some(_), _)
| SQLDataType::Dec(_)
| SQLDataType::BigNumeric(_)
| SQLDataType::BigDecimal(_)
| SQLDataType::Clob(_)
| SQLDataType::Bytes(_)
| SQLDataType::Int64
| SQLDataType::Float64
| SQLDataType::JSONB
| SQLDataType::Unspecified
| SQLDataType::Int16
| SQLDataType::Int32
| SQLDataType::Int128
| SQLDataType::Int256
| SQLDataType::UInt8
| SQLDataType::UInt16
| SQLDataType::UInt32
| SQLDataType::UInt64
| SQLDataType::UInt128
| SQLDataType::UInt256
| SQLDataType::Float32
| SQLDataType::Date32
| SQLDataType::Datetime64(_, _)
| SQLDataType::FixedString(_)
| SQLDataType::Map(_, _)
| SQLDataType::Tuple(_)
| SQLDataType::Nested(_)
| SQLDataType::Union(_)
| SQLDataType::Nullable(_)
| SQLDataType::LowCardinality(_)
| SQLDataType::Trigger
| SQLDataType::TinyBlob
| SQLDataType::MediumBlob
| SQLDataType::LongBlob
| SQLDataType::TinyText
| SQLDataType::MediumText
| SQLDataType::LongText
| SQLDataType::Bit(_)
| SQLDataType::BitVarying(_)
| SQLDataType::Signed
| SQLDataType::SignedInteger
| SQLDataType::Unsigned
| SQLDataType::UnsignedInteger
| SQLDataType::AnyType
| SQLDataType::Table(_)
| SQLDataType::VarBit(_)
| SQLDataType::GeometricType(_) => {
not_impl_err!("Unsupported SQL type {sql_type:?}")
}
}
}