Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ All other sections are for end-users.
<!-- markdownlint-disable MD024 -->
## [Unreleased]

### For developpers
### Added

- `BLOB` type ([#187](https://github.com/SpringQL/SpringQL/pull/187))

### For developers

- Add deny lint option for `rustdoc::broken_intra_doc_links` ([#185](https://github.com/SpringQL/SpringQL/pull/185))
- Refactor : Hide detail module structure ([#177](https://github.com/SpringQL/SpringQL/pull/177))
Expand Down
8 changes: 8 additions & 0 deletions springql-core/src/pipeline/relation/sql_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ pub enum SqlType {
/// String types
StringComparableLoose(StringComparableLoseType),

/// Binary types
BinaryComparable,

/// Boolean types
BooleanComparable,

Expand Down Expand Up @@ -49,6 +52,11 @@ impl SqlType {
SqlType::StringComparableLoose(StringComparableLoseType::Text)
}

/// Constructor of Blob
pub fn blob() -> SqlType {
SqlType::BinaryComparable
}

/// Constructor of Boolean
pub fn boolean() -> SqlType {
SqlType::BooleanComparable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ keyword = {
| ^"AND"
| ^"AVG"
| ^"BIGINT"
| ^"BLOB"
| ^"BOOLEAN"
| ^"BY"
| ^"CREATE"
Expand Down Expand Up @@ -303,6 +304,7 @@ data_type = {
| float_type
| boolean_type
| character_type
| binary_type
| timestamp_type
}

Expand Down Expand Up @@ -350,6 +352,17 @@ character_type = {
^"TEXT"
}

/*
* ----------------------------------------------------------------------------
* Byte types
* (https://www.postgresql.org/docs/current/datatype-binary.html)
* ----------------------------------------------------------------------------
*/

binary_type = {
^"BLOB"
}

/*
* ----------------------------------------------------------------------------
* Timestamp Types
Expand Down
17 changes: 17 additions & 0 deletions springql-core/src/sql_processor/sql_parser/pest_parser_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,12 @@ impl PestParserImpl {
Self::parse_character_type,
identity,
)?)
.or(try_parse_child(
&mut params,
Rule::binary_type,
Self::parse_binary_type,
identity,
)?)
.or(try_parse_child(
&mut params,
Rule::timestamp_type,
Expand Down Expand Up @@ -1130,6 +1136,17 @@ impl PestParserImpl {
}
}

fn parse_binary_type(mut params: FnParseParams) -> Result<SqlType> {
let s = self_as_str(&mut params);
match s.to_ascii_uppercase().as_str() {
"BLOB" => Ok(SqlType::blob()),
x => {
eprintln!("Unexpected data type parsed: {}", x);
unreachable!();
}
}
}

fn parse_timestamp_type(mut params: FnParseParams) -> Result<SqlType> {
let s = self_as_str(&mut params);
match s.to_ascii_uppercase().as_str() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// This file is part of https://github.com/SpringQL/SpringQL which is licensed under MIT OR Apache-2.0. See file LICENSE-MIT or LICENSE-APACHE for full license details.

mod blob;
mod boolean;
mod event_duration;
mod float;
Expand Down Expand Up @@ -58,6 +59,14 @@ pub trait SpringValue: Sized {
Self::default_err("String")
}

/// # Failures
///
/// - `SpringError::Sql` when:
/// - the type implementing SqlConvertible is not convertible from Vec<u8>
fn try_from_blob(_: &[u8]) -> Result<Self> {
Self::default_err("Vec<u8>")
}

/// # Failures
///
/// - `SpringError::Sql` when:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// This file is part of https://github.com/SpringQL/SpringQL which is licensed under MIT OR Apache-2.0. See file LICENSE-MIT or LICENSE-APACHE for full license details.

use crate::{
api::error::Result,
stream_engine::autonomous_executor::row::value::{
sql_convertible::{SpringValue, ToNnSqlValue},
sql_value::NnSqlValue,
},
};

impl SpringValue for Vec<u8> {
fn try_from_blob(v: &[u8]) -> Result<Self> {
Ok(v.to_owned())
}
}

impl ToNnSqlValue for Vec<u8> {
fn into_sql_value(self) -> NnSqlValue {
NnSqlValue::Blob(self)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ pub enum NnSqlValue {
/// TEXT
Text(String),

/// BLOB
Blob(Vec<u8>),

/// BOOLEAN
Boolean(bool),

Expand All @@ -64,6 +67,7 @@ impl MemSize for NnSqlValue {
NnSqlValue::Float(_) => size_of::<f32>(),

NnSqlValue::Text(s) => s.capacity(),
NnSqlValue::Blob(v) => v.capacity(),

NnSqlValue::Boolean(_) => size_of::<bool>(),

Expand All @@ -89,7 +93,7 @@ impl MemSize for NnSqlValue {
///
/// does not work properly with closures which capture &mut environments.
macro_rules! for_all_loose_types {
( $nn_sql_value:expr, $closure_i64:expr, $closure_ordered_float:expr, $closure_string:expr, $closure_bool:expr, $closure_timestamp:expr, $closure_duration:expr ) => {{
( $nn_sql_value:expr, $closure_i64:expr, $closure_ordered_float:expr, $closure_string:expr, $closure_blob:expr, $closure_bool:expr, $closure_timestamp:expr, $closure_duration:expr ) => {{
match &$nn_sql_value {
NnSqlValue::SmallInt(_) | NnSqlValue::Integer(_) | NnSqlValue::BigInt(_) => {
let v = $nn_sql_value.unpack::<i64>().unwrap();
Expand All @@ -100,6 +104,7 @@ macro_rules! for_all_loose_types {
$closure_ordered_float(OrderedFloat(v))
}
NnSqlValue::Text(s) => $closure_string(s.to_string()),
NnSqlValue::Blob(v) => $closure_blob(v.to_owned()),
NnSqlValue::Boolean(b) => $closure_bool(b.clone()),
NnSqlValue::Timestamp(t) => $closure_timestamp(*t),
NnSqlValue::Duration(d) => $closure_duration(*d),
Expand Down Expand Up @@ -129,6 +134,9 @@ impl Hash for NnSqlValue {
|s: String| {
s.hash(state);
},
|v: Vec<u8>| {
v.hash(state);
},
|b: bool| { b.hash(state) },
|t: SpringTimestamp| { t.hash(state) },
|d: SpringEventDuration| { d.hash(state) }
Expand All @@ -143,6 +151,7 @@ impl Display for NnSqlValue {
|i: i64| i.to_string(),
|f: OrderedFloat<f32>| f.to_string(),
|s: String| format!(r#""{}""#, s),
|v: Vec<u8>| format!("{:?}", v),
|b: bool| (if b { "TRUE" } else { "FALSE" }).to_string(),
|t: SpringTimestamp| t.to_string(),
|d: SpringEventDuration| d.to_string()
Expand Down Expand Up @@ -171,6 +180,7 @@ impl NnSqlValue {
NnSqlValue::BigInt(i64_) => T::try_from_i64(i64_),
NnSqlValue::Float(f32_) => T::try_from_f32(f32_),
NnSqlValue::Text(string) => T::try_from_string(string),
NnSqlValue::Blob(blob) => T::try_from_blob(blob),
NnSqlValue::Boolean(b) => T::try_from_bool(b),
NnSqlValue::Timestamp(t) => T::try_from_timestamp(t),
NnSqlValue::Duration(d) => T::try_from_duration(d),
Expand All @@ -185,6 +195,7 @@ impl NnSqlValue {
NnSqlValue::BigInt(_) => SqlType::big_int(),
NnSqlValue::Float(_) => SqlType::float(),
NnSqlValue::Text(_) => SqlType::text(),
NnSqlValue::Blob(_) => SqlType::blob(),
NnSqlValue::Boolean(_) => SqlType::boolean(),
NnSqlValue::Timestamp(_) => SqlType::timestamp(),
NnSqlValue::Duration(_) => SqlType::duration(),
Expand Down Expand Up @@ -218,6 +229,7 @@ impl NnSqlValue {
self.unpack::<String>().map(|v| v.into_sql_value())
}
},
SqlType::BinaryComparable => self.unpack::<Vec<u8>>().map(|v| v.into_sql_value()),
SqlType::BooleanComparable => self.unpack::<bool>().map(|v| v.into_sql_value()),
SqlType::TimestampComparable => {
self.unpack::<SpringTimestamp>().map(|v| v.into_sql_value())
Expand Down Expand Up @@ -286,6 +298,7 @@ impl NnSqlValue {
NnSqlValue::BigInt(v) => Ok(Self::BigInt(-v)),
NnSqlValue::Float(v) => Ok(Self::Float(-v)),
NnSqlValue::Text(_)
| NnSqlValue::Blob(_)
| NnSqlValue::Boolean(_)
| NnSqlValue::Timestamp(_)
| NnSqlValue::Duration(_) => Err(SpringError::Sql(anyhow!("{} cannot negate", self))),
Expand All @@ -306,6 +319,7 @@ impl From<NnSqlValue> for serde_json::Value {
NnSqlValue::Duration(_) => {
unimplemented!("never appear in stream definition (just an intermediate type)")
}
NnSqlValue::Blob(_) => unimplemented!("cannot convert BLOB data into JSON"),
}
}
}
Expand Down Expand Up @@ -404,4 +418,14 @@ mod tests {

Ok(())
}

#[test]
fn test_unpack_blob() {
assert_eq!(
NnSqlValue::Blob(b"hello".to_vec())
.unpack::<Vec<u8>>()
.unwrap(),
b"hello".to_vec()
);
}
}