aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/varbit.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2001-05-03 19:00:37 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2001-05-03 19:00:37 +0000
commit2792374cff361a7a4ec0e750b5fa935d85afc9ac (patch)
tree98736405bf8af30af89bdf224802f868057b7d2a /src/backend/utils/adt/varbit.c
parent77fe28f33e49d752be4e4a1bbc6c112f825e7882 (diff)
downloadpostgresql-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.c76
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)
{