难道HAWQ不支持SQL in the cycle(while or for,use plpgsql)?

Is HAWQ not support SQL in the cycle(while or for,use plpgsql)?

今天,我定义了一个函数,在循环中使用插入语句。但是 HAWQ 返回了一个错误:

ERROR:  could not serialize unrecognized node type: 43983632 (outfast.c:4742)
CONTEXT:  SQL statement "insert into t(id,value) values(1,0.1)"
PL/pgSQL function "test_function" line 6 at SQL statement

我做了一些测试,发现当我在循环中使用'insert statements'时,会报错。 如果我把相关的'insert statements'删掉,就可以正常运行了。

这是一个测试示例:

 CREATE OR REPLACE FUNCTION test_function()
  RETURNS int AS
$BODY$
declare 
 number int;
begin  
 number := 1;
 while number <= 10 loop
  insert into t(id,value) values(1,0.1);
  number := number+1;
 end loop;
 return number;
end
$BODY$
  LANGUAGE plpgsql ;

然后我用'select test_function();'调用function.It会返回上面提到的错误。

这是否意味着我不能在 plpgsql 循环中使用 SQL 语句?

谢谢。 最好的问候。

你会想避免使用 HAWQ 的单例语句,但我有点惊讶它不起作用。您需要改用基于集合的操作。

    CREATE TABLE t (id int, value numeric);

    CREATE OR REPLACE FUNCTION test_function() RETURNS int AS
    $BODY$
    declare 
            number int;
    begin       
            insert into t (id, value) select 1, 0.1 from generate_series(1, 10);
            return 10;
    end
    $BODY$
    LANGUAGE plpgsql;

对于这样一个简单的示例,您可以使用 sql 函数来代替,它的开销比 plpgsql 少。

    DROP FUNCTION test_function();

    CREATE OR REPLACE FUNCTION test_function() RETURNS void AS
    $BODY$
            insert into t (id, value) select 1, 0.1 from generate_series(1, 10);
    $BODY$
    LANGUAGE sql;

这两个函数都在一个语句中完成所有工作,而不是执行 10 个单独的语句。我在 HAWQ 中都进行了测试并且都有效。

如果您必须使用 HAWQ 在循环中执行单例插入语句,这里有一个解决方法。

    CREATE OR REPLACE FUNCTION test_function()
      RETURNS int AS
    $BODY$
    declare 
            number int;
            v_sql text;
    begin       
            number := 1;
            while number <= 10 loop
                    v_sql := 'insert into t(id,value) values(1,0.1)';
                    execute v_sql;
                    number := number+1;
            end loop;
            return number;
    end
    $BODY$
      LANGUAGE plpgsql ;

这其实是hawq 2.0中已经解决的问题。可参考最新https://github.com/apache/incubator-hawq参考

结果如下:

CREATE TABLE t (id INT, value DOUBLE PRECISION);
CREATE TABLE

CREATE OR REPLACE FUNCTION test_function()
RETURNS int AS
$BODY$
declare
    number int;
begin
    number := 1;
    while number <= 10 loop
        insert into t(id, value) values(1, 0.1);
        number := number+1;
    end loop;

    return number;
end
$BODY$
LANGUAGE plpgsql;
CREATE FUNCTION



SELECT test_function();
 test_function
---------------
            11
(1 row)

SELECT * FROM t;
 id | value
----+-------
  1 |   0.1
  1 |   0.1
  1 |   0.1
  1 |   0.1
  1 |   0.1
  1 |   0.1
  1 |   0.1
  1 |   0.1
  1 |   0.1
  1 |   0.1
(10 rows)



SELECT * FROM test_function();
 test_function
---------------
            11
(1 row)

SELECT * FROM t;
 id | value
----+-------
  1 |   0.1
  1 |   0.1
  1 |   0.1
  1 |   0.1
  1 |   0.1
  1 |   0.1
  1 |   0.1
  1 |   0.1
  1 |   0.1
  1 |   0.1
(10 rows)