Postgresql
為什麼在更新點欄位並且該欄位為 NULL 時,數組語法的行為與 ‘(?,?)’ 語法不同?
我正在使用 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]
。這真的應該做兩件事之一:
- 設置
point
為NULL
- 喜歡SELECT point(NULL,1)
。- 引發異常 - 就像這樣
SELECT '(NULL,1)'::point
做。我會說這是一個錯誤,應該報告。