Skip to content

Commit 83de58e

Browse files
committed
Add SETOF support for PostgreSQL function return types
1 parent 8e36e8e commit 83de58e

File tree

4 files changed

+35
-1
lines changed

4 files changed

+35
-1
lines changed

src/ast/data_type.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ pub enum DataType {
6161
/// Table columns.
6262
columns: Vec<ColumnDef>,
6363
},
64+
/// SETOF type modifier for PostgreSQL function return types,
65+
/// e.g. `CREATE FUNCTION ... RETURNS SETOF text`.
66+
///
67+
/// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-createfunction.html
68+
SetOf(Box<DataType>),
6469
/// Fixed-length character type, e.g. CHARACTER(10).
6570
Character(Option<CharacterLength>),
6671
/// Fixed-length char type, e.g. CHAR(10).
@@ -808,6 +813,7 @@ impl fmt::Display for DataType {
808813
DataType::NamedTable { name, columns } => {
809814
write!(f, "{} TABLE ({})", name, display_comma_separated(columns))
810815
}
816+
DataType::SetOf(inner) => write!(f, "SETOF {inner}"),
811817
DataType::GeometricType(kind) => write!(f, "{kind}"),
812818
DataType::TsVector => write!(f, "TSVECTOR"),
813819
DataType::TsQuery => write!(f, "TSQUERY"),

src/keywords.rs

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

src/parser/mod.rs

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

54905490
let return_type = if self.parse_keyword(Keyword::RETURNS) {
5491-
Some(self.parse_data_type()?)
5491+
let is_setof = self.parse_keyword(Keyword::SETOF);
5492+
let base_type = self.parse_data_type()?;
5493+
Some(if is_setof {
5494+
DataType::SetOf(Box::new(base_type))
5495+
} else {
5496+
base_type
5497+
})
54925498
} else {
54935499
None
54945500
};

tests/sqlparser_postgres.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4564,6 +4564,27 @@ fn parse_create_function_detailed() {
45644564
);
45654565
}
45664566

4567+
#[test]
4568+
fn parse_create_function_returns_setof() {
4569+
pg_and_generic().verified_stmt(
4570+
"CREATE FUNCTION get_users() RETURNS SETOF TEXT LANGUAGE sql AS 'SELECT name FROM users'",
4571+
);
4572+
pg_and_generic().verified_stmt(
4573+
r#"CREATE FUNCTION get_all() RETURNS SETOF my_schema."MyType" LANGUAGE sql AS 'SELECT * FROM t'"#,
4574+
);
4575+
4576+
let sql = "CREATE FUNCTION get_names() RETURNS SETOF TEXT LANGUAGE sql AS 'SELECT name FROM t'";
4577+
match pg_and_generic().verified_stmt(sql) {
4578+
Statement::CreateFunction(CreateFunction { return_type, .. }) => {
4579+
assert_eq!(
4580+
return_type,
4581+
Some(DataType::SetOf(Box::new(DataType::Text)))
4582+
);
4583+
}
4584+
_ => panic!("Expected CreateFunction"),
4585+
}
4586+
}
4587+
45674588
#[test]
45684589
fn parse_create_function_with_security() {
45694590
let sql =

0 commit comments

Comments
 (0)