Skip to content

fix(spans): Catch panic when parsing SQL#3064

Merged
jjbayer merged 3 commits intomasterfrom
fix/sql-panic
Feb 8, 2024
Merged

fix(spans): Catch panic when parsing SQL#3064
jjbayer merged 3 commits intomasterfrom
fix/sql-panic

Conversation

@jjbayer
Copy link
Member

@jjbayer jjbayer commented Feb 6, 2024

This PR reapplies #3057, which was reverted because of panics.

As a workaround, catch unwind panics so we can collect panic cases and report them upstream.

#skip-changelog (false positive)

The `sqlparser` lib has been on a fork since
#2846. We can now go back to the
official version because
apache/datafusion-sqlparser-rs#1065 has been merged &
released.
Comment on lines +885 to +888
scrub_sql_test!(
replace_into_set_dont_panic,
r#"REPLACE INTO `foo` SET x = y"#,
"REPLACE INTO foo SET x = y"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without the catch_unwind, this test made parse_query panic.

Comment on lines +34 to +38
relay_log::error!(
tags.db_system = db_system,
query = query,
"parse_query panicked",
);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will help us collect cases that we can then fix upstream.

@jjbayer jjbayer marked this pull request as ready for review February 8, 2024 08:03
@jjbayer jjbayer requested a review from a team as a code owner February 8, 2024 08:03
) -> Result<Vec<Statement>, sqlparser::parser::ParserError> {
match std::panic::catch_unwind(|| parse_query_inner(db_system, query)) {
Ok(res) => res,
Err(_) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the error not contain interesting information (maybe a stacktrace)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It probably does, but how do I extract it? The error type is Box<dyn Any + Send>.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually misread the return type. It contains whatever was passed to panic!() (almost always some kind of string):

fn main() {
    if let Err(e) = std::panic::catch_unwind(|| panic!("test")) {
        println!("oops {:?}", e.downcast_ref::<&'static str>());
    }
    
    let r = 123;
    if let Err(e) = std::panic::catch_unwind(|| panic!("oops {r}")) {
        println!("oops {:?}", e.downcast_ref::<String>());
    }
}

So in our case it could be useful but most likely it's just a unwrap() somewhere.

Copy link
Contributor

@olksdr olksdr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@jjbayer jjbayer merged commit c18b04e into master Feb 8, 2024
@jjbayer jjbayer deleted the fix/sql-panic branch February 8, 2024 11:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants