Calculation of keys_are_unique flag was wrong for cases involving

redundant cross-datatype comparisons.  Per example from Merlin Moncure.
This commit is contained in:
Tom Lane 2004-12-15 19:16:39 +00:00
parent 6ad835f55f
commit c3d6c7d8f9
1 changed files with 12 additions and 12 deletions

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.60 2004/08/29 05:06:40 momjian Exp $ * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.61 2004/12/15 19:16:39 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -224,11 +224,11 @@ _bt_preprocess_keys(IndexScanDesc scan)
BTScanOpaque so = (BTScanOpaque) scan->opaque; BTScanOpaque so = (BTScanOpaque) scan->opaque;
int numberOfKeys = scan->numberOfKeys; int numberOfKeys = scan->numberOfKeys;
int new_numberOfKeys; int new_numberOfKeys;
int numberOfEqualCols;
ScanKey inkeys; ScanKey inkeys;
ScanKey outkeys; ScanKey outkeys;
ScanKey cur; ScanKey cur;
ScanKey xform[BTMaxStrategyNumber]; ScanKey xform[BTMaxStrategyNumber];
bool allEqualSoFar;
bool hasOtherTypeEqual; bool hasOtherTypeEqual;
Datum test; Datum test;
int i, int i,
@ -278,7 +278,7 @@ _bt_preprocess_keys(IndexScanDesc scan)
* Otherwise, do the full set of pushups. * Otherwise, do the full set of pushups.
*/ */
new_numberOfKeys = 0; new_numberOfKeys = 0;
allEqualSoFar = true; numberOfEqualCols = 0;
/* /*
* Initialize for processing of keys for attr 1. * Initialize for processing of keys for attr 1.
@ -321,7 +321,7 @@ _bt_preprocess_keys(IndexScanDesc scan)
*/ */
if (i == numberOfKeys || cur->sk_attno != attno) if (i == numberOfKeys || cur->sk_attno != attno)
{ {
bool priorAllEqualSoFar = allEqualSoFar; int priorNumberOfEqualCols = numberOfEqualCols;
/* check input keys are correctly ordered */ /* check input keys are correctly ordered */
if (i < numberOfKeys && cur->sk_attno != attno + 1) if (i < numberOfKeys && cur->sk_attno != attno + 1)
@ -355,14 +355,14 @@ _bt_preprocess_keys(IndexScanDesc scan)
xform[BTLessEqualStrategyNumber - 1] = NULL; xform[BTLessEqualStrategyNumber - 1] = NULL;
xform[BTGreaterEqualStrategyNumber - 1] = NULL; xform[BTGreaterEqualStrategyNumber - 1] = NULL;
xform[BTGreaterStrategyNumber - 1] = NULL; xform[BTGreaterStrategyNumber - 1] = NULL;
/* track number of attrs for which we have "=" keys */
numberOfEqualCols++;
} }
else else
{ {
/* /* track number of attrs for which we have "=" keys */
* If no "=" for this key, we're done with required keys if (hasOtherTypeEqual)
*/ numberOfEqualCols++;
if (!hasOtherTypeEqual)
allEqualSoFar = false;
} }
/* keep only one of <, <= */ /* keep only one of <, <= */
@ -411,7 +411,7 @@ _bt_preprocess_keys(IndexScanDesc scan)
* If all attrs before this one had "=", include these keys * If all attrs before this one had "=", include these keys
* into the required-keys count. * into the required-keys count.
*/ */
if (priorAllEqualSoFar) if (priorNumberOfEqualCols == attno - 1)
so->numberOfRequiredKeys = new_numberOfKeys; so->numberOfRequiredKeys = new_numberOfKeys;
/* /*
@ -468,8 +468,8 @@ _bt_preprocess_keys(IndexScanDesc scan)
* If unique index and we have equality keys for all columns, set * If unique index and we have equality keys for all columns, set
* keys_are_unique flag for higher levels. * keys_are_unique flag for higher levels.
*/ */
if (allEqualSoFar && relation->rd_index->indisunique && if (relation->rd_index->indisunique &&
relation->rd_rel->relnatts == new_numberOfKeys) relation->rd_rel->relnatts == numberOfEqualCols)
scan->keys_are_unique = true; scan->keys_are_unique = true;
} }