Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
8690ebc2
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,发现更多精彩内容 >>
提交
8690ebc2
编写于
4月 29, 2007
作者:
N
Neil Conway
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Support for MOVE in PL/PgSQL. Initial patch from Magnus, some improvements
by Pavel Stehule, and reviewed by Neil Conway.
上级
f2321a3f
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
226 addition
and
47 deletion
+226
-47
doc/src/sgml/plpgsql.sgml
doc/src/sgml/plpgsql.sgml
+55
-1
src/pl/plpgsql/src/gram.y
src/pl/plpgsql/src/gram.y
+18
-2
src/pl/plpgsql/src/pl_exec.c
src/pl/plpgsql/src/pl_exec.c
+44
-32
src/pl/plpgsql/src/pl_funcs.c
src/pl/plpgsql/src/pl_funcs.c
+54
-9
src/pl/plpgsql/src/plpgsql.h
src/pl/plpgsql/src/plpgsql.h
+3
-2
src/pl/plpgsql/src/scan.l
src/pl/plpgsql/src/scan.l
+2
-1
src/test/regress/expected/plpgsql.out
src/test/regress/expected/plpgsql.out
+27
-0
src/test/regress/sql/plpgsql.sql
src/test/regress/sql/plpgsql.sql
+23
-0
未找到文件。
doc/src/sgml/plpgsql.sgml
浏览文件 @
8690ebc2
<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.10
8 2007/04/28 23:54:5
8 neilc Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.10
9 2007/04/29 01:21:0
8 neilc Exp $ -->
<chapter id="plpgsql">
<title><application>PL/pgSQL</application> - <acronym>SQL</acronym> Procedural Language</title>
...
...
@@ -1522,6 +1522,13 @@ GET DIAGNOSTICS integer_var = ROW_COUNT;
true if it returns a row, false if no row is returned.
</para>
</listitem>
<listitem>
<para>
A <command>MOVE</> statement sets <literal>FOUND</literal>
true if it successfully repositions the cursor, false otherwise.
</para>
</listitem>
<listitem>
<para>
A <command>FOR</> statement sets <literal>FOUND</literal> true
...
...
@@ -2562,6 +2569,53 @@ FETCH curs1 INTO rowvar;
FETCH curs2 INTO foo, bar, baz;
FETCH LAST FROM curs3 INTO x, y;
FETCH RELATIVE -2 FROM curs4 INTO x;
</programlisting>
</para>
</sect3>
<sect3>
<title><literal>MOVE</></title>
<synopsis>
MOVE <optional> <replaceable>direction</replaceable> { FROM | IN } </optional> <replaceable>cursor</replaceable>;
</synopsis>
<para>
<command>MOVE</command> repositions a cursor without retrieving
any data. <command>MOVE</command> works exactly like the
<command>FETCH</command> command, except it only positions the
cursor and does not return rows. As with <command>SELECT
INTO</command>, the special variable <literal>FOUND</literal> can
be checked to see whether the cursor was successfully
repositioned or not.
</para>
<para>
The <replaceable>direction</replaceable> clause can be any of the
variants allowed in the SQL <xref linkend="sql-move"
endterm="sql-move-title"> command except the ones that can move by
more than one row; namely, it can be
<literal>NEXT</>,
<literal>PRIOR</>,
<literal>FIRST</>,
<literal>LAST</>,
<literal>ABSOLUTE</> <replaceable>count</replaceable>,
<literal>RELATIVE</> <replaceable>count</replaceable>,
<literal>FORWARD</>, or
<literal>BACKWARD</>.
Omitting <replaceable>direction</replaceable> is the same
as specifying <literal>NEXT</>.
<replaceable>direction</replaceable> values that require moving
backward are likely to fail unless the cursor was declared or opened
with the <literal>SCROLL</> option.
</para>
<para>
Examples:
<programlisting>
MOVE curs1;
MOVE LAST FROM curs3;
MOVE RELATIVE -2 FROM curs4;
</programlisting>
</para>
</sect3>
...
...
src/pl/plpgsql/src/gram.y
浏览文件 @
8690ebc2
...
...
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.10
1 2007/04/28 23:54:5
9 neilc Exp $
* $PostgreSQL: pgsql/src/pl/plpgsql/src/gram.y,v 1.10
2 2007/04/29 01:21:0
9 neilc Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -125,7 +125,7 @@ static void check_labels(const char *start_label,
%type <stmt> stmt_assign stmt_if stmt_loop stmt_while stmt_exit
%type <stmt> stmt_return stmt_raise stmt_execsql stmt_execsql_insert
%type <stmt> stmt_dynexecute stmt_for stmt_perform stmt_getdiag
%type <stmt> stmt_open stmt_fetch stmt_close stmt_null
%type <stmt> stmt_open stmt_fetch stmt_
move stmt_
close stmt_null
%type <list> proc_exceptions
%type <exception_block> exception_sect
...
...
@@ -179,6 +179,7 @@ static void check_labels(const char *start_label,
%token K_IS
%token K_LOG
%token K_LOOP
%token K_MOVE
%token K_NEXT
%token K_NOSCROLL
%token K_NOT
...
...
@@ -635,6 +636,8 @@ proc_stmt : pl_block ';'
{ $$ = $1; }
| stmt_fetch
{ $$ = $1; }
| stmt_move
{ $$ = $1; }
| stmt_close
{ $$ = $1; }
| stmt_null
...
...
@@ -1478,6 +1481,19 @@ stmt_fetch : K_FETCH lno opt_fetch_direction cursor_variable K_INTO
fetch->rec = rec;
fetch->row = row;
fetch->curvar = $4->varno;
fetch->is_move = false;
$$ = (PLpgSQL_stmt *)fetch;
}
;
stmt_move : K_MOVE lno opt_fetch_direction cursor_variable ';'
{
PLpgSQL_stmt_fetch *fetch = $3;
fetch->lineno = $2;
fetch->curvar = $4->varno;
fetch->is_move = true;
$$ = (PLpgSQL_stmt *)fetch;
}
...
...
src/pl/plpgsql/src/pl_exec.c
浏览文件 @
8690ebc2
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.19
5 2007/04/19 16:33:24 tgl
Exp $
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.19
6 2007/04/29 01:21:09 neilc
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -3114,7 +3114,8 @@ exec_stmt_open(PLpgSQL_execstate *estate, PLpgSQL_stmt_open *stmt)
/* ----------
* exec_stmt_fetch Fetch from a cursor into a target
* exec_stmt_fetch Fetch from a cursor into a target, or just
* move the current position of the cursor
* ----------
*/
static
int
...
...
@@ -3163,46 +3164,57 @@ exec_stmt_fetch(PLpgSQL_execstate *estate, PLpgSQL_stmt_fetch *stmt)
exec_eval_cleanup
(
estate
);
}
/* ----------
* Determine if we fetch into a record or a row
* ----------
*/
if
(
stmt
->
rec
!=
NULL
)
rec
=
(
PLpgSQL_rec
*
)
(
estate
->
datums
[
stmt
->
rec
->
recno
]);
else
if
(
stmt
->
row
!=
NULL
)
row
=
(
PLpgSQL_row
*
)
(
estate
->
datums
[
stmt
->
row
->
rowno
]);
else
elog
(
ERROR
,
"unsupported target"
);
if
(
!
stmt
->
is_move
)
{
/* ----------
* Determine if we fetch into a record or a row
* ----------
*/
if
(
stmt
->
rec
!=
NULL
)
rec
=
(
PLpgSQL_rec
*
)
(
estate
->
datums
[
stmt
->
rec
->
recno
]);
else
if
(
stmt
->
row
!=
NULL
)
row
=
(
PLpgSQL_row
*
)
(
estate
->
datums
[
stmt
->
row
->
rowno
]);
else
elog
(
ERROR
,
"unsupported target"
);
/* ----------
* Fetch 1 tuple from the cursor
* ----------
*/
SPI_scroll_cursor_fetch
(
portal
,
stmt
->
direction
,
how_many
);
tuptab
=
SPI_tuptable
;
n
=
SPI_processed
;
/* ----------
* Fetch 1 tuple from the cursor
* ----------
*/
SPI_scroll_cursor_fetch
(
portal
,
stmt
->
direction
,
how_many
);
tuptab
=
SPI_tuptable
;
n
=
SPI_processed
;
/* ----------
* Set the target and the global FOUND variable appropriately.
* ----------
*/
if
(
n
==
0
)
{
exec_move_row
(
estate
,
rec
,
row
,
NULL
,
tuptab
->
tupdesc
);
exec_set_found
(
estate
,
false
);
/* ----------
* Set the target and the global FOUND variable appropriately.
* ----------
*/
if
(
n
==
0
)
{
exec_move_row
(
estate
,
rec
,
row
,
NULL
,
tuptab
->
tupdesc
);
exec_set_found
(
estate
,
false
);
}
else
{
exec_move_row
(
estate
,
rec
,
row
,
tuptab
->
vals
[
0
],
tuptab
->
tupdesc
);
exec_set_found
(
estate
,
true
);
}
SPI_freetuptable
(
tuptab
);
}
else
{
exec_move_row
(
estate
,
rec
,
row
,
tuptab
->
vals
[
0
],
tuptab
->
tupdesc
);
exec_set_found
(
estate
,
true
);
}
/* Move the cursor */
SPI_scroll_cursor_move
(
portal
,
stmt
->
direction
,
how_many
);
n
=
SPI_processed
;
SPI_freetuptable
(
tuptab
);
/* Set the global FOUND variable appropriately. */
exec_set_found
(
estate
,
n
!=
0
);
}
return
PLPGSQL_RC_OK
;
}
/* ----------
* exec_stmt_close Close a cursor
* ----------
...
...
src/pl/plpgsql/src/pl_funcs.c
浏览文件 @
8690ebc2
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.5
8 2007/03/18 05:36:4
9 neilc Exp $
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_funcs.c,v 1.5
9 2007/04/29 01:21:0
9 neilc Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -493,6 +493,7 @@ static void dump_dynfors(PLpgSQL_stmt_dynfors *stmt);
static
void
dump_getdiag
(
PLpgSQL_stmt_getdiag
*
stmt
);
static
void
dump_open
(
PLpgSQL_stmt_open
*
stmt
);
static
void
dump_fetch
(
PLpgSQL_stmt_fetch
*
stmt
);
static
void
dump_cursor_direction
(
PLpgSQL_stmt_fetch
*
stmt
);
static
void
dump_close
(
PLpgSQL_stmt_close
*
stmt
);
static
void
dump_perform
(
PLpgSQL_stmt_perform
*
stmt
);
static
void
dump_expr
(
PLpgSQL_expr
*
expr
);
...
...
@@ -761,21 +762,64 @@ static void
dump_fetch
(
PLpgSQL_stmt_fetch
*
stmt
)
{
dump_ind
();
printf
(
"FETCH curvar=%d
\n
"
,
stmt
->
curvar
);
if
(
!
stmt
->
is_move
)
{
printf
(
"FETCH curvar=%d
\n
"
,
stmt
->
curvar
);
dump_cursor_direction
(
stmt
);
dump_indent
+=
2
;
if
(
stmt
->
rec
!=
NULL
)
{
dump_ind
();
printf
(
" target = %d %s
\n
"
,
stmt
->
rec
->
recno
,
stmt
->
rec
->
refname
);
}
if
(
stmt
->
row
!=
NULL
)
{
dump_ind
();
printf
(
" target = %d %s
\n
"
,
stmt
->
row
->
rowno
,
stmt
->
row
->
refname
);
}
dump_indent
-=
2
;
}
else
{
printf
(
"MOVE curvar=%d
\n
"
,
stmt
->
curvar
);
dump_cursor_direction
(
stmt
);
}
}
static
void
dump_cursor_direction
(
PLpgSQL_stmt_fetch
*
stmt
)
{
dump_indent
+=
2
;
if
(
stmt
->
rec
!=
NULL
)
dump_ind
();
switch
(
stmt
->
direction
)
{
dump_ind
();
printf
(
" target = %d %s
\n
"
,
stmt
->
rec
->
recno
,
stmt
->
rec
->
refname
);
case
FETCH_FORWARD
:
printf
(
" FORWARD "
);
break
;
case
FETCH_BACKWARD
:
printf
(
" BACKWARD "
);
break
;
case
FETCH_ABSOLUTE
:
printf
(
" ABSOLUTE "
);
break
;
case
FETCH_RELATIVE
:
printf
(
" RELATIVE "
);
break
;
default:
printf
(
"??? unknown cursor direction %d"
,
stmt
->
direction
);
}
if
(
stmt
->
row
!=
NULL
)
if
(
stmt
->
expr
)
{
dump_
ind
(
);
printf
(
"
target = %d %s
\n
"
,
stmt
->
row
->
rowno
,
stmt
->
row
->
refname
);
dump_
expr
(
stmt
->
expr
);
printf
(
"
\n
"
);
}
else
printf
(
"%d
\n
"
,
stmt
->
how_many
);
dump_indent
-=
2
;
}
static
void
...
...
@@ -1067,3 +1111,4 @@ plpgsql_dumptree(PLpgSQL_function *func)
printf
(
"
\n
End of execution tree of function %s
\n\n
"
,
func
->
fn_name
);
fflush
(
stdout
);
}
src/pl/plpgsql/src/plpgsql.h
浏览文件 @
8690ebc2
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.8
7 2007/04/16 17:21:23 tgl
Exp $
* $PostgreSQL: pgsql/src/pl/plpgsql/src/plpgsql.h,v 1.8
8 2007/04/29 01:21:09 neilc
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -446,7 +446,7 @@ typedef struct
typedef
struct
{
/* FETCH statement */
{
/* FETCH
or MOVE
statement */
int
cmd_type
;
int
lineno
;
PLpgSQL_rec
*
rec
;
/* target, as record or row */
...
...
@@ -455,6 +455,7 @@ typedef struct
FetchDirection
direction
;
/* fetch direction */
int
how_many
;
/* count, if constant (expr is NULL) */
PLpgSQL_expr
*
expr
;
/* count, if expression */
bool
is_move
;
/* is this a fetch or move? */
}
PLpgSQL_stmt_fetch
;
...
...
src/pl/plpgsql/src/scan.l
浏览文件 @
8690ebc2
...
...
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/pl/plpgsql/src/scan.l,v 1.5
6 2007/04/16 17:21:23 tgl
Exp $
* $PostgreSQL: pgsql/src/pl/plpgsql/src/scan.l,v 1.5
7 2007/04/29 01:21:09 neilc
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -142,6 +142,7 @@ into { return K_INTO; }
is { return K_IS; }
log { return K_LOG; }
loop { return K_LOOP; }
move { return K_MOVE; }
next { return K_NEXT; }
no{space}+scroll { return K_NOSCROLL; }
not { return K_NOT; }
...
...
src/test/regress/expected/plpgsql.out
浏览文件 @
8690ebc2
...
...
@@ -3023,4 +3023,31 @@ select * from sc_test();
0
(3 rows)
create or replace function sc_test() returns setof integer as $$
declare
c cursor for select * from generate_series(1, 10);
x integer;
begin
open c;
loop
move relative 2 in c;
if not found then
exit;
end if;
fetch next from c into x;
if found then
return next x;
end if;
end loop;
close c;
end;
$$ language plpgsql;
select * from sc_test();
sc_test
---------
3
6
9
(3 rows)
drop function sc_test();
src/test/regress/sql/plpgsql.sql
浏览文件 @
8690ebc2
...
...
@@ -2511,4 +2511,27 @@ $$ language plpgsql;
select
*
from
sc_test
();
create
or
replace
function
sc_test
()
returns
setof
integer
as
$$
declare
c
cursor
for
select
*
from
generate_series
(
1
,
10
);
x
integer
;
begin
open
c
;
loop
move
relative
2
in
c
;
if
not
found
then
exit
;
end
if
;
fetch
next
from
c
into
x
;
if
found
then
return
next
x
;
end
if
;
end
loop
;
close
c
;
end
;
$$
language
plpgsql
;
select
*
from
sc_test
();
drop
function
sc_test
();
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录