1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use crate::datatypes::{DataType, Field, TimeUnit};
use crate::error::Result;
use super::super::api;
use super::super::api::ResultSetMetadata;
pub fn infer_schema(resut_set_metadata: &impl ResultSetMetadata) -> Result<Vec<Field>> {
let num_cols: u16 = resut_set_metadata.num_result_cols().unwrap() as u16;
let fields = (0..num_cols)
.map(|index| {
let mut column_description = api::ColumnDescription::default();
resut_set_metadata
.describe_col(index + 1, &mut column_description)
.unwrap();
column_to_field(&column_description)
})
.collect();
Ok(fields)
}
fn column_to_field(column_description: &api::ColumnDescription) -> Field {
Field::new(
&column_description
.name_to_string()
.expect("Column name must be representable in utf8"),
column_to_data_type(&column_description.data_type),
column_description.could_be_nullable(),
)
}
fn column_to_data_type(data_type: &api::DataType) -> DataType {
use api::DataType as OdbcDataType;
match data_type {
OdbcDataType::Numeric {
precision: p @ 0..=38,
scale,
}
| OdbcDataType::Decimal {
precision: p @ 0..=38,
scale,
} => DataType::Decimal(*p, (*scale) as usize),
OdbcDataType::Integer => DataType::Int32,
OdbcDataType::SmallInt => DataType::Int16,
OdbcDataType::Real | OdbcDataType::Float { precision: 0..=24 } => DataType::Float32,
OdbcDataType::Float { precision: _ } | OdbcDataType::Double => DataType::Float64,
OdbcDataType::Date => DataType::Date32,
OdbcDataType::Timestamp { precision: 0 } => DataType::Timestamp(TimeUnit::Second, None),
OdbcDataType::Timestamp { precision: 1..=3 } => {
DataType::Timestamp(TimeUnit::Millisecond, None)
}
OdbcDataType::Timestamp { precision: 4..=6 } => {
DataType::Timestamp(TimeUnit::Microsecond, None)
}
OdbcDataType::Timestamp { precision: _ } => DataType::Timestamp(TimeUnit::Nanosecond, None),
OdbcDataType::BigInt => DataType::Int64,
OdbcDataType::TinyInt => DataType::Int8,
OdbcDataType::Bit => DataType::Boolean,
OdbcDataType::Binary { length } => DataType::FixedSizeBinary(*length),
OdbcDataType::LongVarbinary { length: _ } | OdbcDataType::Varbinary { length: _ } => {
DataType::Binary
}
OdbcDataType::Unknown
| OdbcDataType::Time { precision: _ }
| OdbcDataType::Numeric { .. }
| OdbcDataType::Decimal { .. }
| OdbcDataType::Other {
data_type: _,
column_size: _,
decimal_digits: _,
}
| OdbcDataType::WChar { length: _ }
| OdbcDataType::Char { length: _ }
| OdbcDataType::WVarchar { length: _ }
| OdbcDataType::LongVarchar { length: _ }
| OdbcDataType::Varchar { length: _ } => DataType::Utf8,
}
}