原文链接: https://mydbanotebook.org/post/pedantry/
感谢 Vik Fearing 对 PostgreSQL 和标准 SQL 的讨论(迄今为止在 pgconf.de 和 pgconf.be 上发表的演讲,我发现我们在 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 标准更一致!
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




