暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【译】摒除Postgres中学究式想法

原创 王语嫣 2022-06-22
271

原文链接: 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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论