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:
shuiyisong
2023-09-27 18:40:25 +08:00
committed by GitHub
parent 9282e59a3b
commit ee8d472aae
32 changed files with 138 additions and 191 deletions

View File

@@ -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,
},

View File

@@ -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 {

View File

@@ -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";

View File

@@ -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()

View File

@@ -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.

View File

@@ -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 { .. } => {

View File

@@ -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 { .. } => {

View File

@@ -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"));
}
}

View File

@@ -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: )"));
}
}