SSCCE:以下脚本:
$ cat test.sql
CREATE TABLE public.foo (
loop INTEGER
);
CREATE OR REPLACE FUNCTION public.foo_fun(loop INTEGER) RETURNS BOOLEAN AS $$
SELECT TRUE;
$$ LANGUAGE SQL;
CREATE OR REPLACE FUNCTION public.foo_tr_fun() RETURNS TRIGGER AS $$
DECLARE
fRV BOOLEAN;
BEGIN
SELECT public.foo_fun(NEW.loop) INTO fRV;
IF fRV THEN
RETURN NEW;
ELSE
RAISE EXCEPTION 'bar';
END IF;
END
$$ LANGUAGE plpgsql;
CREATE TRIGGER foo_tr AFTER INSERT OR UPDATE ON public.foo
FOR EACH ROW
EXECUTE PROCEDURE public.foo_tr_fun();
...我运行的是:
psql -v ON_ERROR_STOP=1 --quiet -X -U some-user -d some-db -f test.sql
...当我尝试将一行插入foo
(from psql
) 时:
$ psql -U some-user some-db
psql (9.1.14)
Type "help" for help.
RegTAP=> SELECT * FROM public.foo;
loop
------
(0 rows)
RegTAP=> INSERT INTO public.foo(loop) VALUES(0);
ERROR: record "new" has no field "loop"
LINE 1: SELECT public.foo_fun(NEW.loop)
^
QUERY: SELECT public.foo_fun(NEW.loop)
CONTEXT: PL/pgSQL function "foo_tr_fun" line 5 at SQL statement
RegTAP=>
事实证明,关键字
loop
需要在 PL/pgSQL 中用双引号引起来,否则解析器会混淆:Postgres 9.3 中的情况没有改变:
SQL fiddle with quotes (works)。
不带引号的 SQL 小提琴(不起作用)。
避免使用像
loop
标识符这样的典型关键字通常是个好主意。除了SQL 关键字之外,还有一些 plpgsql 关键字(例如过程元素或异常处理),但我不知道其他 plpgsql 关键字的完整列表。源代码将是我最好的主意。我在2007年的pgsql-hackers上找到了一个相关的讨论。看来这件事还没有完全解决。
在这里也没有看到 Postgres 9.4 的任何变化......