Skip to content
Snippets Groups Projects
Commit cc62dc20 authored by Tom Lane's avatar Tom Lane
Browse files

Fix tuplecmp() to ensure repeatable sort ordering of tuples

that contain null fields.  Old code would produce erratic sort results
because comparisons of tuples containing nulls could produce inconsistent
answers.
parent bc5f34c8
No related branches found
No related tags found
No related merge requests found
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/lselect.c,v 1.15 1999/02/13 23:20:15 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/lselect.c,v 1.16 1999/07/10 18:21:59 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -186,41 +186,49 @@ puttuple(struct leftist ** treep, ...@@ -186,41 +186,49 @@ puttuple(struct leftist ** treep,
int int
tuplecmp(HeapTuple ltup, HeapTuple rtup, LeftistContext context) tuplecmp(HeapTuple ltup, HeapTuple rtup, LeftistContext context)
{ {
Datum lattr, int nkey;
rattr;
int nkey = 0;
int result = 0; int result = 0;
bool isnull;
if (ltup == (HeapTuple) NULL) if (ltup == (HeapTuple) NULL)
return 0; return 0;
if (rtup == (HeapTuple) NULL) if (rtup == (HeapTuple) NULL)
return 1; return 1;
while (nkey < context->nKeys && !result) for (nkey = 0; nkey < context->nKeys; nkey++)
{ {
lattr = heap_getattr(ltup, ScanKey thisKey = & context->scanKeys[nkey];
context->scanKeys[nkey].sk_attno, Datum lattr,
context->tupDesc, &isnull); rattr;
if (isnull) bool lisnull,
return 0; risnull;
rattr = heap_getattr(rtup,
context->scanKeys[nkey].sk_attno, lattr = heap_getattr(ltup, thisKey->sk_attno,
context->tupDesc, context->tupDesc, &lisnull);
&isnull); rattr = heap_getattr(rtup, thisKey->sk_attno,
if (isnull) context->tupDesc, &risnull);
if (lisnull)
{
if (risnull)
continue; /* treat two nulls as equal */
return 0; /* else, a null sorts after all else */
}
if (risnull)
return 1; return 1;
if (context->scanKeys[nkey].sk_flags & SK_COMMUTE) if (thisKey->sk_flags & SK_COMMUTE)
{
if (!(result =
(long) (*fmgr_faddr(&thisKey->sk_func)) (rattr, lattr)))
result =
-(long) (*fmgr_faddr(&thisKey->sk_func)) (lattr, rattr);
}
else
{ {
if (!(result = if (!(result =
(long) (*fmgr_faddr(&context->scanKeys[nkey].sk_func)) (rattr, lattr))) (long) (*fmgr_faddr(&thisKey->sk_func)) (lattr, rattr)))
result = result =
-(long) (*fmgr_faddr(&context->scanKeys[nkey].sk_func)) (lattr, rattr); -(long) (*fmgr_faddr(&thisKey->sk_func)) (rattr, lattr);
} }
else if (!(result = if (result)
(long) (*fmgr_faddr(&context->scanKeys[nkey].sk_func)) (lattr, rattr))) break;
result =
-(long) (*fmgr_faddr(&context->scanKeys[nkey].sk_func)) (rattr, lattr);
nkey++;
} }
return result == 1; return result == 1;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment