-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
8 changed files
with
192 additions
and
119 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
name = "peer-ast" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
anyhow = "1.0" | ||
pt = { path = "../pt" } | ||
rust_decimal.workspace = true | ||
sqlparser.workspace = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
use sqlparser::ast::{Array, ArrayElemTypeDef, DataType, Expr}; | ||
|
||
/// Flatten Cast EXPR to List with right value type | ||
/// For example Value(SingleQuotedString("{hash1,hash2}") must return | ||
/// a vector Value(SingleQuotedString("hash1"), Value(SingleQuotedString("hash2"))) | ||
pub fn flatten_expr_to_in_list(expr: &Expr) -> anyhow::Result<Vec<Expr>> { | ||
let mut list = vec![]; | ||
// check if expr is of type Cast | ||
if let Expr::Cast { | ||
expr, data_type, .. | ||
} = expr | ||
{ | ||
// assert that expr is of type SingleQuotedString | ||
if let Expr::Value(sqlparser::ast::Value::SingleQuotedString(s)) = expr.as_ref() { | ||
// trim the starting and ending curly braces | ||
let s = s.trim_start_matches('{').trim_end_matches('}'); | ||
// split string by comma | ||
let split = s.split(','); | ||
// match on data type, and create a vector of Expr::Value | ||
match data_type { | ||
DataType::Array(ArrayElemTypeDef::AngleBracket(inner)) | ||
| DataType::Array(ArrayElemTypeDef::SquareBracket(inner)) => match inner.as_ref() { | ||
DataType::Text | DataType::Char(_) | DataType::Varchar(_) => { | ||
for s in split { | ||
list.push(Expr::Value(sqlparser::ast::Value::SingleQuotedString( | ||
s.to_string(), | ||
))); | ||
} | ||
} | ||
DataType::Integer(_) | ||
| DataType::Float(_) | ||
| DataType::BigInt(_) | ||
| DataType::UnsignedBigInt(_) | ||
| DataType::UnsignedInteger(_) | ||
| DataType::UnsignedSmallInt(_) | ||
| DataType::UnsignedTinyInt(_) | ||
| DataType::TinyInt(_) | ||
| DataType::UnsignedInt(_) => { | ||
for s in split { | ||
list.push(Expr::Value(sqlparser::ast::Value::Number( | ||
s.to_string(), | ||
false, | ||
))); | ||
} | ||
} | ||
_ => { | ||
return Err(anyhow::anyhow!( | ||
"Unsupported inner data type for IN list: {:?}", | ||
data_type | ||
)) | ||
} | ||
}, | ||
_ => { | ||
return Err(anyhow::anyhow!( | ||
"Unsupported data type for IN list: {:?}", | ||
data_type | ||
)) | ||
} | ||
} | ||
} else if let Expr::Array(arr) = expr.as_ref() { | ||
list = pour_array_into_list(arr, list).expect("Failed to transfer array to list"); | ||
} | ||
} else if let Expr::Array(arr) = expr { | ||
list = pour_array_into_list(arr, list).expect("Failed to transfer array to list"); | ||
} | ||
|
||
Ok(list) | ||
} | ||
|
||
fn pour_array_into_list(arr: &Array, mut list: Vec<Expr>) -> anyhow::Result<Vec<Expr>> { | ||
for element in &arr.elem { | ||
match &element { | ||
Expr::Value(val) => match val { | ||
sqlparser::ast::Value::Number(_, _) => { | ||
list.push(Expr::Value(sqlparser::ast::Value::Number( | ||
element.to_string(), | ||
false, | ||
))); | ||
} | ||
sqlparser::ast::Value::SingleQuotedString(_) => { | ||
list.push(Expr::Value(sqlparser::ast::Value::UnQuotedString( | ||
element.to_string(), | ||
))); | ||
} | ||
_ => { | ||
return Err(anyhow::anyhow!( | ||
"Unsupported data type for IN list: {:?}", | ||
val | ||
)) | ||
} | ||
}, | ||
_ => { | ||
return Err(anyhow::anyhow!( | ||
"Unsupported element for IN list: {:?}", | ||
element | ||
)) | ||
} | ||
} | ||
} | ||
Ok(list) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.