mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-05-23 08:20:36 +00:00
chore: update datafusion to 50 (#7076)
* chore: update datafusion to 50 Signed-off-by: luofucong <luofc@foxmail.com> * fix ci Signed-off-by: luofucong <luofc@foxmail.com> * fix: update datafusion_pg_catalog import * chore: fix toml format * chore: fix toml format again * fix nextest Signed-off-by: luofucong <luofc@foxmail.com> * fix sqlness Signed-off-by: luofucong <luofc@foxmail.com> * chore: switch datafusion-orc to upstream tag * fix sqlness Signed-off-by: luofucong <luofc@foxmail.com> * resolve PR comments Signed-off-by: luofucong <luofc@foxmail.com> --------- Signed-off-by: luofucong <luofc@foxmail.com> Co-authored-by: Ning Sun <sunning@greptime.com>
This commit is contained in:
@@ -25,7 +25,10 @@ pub trait ObjectNamePartExt {
|
||||
|
||||
impl ObjectNamePartExt for ObjectNamePart {
|
||||
fn to_string_unquoted(&self) -> String {
|
||||
let ObjectNamePart::Identifier(ident) = self;
|
||||
let ObjectNamePart::Identifier(ident) = self else {
|
||||
// If it's not an ident, just return it as a string.
|
||||
return self.to_string();
|
||||
};
|
||||
ident.value.clone()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,15 +14,15 @@
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
use snafu::ResultExt;
|
||||
use sqlparser::ast::{Ident, ObjectNamePart, Query, Value};
|
||||
use snafu::{OptionExt, ResultExt};
|
||||
use sqlparser::ast::{Ident, Query, Value};
|
||||
use sqlparser::dialect::Dialect;
|
||||
use sqlparser::keywords::Keyword;
|
||||
use sqlparser::parser::{Parser, ParserError, ParserOptions};
|
||||
use sqlparser::tokenizer::{Token, TokenWithSpan};
|
||||
|
||||
use crate::ast::{Expr, ObjectName};
|
||||
use crate::error::{self, Result, SyntaxSnafu};
|
||||
use crate::error::{self, InvalidSqlSnafu, Result, SyntaxSnafu};
|
||||
use crate::parsers::tql_parser;
|
||||
use crate::statements::kill::Kill;
|
||||
use crate::statements::statement::Statement;
|
||||
@@ -106,7 +106,7 @@ impl ParserContext<'_> {
|
||||
expected: "a table name",
|
||||
actual: self.parser.peek_token().to_string(),
|
||||
})?;
|
||||
Ok(Self::canonicalize_object_name(raw_table_name))
|
||||
Self::canonicalize_object_name(raw_table_name)
|
||||
}
|
||||
|
||||
pub fn parse_function(sql: &str, dialect: &dyn Dialect) -> Result<Expr> {
|
||||
@@ -303,17 +303,20 @@ impl ParserContext<'_> {
|
||||
}
|
||||
|
||||
/// Like [canonicalize_identifier] but for [ObjectName].
|
||||
pub fn canonicalize_object_name(object_name: ObjectName) -> ObjectName {
|
||||
pub(crate) fn canonicalize_object_name(object_name: ObjectName) -> Result<ObjectName> {
|
||||
object_name
|
||||
.0
|
||||
.into_iter()
|
||||
.map(|x| {
|
||||
let ObjectNamePart::Identifier(ident) = x;
|
||||
ident
|
||||
x.as_ident()
|
||||
.cloned()
|
||||
.map(Self::canonicalize_identifier)
|
||||
.with_context(|| InvalidSqlSnafu {
|
||||
msg: format!("not an ident: '{x}'"),
|
||||
})
|
||||
})
|
||||
.map(Self::canonicalize_identifier)
|
||||
.collect::<Vec<_>>()
|
||||
.into()
|
||||
.collect::<Result<Vec<_>>>()
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
/// Simply a shortcut for sqlparser's same name method `parse_object_name`,
|
||||
|
||||
@@ -68,7 +68,7 @@ impl ParserContext<'_> {
|
||||
.parser
|
||||
.parse_object_name(false)
|
||||
.context(error::SyntaxSnafu)?;
|
||||
let database_name = Self::canonicalize_object_name(database_name);
|
||||
let database_name = Self::canonicalize_object_name(database_name)?;
|
||||
|
||||
match self.parser.peek_token().token {
|
||||
Token::Word(w) => {
|
||||
@@ -117,7 +117,7 @@ impl ParserContext<'_> {
|
||||
.parser
|
||||
.parse_object_name(false)
|
||||
.context(error::SyntaxSnafu)?;
|
||||
let table_name = Self::canonicalize_object_name(raw_table_name);
|
||||
let table_name = Self::canonicalize_object_name(raw_table_name)?;
|
||||
|
||||
let alter_operation = match self.parser.peek_token().token {
|
||||
Token::Word(w) => {
|
||||
@@ -145,7 +145,7 @@ impl ParserContext<'_> {
|
||||
let new_table_name_obj_raw =
|
||||
self.parse_object_name().context(error::SyntaxSnafu)?;
|
||||
let new_table_name_obj =
|
||||
Self::canonicalize_object_name(new_table_name_obj_raw);
|
||||
Self::canonicalize_object_name(new_table_name_obj_raw)?;
|
||||
let new_table_name = match &new_table_name_obj.0[..] {
|
||||
[table] => table.to_string_unquoted(),
|
||||
_ => {
|
||||
|
||||
@@ -104,7 +104,7 @@ impl ParserContext<'_> {
|
||||
expected: "a table name",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
let table_name = Self::canonicalize_object_name(raw_table_name);
|
||||
let table_name = Self::canonicalize_object_name(raw_table_name)?;
|
||||
|
||||
if self.parser.parse_keyword(Keyword::TO) {
|
||||
let (with, connection, location, limit) = self.parse_copy_parameters()?;
|
||||
|
||||
@@ -196,7 +196,7 @@ impl<'a> ParserContext<'a> {
|
||||
expected: "a database name",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
let database_name = Self::canonicalize_object_name(database_name);
|
||||
let database_name = Self::canonicalize_object_name(database_name)?;
|
||||
|
||||
let options = self
|
||||
.parser
|
||||
@@ -2435,8 +2435,7 @@ non TIMESTAMP(6) TIME INDEX,
|
||||
let sql = "CREATE VIEW test AS DELETE from demo";
|
||||
let result =
|
||||
ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}, ParseOptions::default());
|
||||
assert!(result.is_err());
|
||||
assert_matches!(result, Err(crate::error::Error::Syntax { .. }));
|
||||
assert!(result.is_ok_and(|x| x.len() == 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -51,7 +51,7 @@ impl ParserContext<'_> {
|
||||
let query_stmt = self.parse_query()?;
|
||||
match query_stmt {
|
||||
Statement::Query(query) => Ok(Statement::DeclareCursor(DeclareCursor {
|
||||
cursor_name: ParserContext::canonicalize_object_name(cursor_name),
|
||||
cursor_name: ParserContext::canonicalize_object_name(cursor_name)?,
|
||||
query,
|
||||
})),
|
||||
_ => error::InvalidSqlSnafu {
|
||||
@@ -78,7 +78,7 @@ impl ParserContext<'_> {
|
||||
.context(error::SyntaxSnafu)?;
|
||||
|
||||
Ok(Statement::FetchCursor(FetchCursor {
|
||||
cursor_name: ParserContext::canonicalize_object_name(cursor_name),
|
||||
cursor_name: ParserContext::canonicalize_object_name(cursor_name)?,
|
||||
fetch_size,
|
||||
}))
|
||||
}
|
||||
@@ -91,7 +91,7 @@ impl ParserContext<'_> {
|
||||
.context(error::SyntaxSnafu)?;
|
||||
|
||||
Ok(Statement::CloseCursor(CloseCursor {
|
||||
cursor_name: ParserContext::canonicalize_object_name(cursor_name),
|
||||
cursor_name: ParserContext::canonicalize_object_name(cursor_name)?,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ impl ParserContext<'_> {
|
||||
expected: "a table name",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
let table_idents = Self::canonicalize_object_name(raw_table_idents);
|
||||
let table_idents = Self::canonicalize_object_name(raw_table_idents)?;
|
||||
ensure!(
|
||||
!table_idents.0.is_empty(),
|
||||
InvalidTableNameSnafu {
|
||||
|
||||
@@ -58,7 +58,7 @@ impl ParserContext<'_> {
|
||||
expected: "a trigger name",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
let trigger_ident = Self::canonicalize_object_name(raw_trigger_ident);
|
||||
let trigger_ident = Self::canonicalize_object_name(raw_trigger_ident)?;
|
||||
ensure!(
|
||||
!trigger_ident.0.is_empty(),
|
||||
error::InvalidTriggerNameSnafu {
|
||||
@@ -82,7 +82,7 @@ impl ParserContext<'_> {
|
||||
expected: "a view name",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
let view_ident = Self::canonicalize_object_name(raw_view_ident);
|
||||
let view_ident = Self::canonicalize_object_name(raw_view_ident)?;
|
||||
ensure!(
|
||||
!view_ident.0.is_empty(),
|
||||
InvalidTableNameSnafu {
|
||||
@@ -106,7 +106,7 @@ impl ParserContext<'_> {
|
||||
expected: "a flow name",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
let flow_ident = Self::canonicalize_object_name(raw_flow_ident);
|
||||
let flow_ident = Self::canonicalize_object_name(raw_flow_ident)?;
|
||||
ensure!(
|
||||
!flow_ident.0.is_empty(),
|
||||
InvalidFlowNameSnafu {
|
||||
@@ -129,7 +129,7 @@ impl ParserContext<'_> {
|
||||
expected: "a table name",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
let table_ident = Self::canonicalize_object_name(raw_table_ident);
|
||||
let table_ident = Self::canonicalize_object_name(raw_table_ident)?;
|
||||
ensure!(
|
||||
!table_ident.0.is_empty(),
|
||||
InvalidTableNameSnafu {
|
||||
@@ -155,7 +155,7 @@ impl ParserContext<'_> {
|
||||
expected: "a database name",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
let database_name = Self::canonicalize_object_name(database_name);
|
||||
let database_name = Self::canonicalize_object_name(database_name)?;
|
||||
|
||||
Ok(Statement::DropDatabase(DropDatabase::new(
|
||||
database_name,
|
||||
|
||||
@@ -73,6 +73,7 @@ mod tests {
|
||||
projection: vec![sqlparser::ast::SelectItem::Wildcard(
|
||||
WildcardAdditionalOptions::default(),
|
||||
)],
|
||||
exclude: None,
|
||||
into: None,
|
||||
from: vec![sqlparser::ast::TableWithJoins {
|
||||
relation: sqlparser::ast::TableFactor::Table {
|
||||
@@ -112,9 +113,8 @@ mod tests {
|
||||
with: None,
|
||||
body: Box::new(sqlparser::ast::SetExpr::Select(Box::new(select))),
|
||||
order_by: None,
|
||||
limit: None,
|
||||
limit_by: vec![],
|
||||
offset: None,
|
||||
limit_clause: None,
|
||||
pipe_operators: vec![],
|
||||
fetch: None,
|
||||
locks: vec![],
|
||||
for_clause: None,
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
use snafu::ResultExt;
|
||||
use sqlparser::ast::Statement as SpStatement;
|
||||
use sqlparser::ast::{Set, Statement as SpStatement};
|
||||
|
||||
use crate::ast::{Ident, ObjectName};
|
||||
use crate::error::{self, Result};
|
||||
@@ -27,21 +27,27 @@ impl ParserContext<'_> {
|
||||
let _ = self.parser.next_token();
|
||||
let spstatement = self.parser.parse_set().context(error::SyntaxSnafu)?;
|
||||
match spstatement {
|
||||
SpStatement::SetVariable {
|
||||
variables,
|
||||
value,
|
||||
hivevar,
|
||||
..
|
||||
} if !hivevar => Ok(Statement::SetVariables(SetVariables {
|
||||
variable: (*variables)[0].clone(),
|
||||
value,
|
||||
})),
|
||||
SpStatement::Set(set) => match set {
|
||||
Set::SingleAssignment {
|
||||
scope: _,
|
||||
hivevar,
|
||||
variable,
|
||||
values,
|
||||
} if !hivevar => Ok(Statement::SetVariables(SetVariables {
|
||||
variable,
|
||||
value: values,
|
||||
})),
|
||||
|
||||
SpStatement::SetTimeZone { value, .. } => Ok(Statement::SetVariables(SetVariables {
|
||||
variable: ObjectName::from(vec![Ident::new("TIMEZONE")]),
|
||||
value: vec![value],
|
||||
})),
|
||||
Set::SetTimeZone { local: _, value } => Ok(Statement::SetVariables(SetVariables {
|
||||
variable: ObjectName::from(vec![Ident::new("TIMEZONE")]),
|
||||
value: vec![value],
|
||||
})),
|
||||
|
||||
set => error::UnsupportedSnafu {
|
||||
keyword: set.to_string(),
|
||||
}
|
||||
.fail(),
|
||||
},
|
||||
unexp => error::UnsupportedSnafu {
|
||||
keyword: unexp.to_string(),
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ impl ParserContext<'_> {
|
||||
expected: "a database name",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
let database_name = Self::canonicalize_object_name(raw_database_name);
|
||||
let database_name = Self::canonicalize_object_name(raw_database_name)?;
|
||||
ensure!(
|
||||
!database_name.0.is_empty(),
|
||||
InvalidDatabaseNameSnafu {
|
||||
@@ -168,7 +168,7 @@ impl ParserContext<'_> {
|
||||
expected: "a table name",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
let table_name = Self::canonicalize_object_name(raw_table_name);
|
||||
let table_name = Self::canonicalize_object_name(raw_table_name)?;
|
||||
ensure!(
|
||||
!table_name.0.is_empty(),
|
||||
InvalidTableNameSnafu {
|
||||
@@ -197,7 +197,7 @@ impl ParserContext<'_> {
|
||||
expected: "a flow name",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
let flow_name = Self::canonicalize_object_name(raw_flow_name);
|
||||
let flow_name = Self::canonicalize_object_name(raw_flow_name)?;
|
||||
ensure!(
|
||||
!flow_name.0.is_empty(),
|
||||
InvalidFlowNameSnafu {
|
||||
@@ -214,7 +214,7 @@ impl ParserContext<'_> {
|
||||
expected: "a view name",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
let view_name = Self::canonicalize_object_name(raw_view_name);
|
||||
let view_name = Self::canonicalize_object_name(raw_view_name)?;
|
||||
ensure!(
|
||||
!view_name.0.is_empty(),
|
||||
InvalidTableNameSnafu {
|
||||
@@ -241,7 +241,7 @@ impl ParserContext<'_> {
|
||||
);
|
||||
|
||||
// Safety: already checked above
|
||||
Ok(Self::canonicalize_object_name(table_name).0[0].to_string_unquoted())
|
||||
Ok(Self::canonicalize_object_name(table_name)?.0[0].to_string_unquoted())
|
||||
}
|
||||
|
||||
fn parse_db_name(&mut self) -> Result<Option<String>> {
|
||||
@@ -262,7 +262,7 @@ impl ParserContext<'_> {
|
||||
|
||||
// Safety: already checked above
|
||||
Ok(Some(
|
||||
Self::canonicalize_object_name(db_name).0[0].to_string_unquoted(),
|
||||
Self::canonicalize_object_name(db_name)?.0[0].to_string_unquoted(),
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ impl ParserContext<'_> {
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
|
||||
let trigger_name = Self::canonicalize_object_name(trigger_name);
|
||||
let trigger_name = Self::canonicalize_object_name(trigger_name)?;
|
||||
|
||||
ensure!(
|
||||
!trigger_name.0.is_empty(),
|
||||
|
||||
@@ -33,7 +33,7 @@ impl ParserContext<'_> {
|
||||
expected: "a table name",
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
let table_ident = Self::canonicalize_object_name(raw_table_ident);
|
||||
let table_ident = Self::canonicalize_object_name(raw_table_ident)?;
|
||||
|
||||
ensure!(
|
||||
!table_ident.0.is_empty(),
|
||||
|
||||
@@ -75,7 +75,7 @@ pub fn parser_expr_to_scalar_value_literal(
|
||||
// 1. convert parser expr to logical expr
|
||||
let empty_df_schema = DFSchema::empty();
|
||||
let logical_expr = SqlToRel::new(&StubContextProvider::default())
|
||||
.sql_to_expr(expr.into(), &empty_df_schema, &mut Default::default())
|
||||
.sql_to_expr(expr, &empty_df_schema, &mut Default::default())
|
||||
.context(ConvertToLogicalExpressionSnafu)?;
|
||||
|
||||
struct FindNow {
|
||||
|
||||
@@ -310,6 +310,6 @@ impl TryFrom<&Statement> for DfStatement {
|
||||
.fail();
|
||||
}
|
||||
};
|
||||
Ok(DfStatement::Statement(Box::new(s.into())))
|
||||
Ok(DfStatement::Statement(Box::new(s)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ fn extract_tables_from_set_expr(set_expr: &SetExpr, names: &mut HashSet<ObjectNa
|
||||
extract_tables_from_set_expr(left, names);
|
||||
extract_tables_from_set_expr(right, names);
|
||||
}
|
||||
SetExpr::Values(_) | SetExpr::Insert(_) | SetExpr::Update(_) | SetExpr::Table(_) => {}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user