Skip to content

Commit fc0f847

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 3014f8c commit fc0f847

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
@@ -934,6 +934,7 @@ define_keywords!(
934934
SESSION_USER,
935935
SET,
936936
SETERROR,
937+
SETOF,
937938
SETS,
938939
SETTINGS,
939940
SHARE,

src/parser/mod.rs

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

55915591
let return_type = if self.parse_keyword(Keyword::RETURNS) {
5592-
Some(self.parse_data_type()?)
5592+
let setof = self.parse_keyword(Keyword::SETOF);
5593+
let return_type = self.parse_data_type()?;
5594+
Some(if setof {
5595+
DataType::SetOf(Box::new(return_type))
5596+
} else {
5597+
return_type
5598+
})
55935599
} else {
55945600
None
55955601
};

0 commit comments

Comments
 (0)