感谢Vik Fearing关于PostgreSQL和标准SQL的演讲(到目前为止在pgconf.de和pgconf上发表的演讲)。我发现在count(*)中使用 * 的原因是过时的思想。
让我时间回到过去一点,讲讲这个故事…
因此,我们大多数人都知道,没有正当理由使用count()而不是count(),“80年代的一些人认为使用count()很难看”。我们大多数人也知道,count()中的 * 与 select * 中的 * 含义不同,这对很多人来说都很困惑。
但是,Vik在演讲中指出,SQL标准中存在不一致性,因为您必须在select count(*)中使用 *,但不必在窗口函数 row_number() 中使用 * !
实际上,如果您尝试在psql下使用count(),下面是您的错误消息:
laetitia=# select count() from test;
2022-05-21 09:48:26.497 CEST [73961] ERROR: count(*) must be used to call a parameterless aggregate function at character 8
2022-05-21 09:48:26.497 CEST [73961] STATEMENT: select count() from test;
ERROR: count(*) must be used to call a parameterless aggregate function
LINE 1: select count() from test;
Vik 喜欢 * 并且想使用 row_number(*),您已经可以这样做了。但我想删除使用count()时的错误消息。毕竟,如果没有理由拥有一些代码,那么可以简单地删除这些代码!
让我们看看Postgres代码,找出这条消息的显示位置:
laetitia:~/tech/laetitia/postgresql|master ⇒ grep "must be used to call a parameterless aggregate function" -r . --exclude="*.po"
./src/test/regress/expected/window.out:ERROR: count(*) must be used to call a parameterless aggregate function
./src/backend/parser/parse_func.c: errmsg("%s(*) must be used to call a parameterless aggregate function",
./src/backend/parser/parse_func.c: errmsg("%s(*) must be used to call a parameterless aggregate function",
因此,测试是在正确命名为 :parse_func.c
/*
* Reject attempt to call a parameterless aggregate without (*)
* syntax. This is mere pedantry but some folks insisted ...
*/
if (fargs == NIL && !agg_star && !agg_within_group)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("%s(*) must be used to call a parameterless aggregate function",
NameListToString(funcname)),
parser_errposition(pstate, location)));
好吧,所以,关于评论,如果PGDG不相信这是一件好事。
这个代码写了两次,让我们简单地删除它,看看这个新版本是否仍然通过回归测试!
我们可以使用make check对临时安装的postgres进行回归测试。
一个测试失败:
========================
1 of 214 tests failed.
========================
让我们看看差异:
LINE 1: SELECT rank() OVER (PARTITION BY four, ORDER BY ten) FROM te...
^
SELECT count() OVER () FROM tenk1;
-ERROR: count(*) must be used to call a parameterless aggregate function
-LINE 1: SELECT count() OVER () FROM tenk1;
- ^
由于此测试的唯一目标是拒绝任何count(),因此让我们简单地将其删除。
哒哒哒哒!
=======================
All 214 tests passed.
=======================
让我们在我全新的实例上测试它:
laetitia=# select count()
laetitia-# from test;
count
-------
6
(1 row)
多么伟大的成就!现在,Postgres和SQL Standard一致了!
原文标题:Removing some pedantry off Postgres
原文作者:Hacking
原文地址:https://mydbanotebook.org/post/pedantry/




