|
87 | 87 | * produce exactly one output run from their partial input.
|
88 | 88 | *
|
89 | 89 | *
|
90 |
| - * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group |
| 90 | + * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group |
91 | 91 | * Portions Copyright (c) 1994, Regents of the University of California
|
92 | 92 | *
|
93 | 93 | * IDENTIFICATION
|
@@ -459,6 +459,7 @@ struct Tuplesortstate
|
459 | 459 |
|
460 | 460 | /* These are specific to the index_btree subcase: */
|
461 | 461 | bool enforceUnique; /* complain if we find duplicate tuples */
|
| 462 | + bool uniqueNullsNotDistinct; /* unique constraint null treatment */ |
462 | 463 |
|
463 | 464 | /* These are specific to the index_hash subcase: */
|
464 | 465 | uint32 high_mask; /* masks for sortable part of hash code */
|
@@ -1065,6 +1066,7 @@ Tuplesortstate *
|
1065 | 1066 | tuplesort_begin_index_btree(Relation heapRel,
|
1066 | 1067 | Relation indexRel,
|
1067 | 1068 | bool enforceUnique,
|
| 1069 | + bool uniqueNullsNotDistinct, |
1068 | 1070 | int workMem,
|
1069 | 1071 | SortCoordinate coordinate,
|
1070 | 1072 | bool randomAccess)
|
@@ -1103,6 +1105,7 @@ tuplesort_begin_index_btree(Relation heapRel,
|
1103 | 1105 | state->heapRel = heapRel;
|
1104 | 1106 | state->indexRel = indexRel;
|
1105 | 1107 | state->enforceUnique = enforceUnique;
|
| 1108 | + state->uniqueNullsNotDistinct = uniqueNullsNotDistinct; |
1106 | 1109 |
|
1107 | 1110 | indexScanKey = _bt_mkscankey(indexRel, NULL);
|
1108 | 1111 |
|
@@ -4200,14 +4203,15 @@ comparetup_index_btree(const SortTuple *a, const SortTuple *b,
|
4200 | 4203 |
|
4201 | 4204 | /*
|
4202 | 4205 | * If btree has asked us to enforce uniqueness, complain if two equal
|
4203 |
| - * tuples are detected (unless there was at least one NULL field). |
| 4206 | + * tuples are detected (unless there was at least one NULL field and NULLS |
| 4207 | + * NOT DISTINCT was not set). |
4204 | 4208 | *
|
4205 | 4209 | * It is sufficient to make the test here, because if two tuples are equal
|
4206 | 4210 | * they *must* get compared at some stage of the sort --- otherwise the
|
4207 | 4211 | * sort algorithm wouldn't have checked whether one must appear before the
|
4208 | 4212 | * other.
|
4209 | 4213 | */
|
4210 |
| - if (state->enforceUnique && !equal_hasnull) |
| 4214 | + if (state->enforceUnique && !(!state->uniqueNullsNotDistinct && equal_hasnull)) |
4211 | 4215 | {
|
4212 | 4216 | Datum values[INDEX_MAX_KEYS];
|
4213 | 4217 | bool isnull[INDEX_MAX_KEYS];
|
|
0 commit comments