Skip to content

Commit 80107c7

Browse files
ShiKaiWidust1
authored andcommitted
feat: support hex literal (apache#1030)
## Rationale Currently, the underlying storage supports binary data type. However, during the parsing and planning, the binary data is not supported. ## Detailed Changes Support binary data type during parsing and planning stage. ## Test Plan New unit tests and integration tests.
1 parent bd51638 commit 80107c7

File tree

7 files changed

+205
-47
lines changed

7 files changed

+205
-47
lines changed

Cargo.lock

+19-19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+6-6
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ cluster = { path = "cluster" }
7676
criterion = "0.3"
7777
common_types = { path = "common_types" }
7878
common_util = { path = "common_util" }
79-
datafusion = { git = "https://github.com/jiacai2050/arrow-datafusion.git", rev = "13314c37020b90246db9b80f8294370c06e61018" }
80-
datafusion-proto = { git = "https://github.com/jiacai2050/arrow-datafusion.git", rev = "13314c37020b90246db9b80f8294370c06e61018" }
79+
datafusion = { git = "https://github.com/ceresdb/arrow-datafusion.git", rev = "acb5d97a8a8de5296989740f97db3773fe3aa45a" }
80+
datafusion-proto = { git = "https://github.com/ceresdb/arrow-datafusion.git", rev = "acb5d97a8a8de5296989740f97db3773fe3aa45a" }
8181
df_operator = { path = "df_operator" }
8282
etcd-client = "0.10.3"
8383
env_logger = "0.6"
@@ -87,10 +87,10 @@ lazy_static = "1.4.0"
8787
log = "0.4"
8888
logger = { path = "components/logger" }
8989
lru = "0.7.6"
90-
influxql-logical-planner = { git = "https://github.com/CeresDB/influxql", rev = "efbc589", package = "iox_query_influxql" }
91-
influxql-parser = { git = "https://github.com/CeresDB/influxql", rev = "efbc589", package = "influxdb_influxql_parser" }
92-
influxql-query = { git = "https://github.com/CeresDB/influxql", rev = "efbc589", package = "iox_query" }
93-
influxql-schema = { git = "https://github.com/CeresDB/influxql", rev = "efbc589", package = "schema" }
90+
influxql-logical-planner = { git = "https://github.com/CeresDB/influxql", rev = "935e037a5ad6eb142a93f3e9eb321ee72e28cbad", package = "iox_query_influxql" }
91+
influxql-parser = { git = "https://github.com/CeresDB/influxql", rev = "935e037a5ad6eb142a93f3e9eb321ee72e28cbad", package = "influxdb_influxql_parser" }
92+
influxql-query = { git = "https://github.com/CeresDB/influxql", rev = "935e037a5ad6eb142a93f3e9eb321ee72e28cbad", package = "iox_query" }
93+
influxql-schema = { git = "https://github.com/CeresDB/influxql", rev = "935e037a5ad6eb142a93f3e9eb321ee72e28cbad", package = "schema" }
9494
interpreters = { path = "interpreters" }
9595
itertools = "0.10.5"
9696
meta_client = { path = "meta_client" }

common_types/src/datum.rs

+70-21
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2022 CeresDB Project Authors. Licensed under Apache-2.0.
1+
// Copyright 2022-2023 CeresDB Project Authors. Licensed under Apache-2.0.
22

33
//! Datum holds different kind of data
44
@@ -8,78 +8,78 @@ use arrow::temporal_conversions::{EPOCH_DAYS_FROM_CE, NANOSECONDS};
88
use ceresdbproto::schema::DataType as DataTypePb;
99
use chrono::{Datelike, Local, NaiveDate, NaiveTime, TimeZone, Timelike};
1010
use serde::ser::{Serialize, Serializer};
11-
use snafu::{Backtrace, ResultExt, Snafu};
11+
use snafu::{Backtrace, OptionExt, ResultExt, Snafu};
1212
use sqlparser::ast::{DataType as SqlDataType, Value};
1313

14-
use crate::{bytes::Bytes, hash::hash64, string::StringBytes, time::Timestamp};
14+
use crate::{bytes::Bytes, hash::hash64, hex, string::StringBytes, time::Timestamp};
1515

1616
const DATE_FORMAT: &str = "%Y-%m-%d";
1717
const TIME_FORMAT: &str = "%H:%M:%S%.3f";
1818

1919
#[derive(Debug, Snafu)]
2020
pub enum Error {
21-
#[snafu(display(
22-
"Unsupported SQL data type, type:{}.\nBacktrace:\n{}",
23-
sql_type,
24-
backtrace
25-
))]
21+
#[snafu(display("Unsupported SQL data type, type:{sql_type}.\nBacktrace:\n{backtrace}"))]
2622
UnsupportedDataType {
2723
sql_type: SqlDataType,
2824
backtrace: Backtrace,
2925
},
3026

31-
#[snafu(display("Invalid double or float, err:{}.\nBacktrace:\n{}", source, backtrace))]
27+
#[snafu(display("Invalid double or float, err:{source}.\nBacktrace:\n{backtrace}"))]
3228
InvalidDouble {
3329
source: std::num::ParseFloatError,
3430
backtrace: Backtrace,
3531
},
3632

