mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-05-30 11:50:38 +00:00
chore: tune return msg (#2506)
* chore: test return msg * fix: test_child_error Signed-off-by: Ruihang Xia <waynestxia@gmail.com> * chore: fix test * chore: minor fix grpc return value * chore: format return msg * chore: use root error as return value * chore: fix empty err display * chore: iter through external error * chore: remove err msg * chore: remove unused field --------- Signed-off-by: Ruihang Xia <waynestxia@gmail.com> Co-authored-by: Ruihang Xia <waynestxia@gmail.com>
This commit is contained in:
@@ -59,9 +59,8 @@ pub enum Error {
|
||||
UnsupportedDefaultValue { column_name: String, expr: Expr },
|
||||
|
||||
// Syntax error from sql parser.
|
||||
#[snafu(display("Syntax error, sql: {}", sql))]
|
||||
#[snafu(display(""))]
|
||||
Syntax {
|
||||
sql: String,
|
||||
#[snafu(source)]
|
||||
error: ParserError,
|
||||
},
|
||||
|
||||
@@ -37,7 +37,7 @@ impl<'a> ParserContext<'a> {
|
||||
|
||||
let parser = Parser::new(dialect)
|
||||
.try_with_sql(sql)
|
||||
.context(SyntaxSnafu { sql })?;
|
||||
.context(SyntaxSnafu)?;
|
||||
let mut parser_ctx = ParserContext { sql, parser };
|
||||
|
||||
let mut expecting_statement_delimiter = false;
|
||||
@@ -67,12 +67,12 @@ impl<'a> ParserContext<'a> {
|
||||
pub fn parse_function(sql: &'a str, dialect: &dyn Dialect) -> Result<Expr> {
|
||||
let mut parser = Parser::new(dialect)
|
||||
.try_with_sql(sql)
|
||||
.context(SyntaxSnafu { sql })?;
|
||||
.context(SyntaxSnafu)?;
|
||||
|
||||
let function_name = parser.parse_identifier().context(SyntaxSnafu { sql })?;
|
||||
let function_name = parser.parse_identifier().context(SyntaxSnafu)?;
|
||||
parser
|
||||
.parse_function(ObjectName(vec![function_name]))
|
||||
.context(SyntaxSnafu { sql })
|
||||
.context(SyntaxSnafu)
|
||||
}
|
||||
|
||||
/// Parses parser context to a set of statements.
|
||||
@@ -143,7 +143,7 @@ impl<'a> ParserContext<'a> {
|
||||
Err(ParserError::ParserError(format!(
|
||||
"Expected {expected}, found: {found}",
|
||||
)))
|
||||
.context(SyntaxSnafu { sql: self.sql })
|
||||
.context(SyntaxSnafu)
|
||||
}
|
||||
|
||||
pub fn matches_keyword(&mut self, expected: Keyword) -> bool {
|
||||
|
||||
@@ -25,9 +25,7 @@ use crate::statements::statement::Statement;
|
||||
|
||||
impl<'a> ParserContext<'a> {
|
||||
pub(crate) fn parse_alter(&mut self) -> Result<Statement> {
|
||||
let alter_table = self
|
||||
.parse_alter_table()
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
let alter_table = self.parse_alter_table().context(error::SyntaxSnafu)?;
|
||||
Ok(Statement::Alter(alter_table))
|
||||
}
|
||||
|
||||
@@ -98,7 +96,7 @@ impl<'a> ParserContext<'a> {
|
||||
mod tests {
|
||||
use std::assert_matches::assert_matches;
|
||||
|
||||
use snafu::ErrorCompat;
|
||||
use common_error::ext::ErrorExt;
|
||||
use sqlparser::ast::{ColumnOption, DataType};
|
||||
|
||||
use super::*;
|
||||
@@ -215,7 +213,7 @@ mod tests {
|
||||
fn test_parse_alter_drop_column() {
|
||||
let sql = "ALTER TABLE my_metric_1 DROP a";
|
||||
let result = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}).unwrap_err();
|
||||
let err = result.iter_chain().last().unwrap().to_string();
|
||||
let err = result.output_msg();
|
||||
assert!(err.contains("expect keyword COLUMN after ALTER TABLE DROP"));
|
||||
|
||||
let sql = "ALTER TABLE my_metric_1 DROP COLUMN a";
|
||||
@@ -245,7 +243,7 @@ mod tests {
|
||||
fn test_parse_alter_rename_table() {
|
||||
let sql = "ALTER TABLE test_table table_t";
|
||||
let result = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}).unwrap_err();
|
||||
let err = result.iter_chain().last().unwrap().to_string();
|
||||
let err = result.output_msg();
|
||||
assert!(err.contains("expect keyword ADD or DROP or RENAME after ALTER TABLE"));
|
||||
|
||||
let sql = "ALTER TABLE test_table RENAME table_t";
|
||||
|
||||
@@ -57,7 +57,7 @@ impl<'a> ParserContext<'a> {
|
||||
|
||||
self.parser
|
||||
.expect_keyword(Keyword::TO)
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
.context(error::SyntaxSnafu)?;
|
||||
|
||||
let (with, connection, location) = self.parse_copy_to()?;
|
||||
Ok(CopyDatabaseArgument {
|
||||
@@ -89,7 +89,7 @@ impl<'a> ParserContext<'a> {
|
||||
} else {
|
||||
self.parser
|
||||
.expect_keyword(Keyword::FROM)
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
.context(error::SyntaxSnafu)?;
|
||||
Ok(CopyTable::From(self.parse_copy_table_from(table_name)?))
|
||||
}
|
||||
}
|
||||
@@ -107,7 +107,7 @@ impl<'a> ParserContext<'a> {
|
||||
let options = self
|
||||
.parser
|
||||
.parse_options(Keyword::WITH)
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
.context(error::SyntaxSnafu)?;
|
||||
|
||||
let with = options
|
||||
.into_iter()
|
||||
@@ -119,7 +119,7 @@ impl<'a> ParserContext<'a> {
|
||||
let connection_options = self
|
||||
.parser
|
||||
.parse_options(Keyword::CONNECTION)
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
.context(error::SyntaxSnafu)?;
|
||||
|
||||
let connection = connection_options
|
||||
.into_iter()
|
||||
@@ -148,7 +148,7 @@ impl<'a> ParserContext<'a> {
|
||||
let options = self
|
||||
.parser
|
||||
.parse_options(Keyword::WITH)
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
.context(error::SyntaxSnafu)?;
|
||||
|
||||
let with = options
|
||||
.into_iter()
|
||||
@@ -160,7 +160,7 @@ impl<'a> ParserContext<'a> {
|
||||
let connection_options = self
|
||||
.parser
|
||||
.parse_options(Keyword::CONNECTION)
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
.context(error::SyntaxSnafu)?;
|
||||
|
||||
let connection = connection_options
|
||||
.into_iter()
|
||||
|
||||
@@ -69,7 +69,7 @@ impl<'a> ParserContext<'a> {
|
||||
let _ = self.parser.next_token();
|
||||
self.parser
|
||||
.expect_keyword(Keyword::TABLE)
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
.context(error::SyntaxSnafu)?;
|
||||
let if_not_exists =
|
||||
self.parser
|
||||
.parse_keywords(&[Keyword::IF, Keyword::NOT, Keyword::EXISTS]);
|
||||
@@ -86,7 +86,7 @@ impl<'a> ParserContext<'a> {
|
||||
let options = self
|
||||
.parser
|
||||
.parse_options(Keyword::WITH)
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?
|
||||
.context(error::SyntaxSnafu)?
|
||||
.into_iter()
|
||||
.filter_map(|option| {
|
||||
if let Some(v) = parse_option_string(option.value) {
|
||||
@@ -159,7 +159,7 @@ impl<'a> ParserContext<'a> {
|
||||
let options = self
|
||||
.parser
|
||||
.parse_options(Keyword::WITH)
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
.context(error::SyntaxSnafu)?;
|
||||
for option in options.iter() {
|
||||
ensure!(
|
||||
valid_table_option(&option.name.value),
|
||||
@@ -200,7 +200,7 @@ impl<'a> ParserContext<'a> {
|
||||
let column_list = self
|
||||
.parser
|
||||
.parse_parenthesized_column_list(Mandatory, false)
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
.context(error::SyntaxSnafu)?;
|
||||
|
||||
let entries = self.parse_comma_separated(Self::parse_partition_entry)?;
|
||||
|
||||
@@ -219,16 +219,13 @@ impl<'a> ParserContext<'a> {
|
||||
actual: self.peek_token_as_string(),
|
||||
})?;
|
||||
|
||||
let name = self
|
||||
.parser
|
||||
.parse_identifier()
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
let name = self.parser.parse_identifier().context(error::SyntaxSnafu)?;
|
||||
|
||||
self.parser
|
||||
.expect_keyword(Keyword::VALUES)
|
||||
.and_then(|_| self.parser.expect_token(&LESS))
|
||||
.and_then(|_| self.parser.expect_token(&THAN))
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
.context(error::SyntaxSnafu)?;
|
||||
|
||||
let value_list = self.parse_comma_separated(Self::parse_value_list)?;
|
||||
|
||||
@@ -242,10 +239,7 @@ impl<'a> ParserContext<'a> {
|
||||
let _ = self.parser.next_token();
|
||||
SqlValue::Number(MAXVALUE.to_string(), false)
|
||||
}
|
||||
_ => self
|
||||
.parser
|
||||
.parse_value()
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?,
|
||||
_ => self.parser.parse_value().context(error::SyntaxSnafu)?,
|
||||
};
|
||||
Ok(value)
|
||||
}
|
||||
@@ -320,9 +314,7 @@ impl<'a> ParserContext<'a> {
|
||||
columns: &mut Vec<ColumnDef>,
|
||||
constraints: &mut Vec<TableConstraint>,
|
||||
) -> Result<()> {
|
||||
let mut column = self
|
||||
.parse_column_def()
|
||||
.context(SyntaxSnafu { sql: self.sql })?;
|
||||
let mut column = self.parse_column_def().context(SyntaxSnafu)?;
|
||||
|
||||
let mut time_index_opt_idx = None;
|
||||
for (index, opt) in column.options.iter().enumerate() {
|
||||
@@ -496,11 +488,7 @@ impl<'a> ParserContext<'a> {
|
||||
|
||||
fn parse_optional_table_constraint(&mut self) -> Result<Option<TableConstraint>> {
|
||||
let name = if self.parser.parse_keyword(Keyword::CONSTRAINT) {
|
||||
Some(
|
||||
self.parser
|
||||
.parse_identifier()
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?,
|
||||
)
|
||||
Some(self.parser.parse_identifier().context(error::SyntaxSnafu)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -519,7 +507,7 @@ impl<'a> ParserContext<'a> {
|
||||
let columns = self
|
||||
.parser
|
||||
.parse_parenthesized_column_list(Mandatory, false)
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
.context(error::SyntaxSnafu)?;
|
||||
Ok(Some(TableConstraint::Unique {
|
||||
name,
|
||||
columns,
|
||||
@@ -541,7 +529,7 @@ impl<'a> ParserContext<'a> {
|
||||
let columns = self
|
||||
.parser
|
||||
.parse_parenthesized_column_list(Mandatory, false)
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
.context(error::SyntaxSnafu)?;
|
||||
|
||||
ensure!(
|
||||
columns.len() == 1,
|
||||
@@ -837,7 +825,7 @@ mod tests {
|
||||
use std::collections::HashMap;
|
||||
|
||||
use common_catalog::consts::FILE_ENGINE;
|
||||
use snafu::ErrorCompat;
|
||||
use common_error::ext::ErrorExt;
|
||||
use sqlparser::ast::ColumnOption::NotNull;
|
||||
|
||||
use super::*;
|
||||
@@ -1401,10 +1389,7 @@ ENGINE=mito";
|
||||
let result = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {});
|
||||
assert!(result
|
||||
.unwrap_err()
|
||||
.iter_chain()
|
||||
.last()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
.output_msg()
|
||||
.contains("sql parser error: Expected BY, found: RANGE"));
|
||||
|
||||
let sql = r"
|
||||
@@ -1418,10 +1403,7 @@ ENGINE=mito";
|
||||
let result = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {});
|
||||
assert!(result
|
||||
.unwrap_err()
|
||||
.iter_chain()
|
||||
.last()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
.output_msg()
|
||||
.contains("sql parser error: Expected LESS, found: THAN"));
|
||||
|
||||
let sql = r"
|
||||
@@ -1435,10 +1417,7 @@ ENGINE=mito";
|
||||
let result = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {});
|
||||
assert!(result
|
||||
.unwrap_err()
|
||||
.iter_chain()
|
||||
.last()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
.output_msg()
|
||||
.contains("Expected a concrete value, found: MAXVALU"));
|
||||
}
|
||||
|
||||
@@ -1547,7 +1526,7 @@ ENGINE=mito";
|
||||
fn test_invalid_column_name() {
|
||||
let sql = "create table foo(user string, i timestamp time index)";
|
||||
let result = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {});
|
||||
let err = result.unwrap_err().iter_chain().last().unwrap().to_string();
|
||||
let err = result.unwrap_err().output_msg();
|
||||
assert!(err.contains("Cannot use keyword 'user' as column name"));
|
||||
|
||||
// If column name is quoted, it's valid even same with keyword.
|
||||
|
||||
@@ -24,10 +24,7 @@ use crate::statements::statement::Statement;
|
||||
impl<'a> ParserContext<'a> {
|
||||
pub(crate) fn parse_delete(&mut self) -> Result<Statement> {
|
||||
let _ = self.parser.next_token();
|
||||
let spstatement = self
|
||||
.parser
|
||||
.parse_delete()
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
let spstatement = self.parser.parse_delete().context(error::SyntaxSnafu)?;
|
||||
|
||||
match spstatement {
|
||||
SpStatement::Delete { .. } => {
|
||||
|
||||
@@ -24,10 +24,7 @@ use crate::statements::statement::Statement;
|
||||
impl<'a> ParserContext<'a> {
|
||||
pub(crate) fn parse_insert(&mut self) -> Result<Statement> {
|
||||
let _ = self.parser.next_token();
|
||||
let spstatement = self
|
||||
.parser
|
||||
.parse_insert()
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
let spstatement = self.parser.parse_insert().context(error::SyntaxSnafu)?;
|
||||
|
||||
match spstatement {
|
||||
SpStatement::Insert { .. } => {
|
||||
|
||||
@@ -22,10 +22,7 @@ use crate::statements::statement::Statement;
|
||||
impl<'a> ParserContext<'a> {
|
||||
/// Parses select and it's variants.
|
||||
pub(crate) fn parse_query(&mut self) -> Result<Statement> {
|
||||
let spquery = self
|
||||
.parser
|
||||
.parse_query()
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
let spquery = self.parser.parse_query().context(error::SyntaxSnafu)?;
|
||||
|
||||
Ok(Statement::Query(Box::new(Query::try_from(spquery)?)))
|
||||
}
|
||||
@@ -33,7 +30,7 @@ impl<'a> ParserContext<'a> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use snafu::ErrorCompat;
|
||||
use common_error::ext::ErrorExt;
|
||||
|
||||
use crate::dialect::GreptimeDbDialect;
|
||||
use crate::parser::ParserContext;
|
||||
@@ -55,10 +52,7 @@ mod tests {
|
||||
assert!(result.is_err());
|
||||
assert!(result
|
||||
.unwrap_err()
|
||||
.iter_chain()
|
||||
.last()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
.output_msg()
|
||||
.contains("Expected an expression"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,7 @@ impl<'a> ParserContext<'a> {
|
||||
&& w.quote_style.is_none() =>
|
||||
{
|
||||
let _ = self.parser.next_token();
|
||||
self.parse_tql_eval()
|
||||
.context(error::SyntaxSnafu { sql: self.sql })
|
||||
self.parse_tql_eval().context(error::SyntaxSnafu)
|
||||
}
|
||||
|
||||
Keyword::EXPLAIN => {
|
||||
@@ -56,8 +55,7 @@ impl<'a> ParserContext<'a> {
|
||||
|
||||
Keyword::ANALYZE => {
|
||||
let _ = self.parser.next_token();
|
||||
self.parse_tql_analyze()
|
||||
.context(error::SyntaxSnafu { sql: self.sql })
|
||||
self.parse_tql_analyze().context(error::SyntaxSnafu)
|
||||
}
|
||||
_ => self.unsupported(self.peek_token_as_string()),
|
||||
}
|
||||
@@ -136,8 +134,8 @@ impl<'a> ParserContext<'a> {
|
||||
let start = Self::parse_string_or_number(parser, Token::Comma).unwrap_or("0".to_string());
|
||||
let end = Self::parse_string_or_number(parser, Token::Comma).unwrap_or("0".to_string());
|
||||
let step = Self::parse_string_or_number(parser, Token::RParen).unwrap_or("5m".to_string());
|
||||
let query = Self::parse_tql_query(parser, self.sql, delimiter)
|
||||
.context(error::SyntaxSnafu { sql: self.sql })?;
|
||||
let query =
|
||||
Self::parse_tql_query(parser, self.sql, delimiter).context(error::SyntaxSnafu)?;
|
||||
|
||||
Ok(Statement::Tql(Tql::Explain(TqlExplain {
|
||||
query,
|
||||
@@ -166,7 +164,7 @@ impl<'a> ParserContext<'a> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use snafu::ErrorCompat;
|
||||
use common_error::ext::ErrorExt;
|
||||
|
||||
use super::*;
|
||||
use crate::dialect::GreptimeDbDialect;
|
||||
@@ -286,21 +284,11 @@ mod tests {
|
||||
// Invalid duration
|
||||
let sql = "TQL EVAL (1676887657, 1676887659, 1m) http_requests_total{environment=~'staging|testing|development',method!='GET'} @ 1609746000 offset 5m";
|
||||
let result = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}).unwrap_err();
|
||||
assert!(result
|
||||
.iter_chain()
|
||||
.last()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
.contains("Expected ), found: m"));
|
||||
assert!(result.output_msg().contains("Expected ), found: m"));
|
||||
|
||||
// missing end
|
||||
let sql = "TQL EVAL (1676887657, '1m') http_requests_total{environment=~'staging|testing|development',method!='GET'} @ 1609746000 offset 5m";
|
||||
let result = ParserContext::create_with_dialect(sql, &GreptimeDbDialect {}).unwrap_err();
|
||||
assert!(result
|
||||
.iter_chain()
|
||||
.last()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
.contains("Expected ,, found: )"));
|
||||
assert!(result.output_msg().contains("Expected ,, found: )"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user