From 7e4d871efd45286fe4662abf6ba0f41c2f4b0729 Mon Sep 17 00:00:00 2001 From: LucaCappelletti94 Date: Mon, 9 Nov 2026 12:19:23 +0100 Subject: [PATCH] PostgreSQL: Support `NATIONAL CHAR VARYING` --- src/ast/data_type.rs | 7 +++++++ src/parser/mod.rs | 17 ++++++++++++++--- tests/sqlparser_common.rs | 1 + 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/ast/data_type.rs b/src/ast/data_type.rs index fb444a8732..3c49817194 100644 --- a/src/ast/data_type.rs +++ b/src/ast/data_type.rs @@ -108,6 +108,10 @@ pub enum DataType { /// /// [SQL Standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#national-character-string-type NationalChar(Option), + /// National char varying type, e.g. NATIONAL CHAR VARYING(10), [SQL Standard]. + /// + /// [SQL Standard]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#national-character-string-type + NationalCharVarying(Option), /// Uuid type. Uuid, /// Large character object with optional length, @@ -562,6 +566,9 @@ impl fmt::Display for DataType { format_character_string_type(f, "NATIONAL CHARACTER VARYING", size) } DataType::NationalChar(size) => format_character_string_type(f, "NATIONAL CHAR", size), + DataType::NationalCharVarying(size) => { + format_character_string_type(f, "NATIONAL CHAR VARYING", size) + } DataType::Uuid => write!(f, "UUID"), DataType::CharacterLargeObject(size) => { format_type_with_optional_length(f, "CHARACTER LARGE OBJECT", size, false) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 3a23683326..26d78d09f1 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -13867,9 +13867,15 @@ impl<'a> Parser<'a> { } Keyword::NATIONAL if self.peek_keyword(Keyword::CHAR) => { let _ = self.parse_keyword(Keyword::CHAR); - Ok(DataType::NationalChar( - self.parse_optional_character_length()?, - )) + if self.parse_keyword(Keyword::VARYING) { + Ok(DataType::NationalCharVarying( + self.parse_optional_character_length()?, + )) + } else { + Ok(DataType::NationalChar( + self.parse_optional_character_length()?, + )) + } } Keyword::CLOB => Ok(DataType::Clob(self.parse_optional_precision()?)), Keyword::BINARY => Ok(DataType::Binary(self.parse_optional_precision()?)), @@ -23084,6 +23090,11 @@ mod tests { ); test_parse_data_type!(dialect, "NATIONAL CHAR", DataType::NationalChar(None)); test_parse_data_type!(dialect, "NATIONAL CHAR(20)", DataType::NationalChar(length)); + test_parse_data_type!( + dialect, + "NATIONAL CHAR VARYING(20)", + DataType::NationalCharVarying(length) + ); } #[test] diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 50bbb13b4f..491d320b49 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -23492,6 +23492,7 @@ fn parse_national_character_string_types() { "NATIONAL CHARACTER VARYING(4)", "NATIONAL CHAR", "NATIONAL CHAR(4)", + "NATIONAL CHAR VARYING(4)", ] { dialects.verified_stmt(&format!("CREATE TABLE t (c {data_type})")); dialects.verified_expr(&format!("CAST('ab' AS {data_type})"));