diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-09-01 16:28:06 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-09-01 16:28:06 +0000 |
commit | 470a1048ec145fe16b5baea56b9aef93f9878747 (patch) | |
tree | b437c27ddac8636efbb746852ea72b3ed7f4970e /src | |
parent | 1903221517b7a5d8846d77160d9bad61721d48a1 (diff) | |
download | postgresql-470a1048ec145fe16b5baea56b9aef93f9878747.tar.gz postgresql-470a1048ec145fe16b5baea56b9aef93f9878747.zip |
plpgsql functions can return RECORD, per Neil Conway.
Diffstat (limited to 'src')
-rw-r--r-- | src/pl/plpgsql/src/gram.y | 3 | ||||
-rw-r--r-- | src/pl/plpgsql/src/pl_comp.c | 14 | ||||
-rw-r--r-- | src/pl/plpgsql/src/pl_exec.c | 8 | ||||
-rw-r--r-- | src/test/regress/expected/plpgsql.out | 53 | ||||
-rw-r--r-- | src/test/regress/sql/plpgsql.sql | 35 |
5 files changed, 100 insertions, 13 deletions
diff --git a/src/pl/plpgsql/src/gram.y b/src/pl/plpgsql/src/gram.y index 47c8a9c1919..7c62d66d243 100644 --- a/src/pl/plpgsql/src/gram.y +++ b/src/pl/plpgsql/src/gram.y @@ -4,7 +4,7 @@ * procedural language * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.36 2002/08/30 00:28:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.37 2002/09/01 16:28:06 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -1159,7 +1159,6 @@ stmt_return : K_RETURN lno } ; -/* FIXME: this syntax needs work, RETURN NEXT breaks stmt_return */ stmt_return_next: K_RETURN_NEXT lno { PLpgSQL_stmt_return_next *new; diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c index 1878c5e396e..2ee06acbe0b 100644 --- a/src/pl/plpgsql/src/pl_comp.c +++ b/src/pl/plpgsql/src/pl_comp.c @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.49 2002/08/30 00:28:41 tgl Exp $ + * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_comp.c,v 1.50 2002/09/01 16:28:06 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -211,11 +211,11 @@ plpgsql_compile(Oid fn_oid, int functype) procStruct->prorettype); typeStruct = (Form_pg_type) GETSTRUCT(typeTup); - /* Disallow pseudotype result, except VOID */ - /* XXX someday allow RECORD? */ + /* Disallow pseudotype result, except VOID or RECORD */ if (typeStruct->typtype == 'p') { - if (procStruct->prorettype == VOIDOID) + if (procStruct->prorettype == VOIDOID || + procStruct->prorettype == RECORDOID) /* okay */; else if (procStruct->prorettype == TRIGGEROID || procStruct->prorettype == OPAQUEOID) @@ -227,7 +227,8 @@ plpgsql_compile(Oid fn_oid, int functype) format_type_be(procStruct->prorettype)); } - if (typeStruct->typrelid != InvalidOid) + if (typeStruct->typrelid != InvalidOid || + procStruct->prorettype == RECORDOID) function->fn_retistuple = true; else { @@ -486,8 +487,7 @@ plpgsql_compile(Oid fn_oid, int functype) } /* - * Create the magic found variable indicating if the last FOR or - * SELECT statement returned data + * Create the magic FOUND variable. */ var = malloc(sizeof(PLpgSQL_var)); memset(var, 0, sizeof(PLpgSQL_var)); diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 6f52f2c0480..7b7b1c1555e 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -3,7 +3,7 @@ * procedural language * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.61 2002/08/30 23:59:46 tgl Exp $ + * $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.62 2002/09/01 16:28:06 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -1588,9 +1588,9 @@ static int exec_stmt_return_next(PLpgSQL_execstate *estate, PLpgSQL_stmt_return_next *stmt) { - TupleDesc tupdesc; - int natts; - HeapTuple tuple; + TupleDesc tupdesc; + int natts; + HeapTuple tuple; bool free_tuple = false; if (!estate->retisset) diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index 583543262ed..e18a1d556a6 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -1680,3 +1680,56 @@ select * from test_ret_set_scalar(1,10); 11 (10 rows) +create function test_ret_set_rec_dyn(int) returns setof record as ' +DECLARE + retval RECORD; +BEGIN + IF $1 > 10 THEN + SELECT INTO retval 5, 10, 15; + RETURN NEXT retval; + RETURN NEXT retval; + ELSE + SELECT INTO retval 50, 5::numeric, ''xxx''::text; + RETURN NEXT retval; + RETURN NEXT retval; + END IF; + RETURN; +END;' language 'plpgsql'; +SELECT * FROM test_ret_set_rec_dyn(1500) AS (a int, b int, c int); + a | b | c +---+----+---- + 5 | 10 | 15 + 5 | 10 | 15 +(2 rows) + +SELECT * FROM test_ret_set_rec_dyn(5) AS (a int, b numeric, c text); + a | b | c +----+---+----- + 50 | 5 | xxx + 50 | 5 | xxx +(2 rows) + +create function test_ret_rec_dyn(int) returns record as ' +DECLARE + retval RECORD; +BEGIN + IF $1 > 10 THEN + SELECT INTO retval 5, 10, 15; + RETURN retval; + ELSE + SELECT INTO retval 50, 5::numeric, ''xxx''::text; + RETURN retval; + END IF; +END;' language 'plpgsql'; +SELECT * FROM test_ret_rec_dyn(1500) AS (a int, b int, c int); + a | b | c +---+----+---- + 5 | 10 | 15 +(1 row) + +SELECT * FROM test_ret_rec_dyn(5) AS (a int, b numeric, c text); + a | b | c +----+---+----- + 50 | 5 | xxx +(1 row) + diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql index e6795ed10a6..b6607442d72 100644 --- a/src/test/regress/sql/plpgsql.sql +++ b/src/test/regress/sql/plpgsql.sql @@ -1524,3 +1524,38 @@ BEGIN END;' language 'plpgsql'; select * from test_ret_set_scalar(1,10); + +create function test_ret_set_rec_dyn(int) returns setof record as ' +DECLARE + retval RECORD; +BEGIN + IF $1 > 10 THEN + SELECT INTO retval 5, 10, 15; + RETURN NEXT retval; + RETURN NEXT retval; + ELSE + SELECT INTO retval 50, 5::numeric, ''xxx''::text; + RETURN NEXT retval; + RETURN NEXT retval; + END IF; + RETURN; +END;' language 'plpgsql'; + +SELECT * FROM test_ret_set_rec_dyn(1500) AS (a int, b int, c int); +SELECT * FROM test_ret_set_rec_dyn(5) AS (a int, b numeric, c text); + +create function test_ret_rec_dyn(int) returns record as ' +DECLARE + retval RECORD; +BEGIN + IF $1 > 10 THEN + SELECT INTO retval 5, 10, 15; + RETURN retval; + ELSE + SELECT INTO retval 50, 5::numeric, ''xxx''::text; + RETURN retval; + END IF; +END;' language 'plpgsql'; + +SELECT * FROM test_ret_rec_dyn(1500) AS (a int, b int, c int); +SELECT * FROM test_ret_rec_dyn(5) AS (a int, b numeric, c text); |