|
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