Postgres 在 Update 语句中将语法错误评估为布尔值

Bjo*_*que 2 postgresql update

最近我在代码中遇到了一个错误,相当于这个片段:

create table testing(num int, dt date, istrue boolean);

insert into testing values (1, '2018-01-01', True);

UPDATE testing SET num = 2, istrue = null AND dt = '2018-01-01';
Run Code Online (Sandbox Code Playgroud)

UPDATE 语句实际上应该是:

UPDATE testing SET num = 2, istrue = null WHERE dt = '2018-01-01';
Run Code Online (Sandbox Code Playgroud)

然而 postgresql 很高兴地接受了 UPDATE 为有效并评估了代码:

null AND dt = '2018-01-01'
Run Code Online (Sandbox Code Playgroud)

在第二个等号作为布尔值之后,因此基于错误的逻辑更新了数据。

我已经在其他 SQL 风格中尝试过这个,但这是不允许的,他们想要一个 WHERE。

我不是 postgres 的人,但它看起来确实是一个非常奇怪的语法怪癖,还是一个错误?

ype*_*eᵀᴹ 6

然而 postgresql 很高兴地接受了UPDATE它的有效性并评估了代码:

null AND dt = '2018-01-01'
Run Code Online (Sandbox Code Playgroud)

在第二个等号作为布尔值之后,因此基于错误的逻辑更新了数据。

糟糕的事情发生在有错误代码的地方。在这种情况下,代码并不等同于你想要的逻辑,并已取代了WHEREAND。这种 - 糟糕的替换 - 通常会导致错误。极少数情况下它不会导致错误,你会得到这个 - 糟糕 - 结果你从查询中得到不同/意外的结果,或者 - 甚至是灾难性的 - 你更新了你想要更新几行的整个表。

我已经在其他 SQL 风格中尝试过这个,但这是不允许的,他们想要一个WHERE.

我不知道WHEREUPDATE语句中需要任何 DBMS 。SQL Server、Oracle、DB2、SQLite、MySQL,它们都不需要它。这是数据库开发人员、代码审查人员和测试人员的工作——确保代码与业务逻辑和需求保持一致。

我不是 Postgres 人,但它看起来确实是一个非常奇怪的语法怪癖,还是一个错误?

这绝对不是bug。代码被解析和执行 - 正如你正确假设的 - 作为:

UPDATE 
    testing 
SET 
    num = 2, 
    istrue = ( null AND (dt = '2018-01-01') )
;
Run Code Online (Sandbox Code Playgroud)

导致更新整个表。istrue将的值更新NULL为其中的行dtNULL等于'2018-01-01'和具有值FALSE的行的其余部分。