mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Dissociate btequalimage() from interval_ops, ending its deduplication.
Under interval_ops, some equal values are distinguishable. One such pair is '24:00:00' and '1 day'. With that being so, btequalimage() breaches the documented contract for the "equalimage" btree support function. This can cause incorrect results from index-only scans. Users should REINDEX any btree indexes having interval-type columns. After updating, pg_amcheck will report an error for almost all such indexes. This fix makes interval_ops simply omit the support function, like numeric_ops does. Back-pack to v13, where btequalimage() first appeared. In back branches, for the benefit of old catalog content, btequalimage() code will return false for type "interval". Going forward, back-branch initdb will include the catalog change. Reviewed by Peter Geoghegan. Discussion: https://postgr.es/m/20231011013317.22.nmisch@google.com
This commit is contained in:
@ -31,6 +31,7 @@
|
||||
#include "access/xact.h"
|
||||
#include "catalog/index.h"
|
||||
#include "catalog/pg_am.h"
|
||||
#include "catalog/pg_opfamily_d.h"
|
||||
#include "commands/tablecmds.h"
|
||||
#include "common/pg_prng.h"
|
||||
#include "lib/bloomfilter.h"
|
||||
@ -338,10 +339,20 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed,
|
||||
errmsg("index \"%s\" metapage has equalimage field set on unsupported nbtree version",
|
||||
RelationGetRelationName(indrel))));
|
||||
if (allequalimage && !_bt_allequalimage(indrel, false))
|
||||
{
|
||||
bool has_interval_ops = false;
|
||||
|
||||
for (int i = 0; i < IndexRelationGetNumberOfKeyAttributes(indrel); i++)
|
||||
if (indrel->rd_opfamily[i] == INTERVAL_BTREE_FAM_OID)
|
||||
has_interval_ops = true;
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INDEX_CORRUPTED),
|
||||
errmsg("index \"%s\" metapage incorrectly indicates that deduplication is safe",
|
||||
RelationGetRelationName(indrel))));
|
||||
RelationGetRelationName(indrel)),
|
||||
has_interval_ops
|
||||
? errhint("This is known of \"interval\" indexes last built on a version predating 2023-11.")
|
||||
: 0));
|
||||
}
|
||||
|
||||
/* Check index, possibly against table it is an index on */
|
||||
bt_check_every_level(indrel, heaprel, heapkeyspace, parentcheck,
|
||||
|
Reference in New Issue
Block a user