Postgresql

為什麼在更新點欄位並且該欄位為 NULL 時,數組語法的行為與 ‘(?,?)’ 語法不同?

  • August 11, 2014

我正在使用 PostgreSQL 9.3.5。

假設我有下表:

CREATE TEMPORARY TABLE point_test ("name" varchar(255), "pt" point);

然後我插入一行,留下pt NULL

INSERT INTO point_test (name) VALUES ('me');

然後,我想pt使用類似數組的語法進行更新:

UPDATE point_test SET pt[0] = 42, pt[1] = -42 WHERE name = 'me';

這似乎成功(UPDATE 1) -EXPLAIN VERBOSE顯示以下內容:

Update on pg_temp_65.point_test  (cost=0.00..11.75 rows=1 width=538)
 ->  Seq Scan on pg_temp_65.point_test  (cost=0.00..11.75 rows=1 width=538)
       Output: name, (pt[0] := 42::double precision)[1] := (-42)::double precision, ctid
       Filter: ((point_test.name)::text = 'me'::text)

不過,pt依舊NULL。如果我使用稍微不同的語法,它適用於這種情況:

UPDATE point_test SET pt = '(42,-42)' WHERE name = 'me';

結果(42,-42)如預期的那樣。

此外,既然該領域有一些東西,我可以使用第一種語法更新這一點:

UPDATE point_test SET pt[0] = 84, pt[1] = -84 WHERE name = 'me';

結果(84,-84)如預期的那樣。

為什麼這兩種語法的行為僅在pt列是時才有所不同NULL

根據文件:

可以訪問一個點的兩個分量編號,就好像該點是一個索引為 0 和 1 的數組一樣。

但是幾何類型不是數組。

雖然值作為一個整體可以是NULL,但點的一部分(或任何幾何類型不能

所有幾何類型都可以作為字元串文字輸入並轉換為相應的類型。他們都不接受NULL作為輸入的一部分。這會導致錯誤消息

SELECT '(NULL,1)'::point;

錯誤:類型點的無效輸入語法:“(NULL,1)”

第 1 行:SELECT ‘(NULL,1)’::point

另一方面,如果您嘗試將一個或多個 NULL 值傳遞給建構子,您會得到**NULL整個值**- 這有點不一致,但仍然有意義:如果一個組件未知,則整個值都是未知的。所有這些測試都返回TRUE

SELECT point(NULL, NULL) IS NULL
     ,point(1, NULL) IS NULL
     ,point(NULL, 1) IS NULL
     ,point(NULL, 1) IS NULL
     ,circle(point(1, 1), NULL) IS NULL;

這留下了一個**UPDATE**靜默忽略 NULL 到pt[0]or的分配的情況pt[1]。這真的應該做兩件事之一:

  • 設置pointNULL- 喜歡SELECT point(NULL,1)
  • 引發異常 - 就像這樣SELECT '(NULL,1)'::point做。

我會說這是一個錯誤,應該報告。

引用自:https://dba.stackexchange.com/questions/73631