diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2001-05-03 19:00:37 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2001-05-03 19:00:37 +0000 |
commit | 2792374cff361a7a4ec0e750b5fa935d85afc9ac (patch) | |
tree | 98736405bf8af30af89bdf224802f868057b7d2a /src/backend/utils/adt/varbit.c | |
parent | 77fe28f33e49d752be4e4a1bbc6c112f825e7882 (diff) | |
download | postgresql-2792374cff361a7a4ec0e750b5fa935d85afc9ac.tar.gz postgresql-2792374cff361a7a4ec0e750b5fa935d85afc9ac.zip |
Ensure that btree sort ordering functions and boolean comparison operators
give consistent results for all datatypes. Types float4, float8, and
numeric were broken for NaN values; abstime, timestamp, and interval
were broken for INVALID values; timetz was just plain broken (some
possible pairs of values were neither < nor = nor >). Also clean up
text, bpchar, varchar, and bit/varbit to eliminate duplicate code and
thereby reduce the probability of similar inconsistencies arising in
the future.
Diffstat (limited to 'src/backend/utils/adt/varbit.c')
-rw-r--r-- | src/backend/utils/adt/varbit.c | 76 |
1 files changed, 37 insertions, 39 deletions
diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c index 775382568bb..5d03683dd6b 100644 --- a/src/backend/utils/adt/varbit.c +++ b/src/backend/utils/adt/varbit.c @@ -9,7 +9,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.16 2001/03/22 03:59:54 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.17 2001/05/03 19:00:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -537,6 +537,36 @@ _varbit(PG_FUNCTION_ARGS) * need to be so careful. */ +/* bit_cmp + * + * Compares two bitstrings and returns <0, 0, >0 depending on whether the first + * string is smaller, equal, or bigger than the second. All bits are considered + * and additional zero bits may make one string smaller/larger than the other, + * even if their zero-padded values would be the same. + */ +static int32 +bit_cmp(VarBit *arg1, VarBit *arg2) +{ + int bitlen1, + bytelen1, + bitlen2, + bytelen2; + int32 cmp; + + bytelen1 = VARBITBYTES(arg1); + bytelen2 = VARBITBYTES(arg2); + + cmp = memcmp(VARBITS(arg1), VARBITS(arg2), Min(bytelen1, bytelen2)); + if (cmp == 0) + { + bitlen1 = VARBITLEN(arg1); + bitlen2 = VARBITLEN(arg2); + if (bitlen1 != bitlen2) + cmp = (bitlen1 < bitlen2) ? -1 : 1; + } + return cmp; +} + Datum biteq(PG_FUNCTION_ARGS) { @@ -548,13 +578,12 @@ biteq(PG_FUNCTION_ARGS) bitlen1 = VARBITLEN(arg1); bitlen2 = VARBITLEN(arg2); + + /* fast path for different-length inputs */ if (bitlen1 != bitlen2) result = false; else - { - /* bit strings are always stored in a full number of bytes */ - result = memcmp(VARBITS(arg1), VARBITS(arg2), VARBITBYTES(arg1)) == 0; - } + result = (bit_cmp(arg1, arg2) == 0); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); @@ -573,13 +602,12 @@ bitne(PG_FUNCTION_ARGS) bitlen1 = VARBITLEN(arg1); bitlen2 = VARBITLEN(arg2); + + /* fast path for different-length inputs */ if (bitlen1 != bitlen2) result = true; else - { - /* bit strings are always stored in a full number of bytes */ - result = memcmp(VARBITS(arg1), VARBITS(arg2), VARBITBYTES(arg1)) != 0; - } + result = (bit_cmp(arg1, arg2) != 0); PG_FREE_IF_COPY(arg1, 0); PG_FREE_IF_COPY(arg2, 1); @@ -587,36 +615,6 @@ bitne(PG_FUNCTION_ARGS) PG_RETURN_BOOL(result); } -/* bit_cmp - * - * Compares two bitstrings and returns <0, 0, >0 depending on whether the first - * string is smaller, equal, or bigger than the second. All bits are considered - * and additional zero bits may make one string smaller/larger than the other, - * even if their zero-padded values would be the same. - */ -static int32 -bit_cmp(VarBit *arg1, VarBit *arg2) -{ - int bitlen1, - bytelen1, - bitlen2, - bytelen2; - int32 cmp; - - bytelen1 = VARBITBYTES(arg1); - bytelen2 = VARBITBYTES(arg2); - - cmp = memcmp(VARBITS(arg1), VARBITS(arg2), Min(bytelen1, bytelen2)); - if (cmp == 0) - { - bitlen1 = VARBITLEN(arg1); - bitlen2 = VARBITLEN(arg2); - if (bitlen1 != bitlen2) - cmp = (bitlen1 < bitlen2) ? -1 : 1; - } - return cmp; -} - Datum bitlt(PG_FUNCTION_ARGS) { |