postgresql/src/include/access
Peter Geoghegan 9b10926263 Prevent O(N^2) unique index insertion edge case.
Commit dd299df8 made nbtree treat heap TID as a tiebreaker column,
establishing the principle that there is only one correct location (page
and page offset number) for every index tuple, no matter what.
Insertions of tuples into non-unique indexes proceed as if heap TID
(scan key's scantid) is just another user-attribute value, but
insertions into unique indexes are more delicate.  The TID value in
scantid must initially be omitted to ensure that the unique index
insertion visits every leaf page that duplicates could be on.  The
scantid is set once again after unique checking finishes successfully,
which can force _bt_findinsertloc() to step right one or more times, to
locate the leaf page that the new tuple must be inserted on.

Stepping right within _bt_findinsertloc() was assumed to occur no more
frequently than stepping right within _bt_check_unique(), but there was
one important case where that assumption was incorrect: inserting a
"duplicate" with NULL values.  Since _bt_check_unique() didn't do any
real work in this case, it wasn't appropriate for _bt_findinsertloc() to
behave as if it was finishing off a conventional unique insertion, where
any existing physical duplicate must be dead or recently dead.
_bt_findinsertloc() might have to grovel through a substantial portion
of all of the leaf pages in the index to insert a single tuple, even
when there were no dead tuples.

To fix, treat insertions of tuples with NULLs into a unique index as if
they were insertions into a non-unique index: never unset scantid before
calling _bt_search() to descend the tree, and bypass _bt_check_unique()
entirely.  _bt_check_unique() is no longer responsible for incoming
tuples with NULL values.

Discussion: https://postgr.es/m/CAH2-Wzm08nr+JPx4jMOa9CGqxWYDQ-_D4wtPBiKghXAUiUy-nQ@mail.gmail.com
2019-04-23 10:33:57 -07:00
..
amapi.h Report progress of CREATE INDEX operations 2019-04-02 15:18:08 -03:00
amvalidate.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
attnum.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
brin.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
brin_internal.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
brin_page.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
brin_pageops.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
brin_revmap.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
brin_tuple.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
brin_xlog.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
bufmask.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
clog.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
commit_ts.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
genam.h Report progress of CREATE INDEX operations 2019-04-02 15:18:08 -03:00
generic_xlog.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
gin.h Generate less WAL during GiST, GIN and SP-GiST index build. 2019-04-03 17:03:15 +03:00
gin_private.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
ginblock.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
ginxlog.h Generate less WAL during GiST, GIN and SP-GiST index build. 2019-04-03 17:03:15 +03:00
gist.h Generate less WAL during GiST, GIN and SP-GiST index build. 2019-04-03 17:03:15 +03:00
gist_private.h Convert gist to compute page level xid horizon on primary. 2019-04-22 14:28:30 -07:00
gistscan.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
gistxlog.h Convert gist to compute page level xid horizon on primary. 2019-04-22 14:28:30 -07:00
hash.h Move hash_any prototype from access/hash.h to utils/hashutils.h 2019-03-11 13:17:50 -03:00
hash_xlog.h Compute XID horizon for page level index vacuum on primary. 2019-03-26 16:52:54 -07:00
heapam.h tableam: Add table_multi_insert() and revamp/speed-up COPY FROM buffering. 2019-04-04 16:28:18 -07:00
heapam_xlog.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
hio.h Don't include heapam.h from others headers. 2019-01-14 16:24:41 -08:00
htup.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
htup_details.h Fix heap_getattr() handling of fast defaults. 2019-02-06 01:09:32 -08:00
itup.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
multixact.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
nbtree.h Prevent O(N^2) unique index insertion edge case. 2019-04-23 10:33:57 -07:00
nbtxlog.h Compute XID horizon for page level index vacuum on primary. 2019-03-26 16:52:54 -07:00
parallel.h Enable parallel query with SERIALIZABLE isolation. 2019-03-15 17:47:04 +13:00
printsimple.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
printtup.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
relation.h Introduce access/{table.h, relation.h}, for generic functions from heapam.h. 2019-01-21 10:51:36 -08:00
reloptions.h Finish reverting "recheck_on_update" patch. 2019-01-15 12:07:10 -05:00
relscan.h tableam: Add and use scan APIs. 2019-03-11 12:46:41 -07:00
rewriteheap.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
rmgr.h Phase 2 of pgindent updates. 2017-06-21 15:19:25 -04:00
rmgrlist.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
sdir.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
session.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
skey.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
slru.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
spgist.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
spgist_private.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
spgxlog.h Generate less WAL during GiST, GIN and SP-GiST index build. 2019-04-03 17:03:15 +03:00
stratnum.h Move hash_any prototype from access/hash.h to utils/hashutils.h 2019-03-11 13:17:50 -03:00
subtrans.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
sysattr.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
table.h Introduce access/{table.h, relation.h}, for generic functions from heapam.h. 2019-01-21 10:51:36 -08:00
tableam.h tableam: comment and formatting fixes. 2019-04-08 16:24:36 -07:00
timeline.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
transam.h Use FullTransactionId for the transaction stack. 2019-03-28 18:24:43 +13:00
tsmapi.h tableam: sample scan. 2019-03-31 18:37:57 -07:00
tupconvert.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
tupdesc.h Generated columns 2019-03-30 08:15:57 +01:00
tupdesc_details.h Make naming of tupdesc related structs more consistent with the rest of PG. 2019-01-14 16:25:50 -08:00
tupmacs.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
tuptoaster.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
twophase.h Make release of 2PC identifier and locks consistent in COMMIT PREPARED 2019-02-25 14:19:34 +09:00
twophase_rmgr.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
valid.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
visibilitymap.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
xact.h Log all statements from a sample of transactions 2019-04-03 18:43:59 -03:00
xlog.h Add wal_recycle and wal_init_zero GUCs. 2019-04-02 14:37:14 +13:00
xlog_internal.h Convert gist to compute page level xid horizon on primary. 2019-04-22 14:28:30 -07:00
xlogdefs.h Generate less WAL during GiST, GIN and SP-GiST index build. 2019-04-03 17:03:15 +03:00
xloginsert.h Generate less WAL during GiST, GIN and SP-GiST index build. 2019-04-03 17:03:15 +03:00
xlogreader.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
xlogrecord.h Update copyright for 2019 2019-01-02 12:44:25 -05:00
xlogutils.h Update copyright for 2019 2019-01-02 12:44:25 -05:00