Skip to content

Commit

Permalink
feat: impl TryFrom for HashMap and Vec
Browse files Browse the repository at this point in the history
  • Loading branch information
everpcpc committed Apr 12, 2024
1 parent d4f8b6b commit 310370a
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 63 deletions.
7 changes: 2 additions & 5 deletions deny.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
[advisories]
version = 2
db-path = "~/.cargo/advisory-db"
db-urls = ["https://github.com/rustsec/advisory-db"]
vulnerability = "deny"
unmaintained = "warn"
yanked = "warn"
notice = "warn"
ignore = [
#"RUSTSEC-0000-0000",
]

[licenses]
unlicensed = "warn"
version = 2
allow = [
"MIT",
"CC0-1.0",
Expand Down
122 changes: 70 additions & 52 deletions driver/tests/driver/select_simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::assert_eq;
use std::{assert_eq, collections::HashMap};

use chrono::{DateTime, NaiveDate, NaiveDateTime};
use databend_driver::{Client, Connection, DecimalSize, NumberValue, Value};
Expand Down Expand Up @@ -180,69 +180,87 @@ async fn select_nullable_u64() {
#[tokio::test]
async fn select_array() {
let conn = prepare().await;
let row = conn
.query_row("select [], [1, 2, 3, 4, 5], [10::Decimal(15,2), 1.1+2.3], [to_binary('xyz')]")

let row1 = conn.query_row("select []").await.unwrap().unwrap();
let (val1,): (Vec<String>,) = row1.try_into().unwrap();
assert_eq!(val1, Vec::<String>::new());

let row2 = conn
.query_row("select [1, 2, 3, 4, 5]")
.await
.unwrap()
.unwrap();
assert!(row.is_some());
let row = row.unwrap();
assert_eq!(
row.values().to_owned(),
vec![
Value::EmptyArray,
Value::Array(vec![
Value::Number(NumberValue::UInt8(1)),
Value::Number(NumberValue::UInt8(2)),
Value::Number(NumberValue::UInt8(3)),
Value::Number(NumberValue::UInt8(4)),
Value::Number(NumberValue::UInt8(5)),
]),
Value::Array(vec![
Value::Number(NumberValue::Decimal128(
1000,
DecimalSize {
precision: 4,
scale: 2
}
)),
Value::Number(NumberValue::Decimal128(
340,
DecimalSize {
precision: 4,
scale: 2
}
))
]),
Value::Array(vec![Value::Binary(vec![120, 121, 122])]),
]
);
let (val2,): (Vec<u8>,) = row2.try_into().unwrap();
assert_eq!(val2, vec![1, 2, 3, 4, 5]);

let row3 = conn
.query_row("select [10::Decimal(15,2), 1.1+2.3]")
.await
.unwrap()
.unwrap();
let (val3,): (Vec<String>,) = row3.try_into().unwrap();
assert_eq!(val3, vec!["10.00".to_string(), "3.4".to_string()]);

let row4 = conn
.query_row("select [to_binary('xyz')]")
.await
.unwrap()
.unwrap();
let (val4,): (Vec<Vec<u8>>,) = row4.try_into().unwrap();
assert_eq!(val4, vec![vec![120, 121, 122]]);
}

#[tokio::test]
async fn select_map() {
let conn = prepare().await;
let row = conn
.query_row("select {}, {'k1':'v1','k2':'v2'}, {'xx':to_date('2020-01-01')}")

let row1 = conn.query_row("select {}").await.unwrap().unwrap();
let (val1,): (HashMap<u8, u8>,) = row1.try_into().unwrap();
assert_eq!(val1, HashMap::new());

let row2 = conn
.query_row("select {'k1':'v1','k2':'v2'}")
.await
.unwrap()
.unwrap();
assert!(row.is_some());
let row = row.unwrap();
let (val2,): (HashMap<String, String>,) = row2.try_into().unwrap();
assert_eq!(
row.values().to_owned(),
val2,
vec![
Value::EmptyMap,
Value::Map(vec![
(
Value::String("k1".to_string()),
Value::String("v1".to_string())
),
(
Value::String("k2".to_string()),
Value::String("v2".to_string())
),
]),
Value::Map(vec![(Value::String("xx".to_string()), Value::Date(18262)),]),
("k1".to_string(), "v1".to_string()),
("k2".to_string(), "v2".to_string())
]
.into_iter()
.collect()
);

let row3 = conn
.query_row("select {'xx':to_date('2020-01-01')}")
.await
.unwrap()
.unwrap();
let (val3,): (HashMap<String, NaiveDate>,) = row3.try_into().unwrap();
assert_eq!(
val3,
vec![(
"xx".to_string(),
NaiveDate::from_ymd_opt(2020, 1, 1).unwrap()
)]
.into_iter()
.collect()
);

let row4 = conn
.query_row("select {1: 'a', 2: 'b'}")
.await
.unwrap()
.unwrap();
let (val4,): (HashMap<u8, String>,) = row4.try_into().unwrap();
assert_eq!(
val4,
vec![(1, "a".to_string()), (2, "b".to_string())]
.into_iter()
.collect()
);
}

Expand Down
8 changes: 4 additions & 4 deletions sql/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ flight-sql = ["dep:arrow-array", "dep:arrow-schema", "dep:tonic"]
[dependencies]
databend-client = { workspace = true }

memchr = "2.7.2"
chrono = { version = "0.4.35", default-features = false }
geozero = { version = "0.12.0", features = ["default", "with-wkb"] }
geozero = { version = "0.12", features = ["default", "with-wkb"] }
glob = "0.3"
itertools = "0.12"
jsonb = "0.3"
lexical-core = "0.8.5"
lexical-core = "0.8"
memchr = "2.7"

roaring = { version = "0.10", features = ["serde"] }
serde = { version = "1.0", default-features = false, features = ["derive"] }
Expand All @@ -33,11 +33,11 @@ url = { version = "2.5", default-features = false }
arrow = { version = "47.0" }
arrow-array = { version = "47.0", optional = true }
arrow-schema = { version = "47.0", optional = true }
hex = "0.4.3"
tonic = { version = "0.10", default-features = false, features = [
"transport",
"codegen",
"tls",
"tls-webpki-roots",
"prost",
], optional = true }
hex = "0.4.3"
3 changes: 1 addition & 2 deletions sql/src/rows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
// limitations under the License.

use std::pin::Pin;
use std::sync::Arc;
use std::task::Context;
use std::task::Poll;

Expand Down Expand Up @@ -149,7 +148,7 @@ impl TryFrom<RecordBatch> for Rows {
rows.push(Row(values));
}
Ok(Self {
schema: Arc::new(schema.try_into()?),
schema: std::sync::Arc::new(schema.try_into()?),
rows,
})
}
Expand Down
45 changes: 45 additions & 0 deletions sql/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::HashMap;
use std::hash::Hash;
use std::io::BufRead;
use std::io::Cursor;

Expand Down Expand Up @@ -472,6 +474,8 @@ impl TryFrom<Value> for String {
match val {
Value::String(s) => Ok(s),
Value::Bitmap(s) => Ok(s),
Value::Number(NumberValue::Decimal128(v, s)) => Ok(display_decimal_128(v, s.scale)),
Value::Number(NumberValue::Decimal256(v, s)) => Ok(display_decimal_256(v, s.scale)),
Value::Variant(s) => Ok(s),
_ => Err(ConvertError::new("string", format!("{:?}", val)).into()),
}
Expand Down Expand Up @@ -563,6 +567,47 @@ impl TryFrom<Value> for NaiveDate {
}
}

impl<V> TryFrom<Value> for Vec<V>
where
V: TryFrom<Value, Error = Error>,
{
type Error = Error;
fn try_from(val: Value) -> Result<Self> {
match val {
Value::Binary(vals) => vals
.into_iter()
.map(|v| V::try_from(Value::Number(NumberValue::UInt8(v))))
.collect(),
Value::Array(vals) => vals.into_iter().map(V::try_from).collect(),
Value::EmptyArray => Ok(vec![]),
_ => Err(ConvertError::new("Vec", format!("{}", val)).into()),
}
}
}

impl<K, V> TryFrom<Value> for HashMap<K, V>
where
K: TryFrom<Value, Error = Error> + Eq + Hash,
V: TryFrom<Value, Error = Error>,
{
type Error = Error;
fn try_from(val: Value) -> Result<Self> {
match val {
Value::Map(kvs) => {
let mut map = HashMap::new();
for (k, v) in kvs {
let k = K::try_from(k)?;
let v = V::try_from(v)?;
map.insert(k, v);
}
Ok(map)
}
Value::EmptyMap => Ok(HashMap::new()),
_ => Err(ConvertError::new("HashMap", format!("{}", val)).into()),
}
}
}

// This macro implements TryFrom to Option for Nullable column
macro_rules! impl_try_from_to_option {
($($t:ty),*) => {
Expand Down

0 comments on commit 310370a

Please sign in to comment.