Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
470a1048
G
Gpdb
项目概览
Greenplum
/
Gpdb
通知
7
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
Gpdb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
470a1048
编写于
9月 01, 2002
作者:
T
Tom Lane
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
plpgsql functions can return RECORD, per Neil Conway.
上级
19032215
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
123 addition
and
17 deletion
+123
-17
doc/src/sgml/plpgsql.sgml
doc/src/sgml/plpgsql.sgml
+1
-3
doc/src/sgml/xfunc.sgml
doc/src/sgml/xfunc.sgml
+22
-1
src/pl/plpgsql/src/gram.y
src/pl/plpgsql/src/gram.y
+1
-2
src/pl/plpgsql/src/pl_comp.c
src/pl/plpgsql/src/pl_comp.c
+7
-7
src/pl/plpgsql/src/pl_exec.c
src/pl/plpgsql/src/pl_exec.c
+4
-4
src/test/regress/expected/plpgsql.out
src/test/regress/expected/plpgsql.out
+53
-0
src/test/regress/sql/plpgsql.sql
src/test/regress/sql/plpgsql.sql
+35
-0
未找到文件。
doc/src/sgml/plpgsql.sgml
浏览文件 @
470a1048
<
!--
$
Header
:
/
cvsroot
/
pgsql
/
doc
/
src
/
sgml
/
plpgsql
.
sgml
,
v
1.
5
2002
/
08
/
30
00
:
28
:
40
tgl
Exp
$
$
Header
:
/
cvsroot
/
pgsql
/
doc
/
src
/
sgml
/
plpgsql
.
sgml
,
v
1.
6
2002
/
09
/
01
16
:
28
:
05
tgl
Exp
$
-->
<
chapter
id
=
"plpgsql"
>
...
...
@@ -538,8 +538,6 @@ END;
<
para
>
Note
that
<
literal
>
RECORD
</>
is
not
a
true
data
type
,
only
a
placeholder
.
Thus
,
for
example
,
one
cannot
declare
a
function
returning
<
literal
>
RECORD
</>.
</
para
>
</
sect2
>
...
...
doc/src/sgml/xfunc.sgml
浏览文件 @
470a1048
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.
59 2002/08/30 00:28:40
tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/xfunc.sgml,v 1.
60 2002/09/01 16:28:05
tgl Exp $
-->
<chapter id="xfunc">
...
...
@@ -2119,6 +2119,27 @@ SELECT * FROM vw_getfoo;
</programlisting>
are all valid statements.
</para>
<para>
In some cases it is useful to define table functions that can return
different column sets depending on how they are invoked. To support this,
the table function can be declared as returning the pseudo-type
<type>record</>. When such a function is used in a query, the expected
row structure must be specified in the query itself, so that the system
can know how to parse and plan the query. Consider this example:
<programlisting>
SELECT *
FROM dblink('dbname=template1', 'select proname, prosrc from pg_proc')
AS t1(proname name, prosrc text)
WHERE proname LIKE 'bytea%';
</programlisting>
The <literal>dblink</> function executes a remote query (see
<literal>contrib/dblink</>). It is declared to return <type>record</>
since it might be used for any kind of query. The actual column set
must be specified in the calling query so that the parser knows, for
example, what <literal>*</> should expand to.
</para>
</sect1>
<sect1 id="xfunc-plhandler">
...
...
src/pl/plpgsql/src/gram.y
浏览文件 @
470a1048
...
...
@@ -4,7 +4,7 @@
* procedural language
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.3
6 2002/08/30 00:28:41
tgl Exp $
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/gram.y,v 1.3
7 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;
...
...
src/pl/plpgsql/src/pl_comp.c
浏览文件 @
470a1048
...
...
@@ -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
));
...
...
src/pl/plpgsql/src/pl_exec.c
浏览文件 @
470a1048
...
...
@@ -3,7 +3,7 @@
* procedural language
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.6
1 2002/08/30 23:59:4
6 tgl Exp $
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.6
2 2002/09/01 16:28:0
6 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
)
...
...
src/test/regress/expected/plpgsql.out
浏览文件 @
470a1048
...
...
@@ -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)
src/test/regress/sql/plpgsql.sql
浏览文件 @
470a1048
...
...
@@ -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
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录