mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-07-07 17:04:59 +00:00
Parse SET NAMES syntax in Postgres (#1752)
This commit is contained in:
parent
a629ddf89b
commit
9e09b617e8
8 changed files with 39 additions and 12 deletions
|
@ -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
|
||||
|
@ -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 ")?;
|
||||
|
|
|
@ -155,4 +155,8 @@ impl Dialect for GenericDialect {
|
|||
fn supports_match_against(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn supports_set_names(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -980,6 +980,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
|
||||
|
|
|
@ -137,6 +137,10 @@ impl Dialect for MySqlDialect {
|
|||
fn supports_match_against(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn supports_set_names(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// `LOCK TABLES`
|
||||
|
|
|
@ -254,4 +254,8 @@ impl Dialect for PostgreSqlDialect {
|
|||
fn supports_geometric_types(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn supports_set_names(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -14631,3 +14631,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");
|
||||
}
|
||||
|
|
|
@ -2696,7 +2696,7 @@ fn parse_set_names() {
|
|||
assert_eq!(
|
||||
stmt,
|
||||
Statement::SetNames {
|
||||
charset_name: "utf8mb4".to_string(),
|
||||
charset_name: "utf8mb4".into(),
|
||||
collation_name: None,
|
||||
}
|
||||
);
|
||||
|
@ -2705,7 +2705,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()),
|
||||
}
|
||||
);
|
||||
|
@ -2716,7 +2716,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()),
|
||||
}]
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue