Clean up around lexical comparisons
authorPeter Geoghegan <[email protected]>
Wed, 12 Mar 2014 04:07:46 +0000 (21:07 -0700)
committerPeter Geoghegan <[email protected]>
Wed, 12 Mar 2014 04:07:46 +0000 (21:07 -0700)
src/backend/utils/adt/jsonb_op.c
src/backend/utils/adt/jsonb_support.c
src/include/utils/jsonb.h

index 5aff4c6158758ae56aade7a0c83658432b8d9ca8..6c138339f8fe0f29055e1735d419875c0f541c7d 100644 (file)
@@ -380,7 +380,7 @@ deepContains(JsonbIterator ** it1, JsonbIterator ** it2)
            else if (v->type == jbvString || v->type == jbvNull ||
                     v->type == jbvBool || v->type == jbvNumeric)
            {
-               if (compareJsonbValue(v, &v2) != 0)
+               if (!compareJsonbValue(v, &v2))
                {
                    res = false;
                    break;
index bbcec8bd72917e5094cf844970e67abf7b4bfd01..327c54c625cb55917d96b1c356f1126e72a3855d 100644 (file)
@@ -137,13 +137,20 @@ JsonbValueToJsonb(JsonbValue * v)
 }
 
 /*
- * Compare 2 JsonbValues.
+ * Are two JsonbValues a and b equal?
  *
- * Uses lexical string sorting.
+ * Does not use lexical comparisons.  Therefore, it is essentially that this
+ * never be used for anything other than searching for values within a single
+ * jsonb.
+ *
+ * We return bool because we don't want to give anyone any ideas about using
+ * this for sorting.  This is just for "contains" style searching.
  */
-int
+bool
 compareJsonbValue(JsonbValue * a, JsonbValue * b)
 {
+   int         i;
+
    check_stack_depth();
 
    if (a->type == b->type)
@@ -151,66 +158,54 @@ compareJsonbValue(JsonbValue * a, JsonbValue * b)
        switch (a->type)
        {
            case jbvNull:
-               return 0;
+               return true;
            case jbvString:
-               return lexicalCompareJsonbStringValue(a, b);
+               return lengthCompareJsonbStringValue(a, b, NULL) == 0;
            case jbvBool:
-               if (a->boolean == b->boolean)
-                   return 0;
-               return (a->boolean > b->boolean) ? 1 : -1;
+               return a->boolean == b->boolean;
            case jbvNumeric:
-               return DatumGetInt32(DirectFunctionCall2(numeric_cmp,
-                                                PointerGetDatum(a->numeric),
-                                              PointerGetDatum(b->numeric)));
+               return DatumGetBool(DirectFunctionCall2(numeric_eq,
+                                                       PointerGetDatum(a->numeric),
+                                                       PointerGetDatum(b->numeric)));
            case jbvArray:
                if (a->array.nelems == b->array.nelems)
                {
-                   int         i,
-                               r;
-
                    for (i = 0; i < a->array.nelems; i++)
-                       if ((r = compareJsonbValue(a->array.elems + i,
-                                                  b->array.elems + i)) != 0)
-                           return r;
-
-                   return 0;
+                       if (compareJsonbValue(a->array.elems + i,
+                                             b->array.elems + i))
+                           return true;
                }
-
-               return (a->array.nelems > b->array.nelems) ? 1 : -1;
+               break;
            case jbvObject:
                if (a->object.npairs == b->object.npairs)
                {
-                   int         i,
-                               r;
-
                    for (i = 0; i < a->object.npairs; i++)
                    {
-                       if ((r = lexicalCompareJsonbStringValue(&a->object.pairs[i].key,
-                                                               &b->object.pairs[i].key)) != 0)
-                           return r;
-                       if ((r = compareJsonbValue(&a->object.pairs[i].value,
-                                           &b->object.pairs[i].value)) != 0)
-                           return r;
+                       if (lengthCompareJsonbStringValue(&a->object.pairs[i].key,
+                                                         &b->object.pairs[i].key,
+                                                         NULL) == 0)
+                           return true;
+                       if (compareJsonbValue(&a->object.pairs[i].value,
+                                             &b->object.pairs[i].value))
+                           return true;
                    }
-
-                   return 0;
                }
-
-               return (a->object.npairs > b->object.npairs) ? 1 : -1;
+               break;
            case jbvBinary:
-               return compareJsonbBinaryValue(a->binary.data, b->binary.data);
+               /* This wastes a few cycles on unneeded lexical comparisons */
+               return compareJsonbBinaryValue(a->binary.data, b->binary.data) == 0;
            default:
                elog(ERROR, "invalid jsonb scalar type");
        }
    }
 
-   return (a->type > b->type) ? 1 : -1;
+   return false;
 }
 
 /*
  * Gives consistent ordering of Jsonb values.
  *
- * Strings are compared lexically.
+ * Strings are compared lexically, making this suitable as a sort comparator.
  */
 int
 compareJsonbBinaryValue(char *a, char *b)
@@ -1336,13 +1331,13 @@ lengthCompareJsonbStringValue(const void *a, const void *b, void *binequal)
  * Pairs with equals keys are ordered such that the order field is respected.
  */
 static int
-lengthCompareJsonbPair(const void *a, const void *b, void *arg)
+lengthCompareJsonbPair(const void *a, const void *b, void *binequal)
 {
-   const JsonbPair *pa = a;
-   const JsonbPair *pb = b;
+   const JsonbPair *pa = (const JsonbPair *) a;
+   const JsonbPair *pb = (const JsonbPair *) b;
    int         res;
 
-   res = lengthCompareJsonbStringValue(&pa->key, &pb->key, arg);
+   res = lengthCompareJsonbStringValue(&pa->key, &pb->key, binequal);
 
    /*
     * Guarantee keeping order of equal pair. Unique algorithm will prefer
index 1fa8eb7aeb80509defb11dded12e38d6ccf51720..bd9c9eed519b9a25b4fa4ac6c926d8f74d060abd 100644 (file)
@@ -222,7 +222,7 @@ extern Datum gin_consistent_jsonb_hash(PG_FUNCTION_ARGS);
 
 /* Support functions */
 extern int compareJsonbBinaryValue(char *a, char *b);
-extern int compareJsonbValue(JsonbValue *a, JsonbValue *b);
+extern bool    compareJsonbValue(JsonbValue *a, JsonbValue *b);
 extern JsonbValue *findUncompressedJsonbValueByValue(char *buffer, uint32 flags,
                                  uint32 *lowbound, JsonbValue *key);
 extern JsonbValue *findUncompressedJsonbValue(char *buffer, uint32 flags,