mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +03:00
Fix heap_getattr() handling of fast defaults.
Previously heap_getattr() returned NULL for attributes with a fast default value (c.f.16828d5c02
), as it had no handling whatsoever for that case. A previous fix,7636e5c60f
, attempted to fix issues caused by this oversight, but just expanding OLD tuples for triggers doesn't actually solve the underlying issue. One known consequence of this bug is that the check for HOT updates can return the wrong result, when a previously fast-default'ed column is set to NULL. Which in turn means that an index over a column with fast default'ed columns might be corrupt if the underlying column(s) allow NULLs. Fix by handling fast default columns in heap_getattr(), remove now superfluous expansion in GetTupleForTrigger(). Author: Andres Freund Discussion: https://postgr.es/m/20190201162404.onngi77f26baem4g@alap3.anarazel.de Backpatch: 11, where fast defaults were introduced
This commit is contained in:
@ -770,6 +770,33 @@ SELECT * FROM vtype2;
|
||||
2 | yyy
|
||||
(2 rows)
|
||||
|
||||
-- Ensure that defaults are checked when evaluating whether HOT update
|
||||
-- is possible, this was broken for a while:
|
||||
-- https://postgr.es/m/20190202133521.ylauh3ckqa7colzj%40alap3.anarazel.de
|
||||
BEGIN;
|
||||
CREATE TABLE t();
|
||||
INSERT INTO t DEFAULT VALUES;
|
||||
ALTER TABLE t ADD COLUMN a int DEFAULT 1;
|
||||
CREATE INDEX ON t(a);
|
||||
-- set column with a default 1 to NULL, due to a bug that wasn't
|
||||
-- noticed has heap_getattr buggily returned NULL for default columns
|
||||
UPDATE t SET a = NULL;
|
||||
-- verify that index and non-index scans show the same result
|
||||
SET LOCAL enable_seqscan = true;
|
||||
SELECT * FROM t WHERE a IS NULL;
|
||||
a
|
||||
---
|
||||
|
||||
(1 row)
|
||||
|
||||
SET LOCAL enable_seqscan = false;
|
||||
SELECT * FROM t WHERE a IS NULL;
|
||||
a
|
||||
---
|
||||
|
||||
(1 row)
|
||||
|
||||
ROLLBACK;
|
||||
-- cleanup
|
||||
DROP TABLE vtype;
|
||||
DROP TABLE vtype2;
|
||||
|
@ -505,6 +505,26 @@ ALTER TABLE vtype2 ALTER COLUMN b TYPE varchar(20) USING b::varchar(20);
|
||||
SELECT * FROM vtype2;
|
||||
|
||||
|
||||
-- Ensure that defaults are checked when evaluating whether HOT update
|
||||
-- is possible, this was broken for a while:
|
||||
-- https://postgr.es/m/20190202133521.ylauh3ckqa7colzj%40alap3.anarazel.de
|
||||
BEGIN;
|
||||
CREATE TABLE t();
|
||||
INSERT INTO t DEFAULT VALUES;
|
||||
ALTER TABLE t ADD COLUMN a int DEFAULT 1;
|
||||
CREATE INDEX ON t(a);
|
||||
-- set column with a default 1 to NULL, due to a bug that wasn't
|
||||
-- noticed has heap_getattr buggily returned NULL for default columns
|
||||
UPDATE t SET a = NULL;
|
||||
|
||||
-- verify that index and non-index scans show the same result
|
||||
SET LOCAL enable_seqscan = true;
|
||||
SELECT * FROM t WHERE a IS NULL;
|
||||
SET LOCAL enable_seqscan = false;
|
||||
SELECT * FROM t WHERE a IS NULL;
|
||||
ROLLBACK;
|
||||
|
||||
|
||||
-- cleanup
|
||||
DROP TABLE vtype;
|
||||
DROP TABLE vtype2;
|
||||
|
Reference in New Issue
Block a user