Greenplum plpgsql函数中exit存在无法跳出循环的BUG

Greenplum中如果使用循环,并且内部嵌套了子块,在子块中的exit只能跳出子块,不能跳出子块外面的循环。

CREATE OR REPLACE FUNCTION test1(i integer) RETURNS
integer AS
$$
DECLARE count int;
BEGIN
    count := 1;
    LOOP
        count := count + 1;

        begin
            raise notice 'sub xact: %', count;
            EXECUTE 'select 1';
            IF count > 10 THEN
                EXIT;  -- BUG在这里, 只跳出了begin, 没有跳出LOOP
                raise notice 'sub xact if: %', count;
            END IF;
            raise notice 'sub xact end if: %', count;
        exception when others then
        end;

        raise notice 'parent xact: %', count;
    END LOOP;
    return 1;
END
$$ LANGUAGE plpgsql;

postgres=# select test1(1);
NOTICE:  sub xact: 2
NOTICE:  sub xact end if: 2
NOTICE:  parent xact: 2
NOTICE:  sub xact: 3
NOTICE:  sub xact end if: 3
NOTICE:  parent xact: 3
NOTICE:  sub xact: 4
NOTICE:  sub xact end if: 4
NOTICE:  parent xact: 4
NOTICE:  sub xact: 5
NOTICE:  sub xact end if: 5
NOTICE:  parent xact: 5
NOTICE:  sub xact: 6
NOTICE:  sub xact end if: 6
NOTICE:  parent xact: 6
NOTICE:  sub xact: 7
NOTICE:  sub xact end if: 7
NOTICE:  parent xact: 7
NOTICE:  sub xact: 8
NOTICE:  sub xact end if: 8
NOTICE:  parent xact: 8
NOTICE:  sub xact: 9
NOTICE:  sub xact end if: 9
NOTICE:  parent xact: 9
NOTICE:  sub xact: 10
NOTICE:  sub xact end if: 10
NOTICE:  parent xact: 10
NOTICE:  sub xact: 11
NOTICE:  parent xact: 11
NOTICE:  sub xact: 12
NOTICE:  parent xact: 12
NOTICE:  sub xact: 13
NOTICE:  parent xact: 13
NOTICE:  sub xact: 14
NOTICE:  parent xact: 14

CREATE OR REPLACE FUNCTION test1(i integer) RETURNS
integer AS
$$
DECLARE count int;
BEGIN
    count := 1;
    LOOP
        count := count + 1;

        begin
            raise notice 'sub xact: %', count;
            EXECUTE 'select 1';
            IF count > 10 THEN
                return 0;  -- 改成return, 退出整个函数, 如果要跳出loop, 应该在loop内控制。不能放在LOOP内的sub block执行。
            END IF;
        exception when others then
        end;

        raise notice 'parent xact: %', count;
    END LOOP;
    return 1;
END
$$ LANGUAGE plpgsql;

postgres=# select test1(1);
NOTICE:  sub xact: 2
NOTICE:  parent xact: 2
NOTICE:  sub xact: 3
NOTICE:  parent xact: 3
NOTICE:  sub xact: 4
NOTICE:  parent xact: 4
NOTICE:  sub xact: 5
NOTICE:  parent xact: 5
NOTICE:  sub xact: 6
NOTICE:  parent xact: 6
NOTICE:  sub xact: 7
NOTICE:  parent xact: 7
NOTICE:  sub xact: 8
NOTICE:  parent xact: 8
NOTICE:  sub xact: 9
NOTICE:  parent xact: 9
NOTICE:  sub xact: 10
NOTICE:  parent xact: 10
NOTICE:  sub xact: 11
 test1
-------
     0
(1 row)

在PostgreSQL中不存在这个问题。 使用GP时需要注意一下。

时间: 2024-10-29 20:02:55

Greenplum plpgsql函数中exit存在无法跳出循环的BUG的相关文章

linux中exit()和_exit()函数的作用