3733
#[snafu(display(
38-
"Invalid insert value, kind:{}, value:{:?}.\nBacktrace:\n{}",
39-
kind,
40-
value,
41-
backtrace
34+
"Invalid insert value, kind:{kind}, value:{value:?}.\nBacktrace:\n{backtrace}"
4235
))]
4336
InvalidValueType {
4437
kind: DatumKind,
4538
value: Value,
4639
backtrace: Backtrace,
4740
},
48-
#[snafu(display("Invalid timestamp, err:{}.\nBacktrace:\n{}", source, backtrace))]
41+
42+
#[snafu(display("Invalid timestamp, err:{source}.\nBacktrace:\n{backtrace}"))]
4943
InvalidTimestamp {
5044
source: std::num::ParseIntError,
5145
backtrace: Backtrace,
5246
},
5347

54-
#[snafu(display("Invalid date, err:{}.\nBacktrace:\n{}", source, backtrace))]
48+
#[snafu(display("Invalid date, err:{source}.\nBacktrace:\n{backtrace}"))]
5549
InvalidDate {
5650
source: chrono::ParseError,
5751
backtrace: Backtrace,
5852
},
5953

60-
#[snafu(display("Invalid time, err:{}.\nBacktrace:\n{}", source, backtrace))]
54+
#[snafu(display("Invalid time, err:{source}.\nBacktrace:\n{backtrace}"))]
6155
InvalidTimeCause {
6256
source: chrono::ParseError,
6357
backtrace: Backtrace,
6458
},
6559

66-
#[snafu(display("Invalid time, err:{}.\nBacktrace:\n{}", source, backtrace))]
60+
#[snafu(display("Invalid time, err:{source}.\nBacktrace:\n{backtrace}"))]
6761
InvalidTimeHourFormat {
6862
source: std::num::ParseIntError,
6963
backtrace: Backtrace,
7064
},
7165

72-
#[snafu(display("Invalid time, err:{}", msg))]
73-
InvalidTimeNoCause { msg: String },
66+
#[snafu(display("Invalid time, err:{msg}.\nBacktrace:\n{backtrace}"))]
67+
InvalidTimeNoCause { msg: String, backtrace: Backtrace },
7468

75-
#[snafu(display("Invalid integer, err:{}.\nBacktrace:\n{}", source, backtrace))]
69+
#[snafu(display("Invalid integer, err:{source}.\nBacktrace:\n{backtrace}"))]
7670
InvalidInt {
7771
source: std::num::ParseIntError,
7872
backtrace: Backtrace,
7973
},
8074

81-
#[snafu(display("Invalid datum byte, byte:{}.\nBacktrace:\n{}", value, backtrace))]
75+
#[snafu(display("Invalid datum byte, byte:{value}.\nBacktrace:\n{backtrace}"))]
8276
InvalidDatumByte { value: u8, backtrace: Backtrace },
77+
78+
#[snafu(display("Invalid hex value, hex_val:{hex_val}.\nBacktrace:\n{backtrace}"))]
79+
InvalidHexValue {
80+
hex_val: String,
81+
backtrace: Backtrace,
82+
},
8383
}
8484

8585
pub type Result<T> = std::result::Result<T, Error>;
@@ -749,6 +749,10 @@ impl Datum {
749749
(DatumKind::Varbinary, Value::DoubleQuotedString(s)) => {
750750
Ok(Datum::Varbinary(Bytes::from(s)))
751751
}
752+
(DatumKind::Varbinary, Value::HexStringLiteral(s)) => {
753+
let bytes = hex::try_decode(&s).context(InvalidHexValue { hex_val: s })?;
754+
Ok(Datum::Varbinary(Bytes::from(bytes)))
755+
}
752756
(DatumKind::String, Value::DoubleQuotedString(s)) => {
753757
Ok(Datum::String(StringBytes::from(s)))
754758
}
@@ -1478,4 +1482,49 @@ mod tests {
14781482
assert!(Datum::parse_datum_time_from_str(source).is_err());
14791483
}
14801484
}
1485+
1486+
#[test]
1487+
fn test_convert_from_sql_value() {
1488+
let cases = vec![
1489+
(
1490+
Value::Boolean(false),
1491+
DatumKind::Boolean,
1492+
true,
1493+
Some(Datum::Boolean(false)),
1494+
),
1495+
(
1496+
Value::Number("100.1".to_string(), false),
1497+
DatumKind::Float,
1498+
true,
1499+
Some(Datum::Float(100.1)),
1500+
),
1501+
(
1502+
Value::SingleQuotedString("string_literal".to_string()),
1503+
DatumKind::String,
1504+
true,
1505+
Some(Datum::String(StringBytes::from_static("string_literal"))),
1506+
),
1507+
(
1508+
Value::HexStringLiteral("c70a0b".to_string()),
1509+
DatumKind::Varbinary,
1510+
true,
1511+
Some(Datum::Varbinary(Bytes::from(vec![199, 10, 11]))),
1512+
),
1513+
(
1514+
Value::EscapedStringLiteral("string_literal".to_string()),
1515+
DatumKind::String,
1516+
false,
1517+
None,
1518+
),
1519+
];
1520+
1521+
for (input, kind, succeed, expect) in cases {
1522+
let res = Datum::try_from_sql_value(&kind, input);
1523+
if succeed {
1524+
assert_eq!(res.unwrap(), expect.unwrap());
1525+
} else {
1526+
assert!(res.is_err());
1527+
}
1528+
}
1529+
}
14811530
}

0 commit comments

Comments
 (0)