Skip to content
Merged
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
7 changes: 2 additions & 5 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2956,10 +2956,8 @@ pub enum Statement {
/// ```sql
/// SET NAMES 'charset_name' [COLLATE 'collation_name']
/// ```
///
/// Note: this is a MySQL-specific statement.
SetNames {
charset_name: String,
charset_name: Ident,
collation_name: Option<String>,
},
/// ```sql
Expand Down Expand Up @@ -4684,8 +4682,7 @@ impl fmt::Display for Statement {
charset_name,
collation_name,
} => {
f.write_str("SET NAMES ")?;
f.write_str(charset_name)?;
write!(f, "SET NAMES {}", charset_name)?;

if let Some(collation) = collation_name {
f.write_str(" COLLATE ")?;
Expand Down
4 changes: 4 additions & 0 deletions src/dialect/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,8 @@ impl Dialect for GenericDialect {
fn supports_match_against(&self) -> bool {
true
}

fn supports_set_names(&self) -> bool {
true
}
}
10 changes: 10 additions & 0 deletions src/dialect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -953,6 +953,16 @@ pub trait Dialect: Debug + Any {
fn supports_order_by_all(&self) -> bool {
false
}

/// Returns true if the dialect supports `SET NAMES <charset_name> [COLLATE <collation_name>]`.
///
/// - [MySQL](https://dev.mysql.com/doc/refman/8.4/en/set-names.html)
/// - [Postgres](https://www.postgresql.org/docs/17/sql-set.html)
///
/// Note: Postgres doesn't support the `COLLATE` clause, but we permissively parse it anyway.
fn supports_set_names(&self) -> bool {
false
}
}

/// This represents the operators for which precedence must be defined
Expand Down
4 changes: 4 additions & 0 deletions src/dialect/mysql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ impl Dialect for MySqlDialect {
fn supports_match_against(&self) -> bool {
true
}

fn supports_set_names(&self) -> bool {
true
}
}

/// `LOCK TABLES`
Expand Down
4 changes: 4 additions & 0 deletions src/dialect/postgresql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,4 +254,8 @@ impl Dialect for PostgreSqlDialect {
fn supports_geometric_types(&self) -> bool {
true
}

fn supports_set_names(&self) -> bool {
true
}
}
8 changes: 4 additions & 4 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10962,14 +10962,14 @@ impl<'a> Parser<'a> {
OneOrManyWithParens::One(self.parse_object_name(false)?)
};

if matches!(&variables, OneOrManyWithParens::One(variable) if variable.to_string().eq_ignore_ascii_case("NAMES")
&& dialect_of!(self is MySqlDialect | GenericDialect))
{
let names = matches!(&variables, OneOrManyWithParens::One(variable) if variable.to_string().eq_ignore_ascii_case("NAMES"));

if names && self.dialect.supports_set_names() {
if self.parse_keyword(Keyword::DEFAULT) {
return Ok(Statement::SetNamesDefault {});
}

let charset_name = self.parse_literal_string()?;
let charset_name = self.parse_identifier()?;
let collation_name = if self.parse_one_of_keywords(&[Keyword::COLLATE]).is_some() {
Some(self.parse_literal_string()?)
} else {
Expand Down
8 changes: 8 additions & 0 deletions tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14617,3 +14617,11 @@ fn parse_array_type_def_with_brackets() {
dialects.verified_stmt("SELECT x::INT[]");
dialects.verified_stmt("SELECT STRING_TO_ARRAY('1,2,3', ',')::INT[3]");
}

#[test]
fn parse_set_names() {
let dialects = all_dialects_where(|d| d.supports_set_names());
dialects.verified_stmt("SET NAMES 'UTF8'");
dialects.verified_stmt("SET NAMES 'utf8'");
dialects.verified_stmt("SET NAMES UTF8 COLLATE bogus");
}
6 changes: 3 additions & 3 deletions tests/sqlparser_mysql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2685,7 +2685,7 @@ fn parse_set_names() {
assert_eq!(
stmt,
Statement::SetNames {
charset_name: "utf8mb4".to_string(),
charset_name: "utf8mb4".into(),
collation_name: None,
}
);
Expand All @@ -2694,7 +2694,7 @@ fn parse_set_names() {
assert_eq!(
stmt,
Statement::SetNames {
charset_name: "utf8mb4".to_string(),
charset_name: "utf8mb4".into(),
collation_name: Some("bogus".to_string()),
}
);
Expand All @@ -2705,7 +2705,7 @@ fn parse_set_names() {
assert_eq!(
stmt,
vec![Statement::SetNames {
charset_name: "utf8mb4".to_string(),
charset_name: "utf8mb4".into(),
collation_name: Some("bogus".to_string()),
}]
);
Expand Down