user是一个伪函数关键字
user是current_user的别名,是一个内置的伪函数。它没有大多数零参数函数的(),因为SQL标准委员会规定current_user应该这样。我不知道为什么user也遵循这个规定,因为我认为规范并没有要求。
函数可以在FROM子句中使用
无论如何,在PostgreSQL中指定一个函数在from子句中是合法的,例如:
regress=> SELECT * from clock_timestamp();
clock_timestamp
-------------------------------
2014-09-03 17:00:59.191019+08
(1 row)
因为一个返回单个值的函数也可以在返回集合的上下文中使用。
所以当你运行:
select * from user;
你真的做得很好:
select current_user;
"引用"转义关键字
如果你写"user"而不是"用户",它之所以“有效”,是因为带引号的标识符始终是用户标识符,而不是关键字。 user是一个关键字;"user"是一个合法的表名的用户定义标识符。
有点混乱,对吧?
通常情况下,"tablename"和tablename是相同的(带引号的小写和无引号的小写),除非tablename是一个关键字。
如果我们选择一个不是伪函数的关键字,这可能会更有意义,因此它不是合法的语法。比如:
regress=> CREATE TABLE "where" (id integer);
CREATE TABLE
regress=> CREATE TABLE where (id integer);
ERROR: syntax error at or near "where"
LINE 1: CREATE TABLE where (id integer);
^
引用使标识符区分大小写
通常情况下,PostgreSQL将所有标识符转换为小写。这是SQL规范所要求的,尽管实际上它要求使用大写。因此,当您:
CREATE TABLE MyTable (id integer);
PostgreSQL实际上创建了一个名为mytable的表。然而,如果您使用"双引号"标识符,这种大小写折叠将被禁用 - 同样是根据SQL标准。
所以原因是:
select * from "User";
失败的原因是,根据SQL标准,PostgreSQL将带引号的标识符视为区分大小写。因此,"User"、"USER"和"user"都是不同的东西。
如何避免这些问题?
不要将表命名为关键字,例如类型名称、函数名称等。虽然这通常是合法的,但很少是一个好主意。
如果您打算使用关键字作为名称,在出现的地方始终"双引号"括起来,并且实际上应该养成这样的习惯,即始终以一致的大小写使用所有标识符。
这里有一个关键字列表。