Skip to content

Commit

Permalink
Fix handling for multiple unique index in compressed INSERT
Browse files Browse the repository at this point in the history
Adjust compressed_insert_key_columns to correctly handle multiple
unique indexes. This patch changes the function to no longer combine
the columns from multiple indexes but instead only return columns
from the first matching index that is found.
This patch also fixes a couple comments in that function.
  • Loading branch information
svenklemm committed Jun 25, 2024
1 parent e2089f7 commit 99aa76b
Showing 1 changed file with 17 additions and 25 deletions.
42 changes: 17 additions & 25 deletions tsl/src/compression/compression.c
Original file line number Diff line number Diff line change
Expand Up @@ -2175,10 +2175,11 @@ create_segment_filter_scankey(RowDecompressor *decompressor, char *segment_filte

/*
* For insert into compressed chunks with unique index determine the
* columns which are safe to use for batch filtering.
* columns which can be used for INSERT batch filtering.
* The passed in relation is the uncompressed chunk.
*
* This is based on RelationGetIndexAttrBitmap from postgres with changes
* to also track unique expression indexes.
* In case of multiple unique indexes we have to pick one and must not
* combine the columns from different indexes, so we just pick first one.
*/
static Bitmapset *
compressed_insert_key_columns(Relation relation)
Expand All @@ -2196,44 +2197,35 @@ compressed_insert_key_columns(Relation relation)
if (indexoidlist == NIL)
return NULL;

/*
* For each index, add referenced attributes to indexattrs.
*
* Note: we consider all indexes returned by RelationGetIndexList, even if
* they are not indisready or indisvalid. This is important because an
* index for which CREATE INDEX CONCURRENTLY has just started must be
* included in HOT-safety decisions (see README.HOT). If a DROP INDEX
* CONCURRENTLY is far enough along that we should ignore the index, it
* won't be returned at all by RelationGetIndexList.
*/
foreach (l, indexoidlist)
{
Oid indexOid = lfirst_oid(l);
Relation indexDesc = index_open(indexOid, AccessShareLock);

if (!indexDesc->rd_index->indisunique)
/*
* We are only interested in unique indexes that are not partial.
* PRIMARY KEY indexes also have indisunique set to true so we do not
* need to check for them separately.
*/
if (!indexDesc->rd_index->indislive || !indexDesc->rd_index->indisvalid ||
!indexDesc->rd_index->indisunique || indexDesc->rd_indpred || indexDesc->rd_indexprs)
{
index_close(indexDesc, AccessShareLock);
continue;
}

/* Collect simple attribute references.
* For covering indexes we only need to collect the key attributes.
* Unlike RelationGetIndexAttrBitmap we allow expression indexes
* but we do not extract attributes from the expressions as that
* would not be a safe filter as the expression can alter attributes
* which would not make them sufficient for batch filtering.
/*
* Collect simple attribute references.
* For covering indexes we need to ignore the included columns.
*/
for (int i = 0; i < indexDesc->rd_index->indnkeyatts; i++)
{
int attrnum = indexDesc->rd_index->indkey.values[i];
if (attrnum != 0)
{
indexattrs =
bms_add_member(indexattrs, attrnum - FirstLowInvalidHeapAttributeNumber);
}
indexattrs = bms_add_member(indexattrs, attrnum - FirstLowInvalidHeapAttributeNumber);
}
index_close(indexDesc, AccessShareLock);

return indexattrs;
}

return indexattrs;
Expand Down

0 comments on commit 99aa76b

Please sign in to comment.