Skip to content

Commit 13822ab

Browse files
parser(postgres): support RETURNS SETOF in CREATE FUNCTION
Add a dedicated SETOF data type wrapper in the AST, teach the PostgreSQL CREATE FUNCTION parser to wrap return types after RETURNS SETOF, and register SETOF in the keyword table so parsing no longer relies on raw NoKeyword text matching.
1 parent 31e1942 commit 13822ab

File tree

3 files changed

+13
-1
lines changed

3 files changed

+13
-1
lines changed

src/ast/data_type.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ pub enum EnumMember {
4747
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4848
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4949
pub enum DataType {
50+
/// Set-returning function type in [PostgreSQL], e.g. CREATE FUNCTION RETURNS SETOF UUID.
51+
///
52+
/// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-createfunction.html
53+
SetOf(Box<DataType>),
5054
/// Table type in [PostgreSQL], e.g. CREATE FUNCTION RETURNS TABLE(...).
5155
///
5256
/// [PostgreSQL]: https://www.postgresql.org/docs/15/sql-createfunction.html
@@ -501,6 +505,7 @@ pub enum DataType {
501505
impl fmt::Display for DataType {
502506
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
503507
match self {
508+
DataType::SetOf(data_type) => write!(f, "SETOF {data_type}"),
504509
DataType::Character(size) => format_character_string_type(f, "CHARACTER", size),
505510
DataType::Char(size) => format_character_string_type(f, "CHAR", size),
506511
DataType::CharacterVarying(size) => {

src/keywords.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,7 @@ define_keywords!(
933933
SESSION_USER,
934934
SET,
935935
SETERROR,
936+
SETOF,
936937
SETS,
937938
SETTINGS,
938939
SHARE,

src/parser/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5581,7 +5581,13 @@ impl<'a> Parser<'a> {
55815581
self.expect_token(&Token::RParen)?;
55825582

55835583
let return_type = if self.parse_keyword(Keyword::RETURNS) {
5584-
Some(self.parse_data_type()?)
5584+
let setof = self.parse_keyword(Keyword::SETOF);
5585+
let return_type = self.parse_data_type()?;
5586+
Some(if setof {
5587+
DataType::SetOf(Box::new(return_type))
5588+
} else {
5589+
return_type
5590+
})
55855591
} else {
55865592
None
55875593
};

0 commit comments

Comments
 (0)