Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/ast/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2113,8 +2113,7 @@ impl fmt::Display for ColumnOption {
GeneratedAs::ExpStored => "",
};
write!(f, "GENERATED {when} AS IDENTITY")?;
if sequence_options.is_some() {
let so = sequence_options.as_ref().unwrap();
if let Some(so) = sequence_options {
if !so.is_empty() {
write!(f, " (")?;
}
Expand Down
16 changes: 6 additions & 10 deletions src/ast/helpers/stmt_data_loading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,18 +86,14 @@ pub struct StageLoadSelectItem {

impl fmt::Display for StageParamsObject {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let url = &self.url.as_ref();
let storage_integration = &self.storage_integration.as_ref();
let endpoint = &self.endpoint.as_ref();

if url.is_some() {
write!(f, " URL='{}'", url.unwrap())?;
if let Some(ref url) = self.url {
write!(f, " URL='{url}'")?;
}
if storage_integration.is_some() {
write!(f, " STORAGE_INTEGRATION={}", storage_integration.unwrap())?;
if let Some(ref storage_integration) = self.storage_integration {
write!(f, " STORAGE_INTEGRATION={storage_integration}")?;
}
if endpoint.is_some() {
write!(f, " ENDPOINT='{}'", endpoint.unwrap())?;
if let Some(ref endpoint) = self.endpoint {
write!(f, " ENDPOINT='{endpoint}'")?;
}
if !self.credentials.options.is_empty() {
write!(f, " CREDENTIALS=({})", self.credentials)?;
Expand Down
31 changes: 12 additions & 19 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1853,16 +1853,10 @@ impl fmt::Display for Expr {
negated,
} => {
let not_ = if *negated { "NOT " } else { "" };
if form.is_none() {
write!(f, "{expr} IS {not_}NORMALIZED")
if let Some(form) = form {
write!(f, "{} IS {}{} NORMALIZED", expr, not_, form)
} else {
write!(
f,
"{} IS {}{} NORMALIZED",
expr,
not_,
form.as_ref().unwrap()
)
write!(f, "{expr} IS {not_}NORMALIZED")
}
}
Expr::SimilarTo {
Expand Down Expand Up @@ -5741,8 +5735,8 @@ impl fmt::Display for Statement {
write!(f, " SESSION")?;
}
write!(f, " STATUS")?;
if filter.is_some() {
write!(f, " {}", filter.as_ref().unwrap())?;
if let Some(filter) = filter {
write!(f, " {}", filter)?;
}
Ok(())
}
Expand All @@ -5759,8 +5753,8 @@ impl fmt::Display for Statement {
write!(f, " SESSION")?;
}
write!(f, " VARIABLES")?;
if filter.is_some() {
write!(f, " {}", filter.as_ref().unwrap())?;
if let Some(filter) = filter {
write!(f, " {}", filter)?;
}
Ok(())
}
Expand Down Expand Up @@ -6172,8 +6166,8 @@ impl fmt::Display for Statement {
if !copy_options.options.is_empty() {
write!(f, " COPY_OPTIONS=({copy_options})")?;
}
if comment.is_some() {
write!(f, " COMMENT='{}'", comment.as_ref().unwrap())?;
if let Some(comment) = comment {
write!(f, " COMMENT='{}'", comment)?;
}
Ok(())
}
Expand Down Expand Up @@ -6260,12 +6254,11 @@ impl fmt::Display for Statement {
}
Statement::Pragma { name, value, is_eq } => {
write!(f, "PRAGMA {name}")?;
if value.is_some() {
let val = value.as_ref().unwrap();
if let Some(value) = value {
if *is_eq {
write!(f, " = {val}")?;
write!(f, " = {value}")?;
} else {
write!(f, "({val})")?;
write!(f, "({value})")?;
}
}
Ok(())
Expand Down
15 changes: 7 additions & 8 deletions src/ast/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,15 +307,14 @@ pub struct Table {

impl fmt::Display for Table {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(ref schema_name) = self.schema_name {
write!(
f,
"TABLE {}.{}",
schema_name,
self.table_name.as_ref().unwrap(),
)?;
if let Some(ref table_name) = self.table_name {
if let Some(ref schema_name) = self.schema_name {
write!(f, "TABLE {}.{}", schema_name, table_name,)?;
} else {
write!(f, "TABLE {}", table_name)?;
}
} else {
write!(f, "TABLE {}", self.table_name.as_ref().unwrap(),)?;
write!(f, "TABLE")?;
}
Ok(())
}
Expand Down
12 changes: 11 additions & 1 deletion src/ast/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,8 @@ impl fmt::Display for EscapeQuotedString<'_> {
// The quote is not escaped.
// Including idx in the range, so the quote at idx will be printed twice:
// in this call to write_str() and in the next one.
f.write_str(&self.string[start_idx..=idx])?;
let end_idx = idx + ch.len_utf8();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

could we add a test case that fails without this fix?

Copy link
Copy Markdown
Author

@Mrmaxmeier Mrmaxmeier May 5, 2026

Choose a reason for hiding this comment

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

Sure, I've added a test. Notably though, this crash is not reachable with normal sqlparser usage because escape_quoted_string is only called with ASCII quote chars. I've only encountered this due to the way I'm using sqlparser for my input generation experiments.

f.write_str(&self.string[start_idx..end_idx])?;
start_idx = idx;
}
}
Expand Down Expand Up @@ -707,3 +708,12 @@ impl fmt::Display for TrimWhereField {
})
}
}

#[cfg(test)]
#[test]
fn test_escape_quoted_string_with_multibyte_quote_char() {
assert_eq!(
format!("{}", escape_quoted_string("a🦀b🦀c", '🦀')),
"a🦀🦀b🦀🦀c"
);
}
2 changes: 1 addition & 1 deletion src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1009,7 +1009,7 @@ impl<'a> Parser<'a> {
FlushType::OptimizerCosts
} else if self.parse_keywords(&[Keyword::RELAY, Keyword::LOGS]) {
if self.parse_keywords(&[Keyword::FOR, Keyword::CHANNEL]) {
channel = Some(self.parse_object_name(false).unwrap().to_string());
channel = Some(self.parse_object_name(false)?.to_string());
}
FlushType::RelayLogs
} else if self.parse_keywords(&[Keyword::SLOW, Keyword::LOGS]) {
Expand Down