exit和_exit函数都是用来终止进程的.当程序执行到exit或_exit时,系统无条件的停止剩下所有操作, 清除包括PCB在内的各种数据结构,并终止本进程的运行.但是,这两个函数是有区别的. exit()函数的作用是:直接使用进程停止运行,清除其使用的内存空间,并清除其在内核中的各种数据 结构:_exit()函数则在这一基础上做了一些包装.在执行退出之前加了若干道工序.exit()函数与_exit()函 数最大区别就在于exit()函数在调用exit系统之前要检查文件的打开情况,把文件缓冲区

PHP中exit()与die()的区别

本篇文章简要分析一下在php中经常用到的exit和die的区别,有需要的朋友可以看一下. 首先思考一个问题: 如下代码会向页面显示什么? <?php die(123); ?> 曾经有段时间我一直认为 页面会显示 123,但实践结果告诉我,答案错了,页面一片空白! 一直不知道为什么,死活不输出123,为了让页面输出123,我把它修改为如下代码: <?php echo '123'; die(); ?> 网上的一段资料: PHP中exit()与die()的区别 PHP手册:die()Eq

_exit()函数与exit()函数的区别

exit()在结束调用它的进程之前,要进行如下步骤: 1.cleanup(): 2.在atexit()注册的函数: 'exit()'与'_exit()'有不少区别在使用'fork()',特别是'vfork()'时变得很 突出. 'exit()'与'_exit()'的基本区别在于前一个调用实施与调用库里用户状态结构 (user-mode constructs)有关的清除工作(clean-up),而且调用用户自定义的清除程序 (译者注:自定义清除程序由atexit函数定义,可定义多次,并以倒序执行)

Python中exit、return、sys.exit()等使用实例和区别

  这篇文章主要介绍了Python中exit.return.sys.exit()等使用实例和区别,本文是一个实际项目中的总结,需要的朋友可以参考下 有这样一道题目: 字符串标识符.修改例 6-1 的 idcheck.py 脚本,使之可以检测长度为一的标识符,并且可以识别 Python 关键字,对后一个要求,你可以使用 keyword 模块(特别是 keyword.kelist)来帮你. 我最初的代码是: 代码如下: #!/usr/bin/env python import string impo

linux中exit()和

  /***** exit1.c ******/#include<stdio.h>#include<stdlib.h>main(){ printf("output begin/n"); printf("content in buffer"); exit(0);} 使用了exit()函数,结束进程前,把文件缓冲区内容写回文件.这是比较安全的退出方式. 而下面的_exit()函数,结束进程前,不处理缓冲区,直接清空,这样风险比较大.   /***

c-将主函数分到子函数中

问题描述 将主函数分到子函数中 #include typedef struct student { char name[10]; char id[10]; int scord1; int scord2; double scord3; }student; int main() { FILE *fp=NULL, *ftp=NULL; int i = 0, a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0; double average = 0; stud

链表的插入 插入函数写好了 在main函数中调用 然而最后的结果并没有实现插入的功能

问题描述 链表的插入 插入函数写好了 在main函数中调用 然而最后的结果并没有实现插入的功能 struct Link *InsertNode01(struct Link *head,int nodeData,int i) { int j=1; struct Link *pr = head, *p, *temp = NULL; p = (struct Link *)malloc(sizeof(struct Link)); if(p == NULL) { printf("NO enough mem

循环问题-C语言中if函数中的问题

问题描述 C语言中if函数中的问题 #includeint main(){ int num[2][6]={{000000}{000000}}; int i=0j=0mnpz; printf(""Please type 1 for first classPlease type 2 for economy ""); { for(p=1;p<=10;p++) { scanf(""%d""&z); if(z==1&

for-关于 += 在被调用函数中时的问题。

问题描述 关于 += 在被调用函数中时的问题. int add(int a){int b = 0: b += 1;}int main (void){int a =0;int i = 0;for(i = 0;i<= 5;i++){printf(""%dn""add(a));}return 0;}如果通过循环调用函数的话, b += 1;怎么进行赋值? 解决方案 使用指针或引用都可以达到要求,一般教科书上会使用指针. void add(int *a){ *a =