]> granicus.if.org Git - postgresql/commitdiff
Minor refactoring of jsonb_util.c
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 28 May 2014 20:44:31 +0000 (23:44 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 28 May 2014 20:48:02 +0000 (23:48 +0300)
The only caller of compareJsonbScalarValue that needed locale-sensitive
comparison of strings was also the only caller that didn't just check for
equality. Separate the two cases for clarity: compareJsonbScalarValue now
does locale-sensitive comparison, and a new function,
equalsJsonbScalarValue, just checks for equality.

src/backend/utils/adt/jsonb_util.c

index 434c68bd24ea62d2d8fda18ebc39a51121489406..93bb148232e140d357c0fb60aac04beddc03d43c 100644 (file)
@@ -34,8 +34,8 @@
 
 static void fillJsonbValue(JEntry *array, int index, char *base_addr,
                           JsonbValue *result);
+static bool    equalsJsonbScalarValue(JsonbValue *a, JsonbValue *b);
 static int     compareJsonbScalarValue(JsonbValue *a, JsonbValue *b);
-static int     lexicalCompareJsonbStringValue(const void *a, const void *b);
 static Jsonb *convertToJsonb(JsonbValue *val);
 static void convertJsonbValue(StringInfo buffer, JEntry *header, JsonbValue *val, int level);
 static void convertJsonbArray(StringInfo buffer, JEntry *header, JsonbValue *val, int level);
@@ -161,8 +161,6 @@ compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
                                switch (va.type)
                                {
                                        case jbvString:
-                                               res = lexicalCompareJsonbStringValue(&va, &vb);
-                                               break;
                                        case jbvNull:
                                        case jbvNumeric:
                                        case jbvBool:
@@ -289,7 +287,7 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags,
 
                        if (key->type == result->type)
                        {
-                               if (compareJsonbScalarValue(key, result) == 0)
+                               if (equalsJsonbScalarValue(key, result))
                                        return result;
                        }
                }
@@ -917,7 +915,7 @@ JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
                        }
                        else if (IsAJsonbScalar(lhsVal))
                        {
-                               if (compareJsonbScalarValue(lhsVal, &vcontained) != 0)
+                               if (!equalsJsonbScalarValue(lhsVal, &vcontained))
                                        return false;
                        }
                        else
@@ -1118,31 +1116,25 @@ JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash)
 
 /*
  * Are two scalar JsonbValues of the same type a and b equal?
- *
- * Does not use lexical comparisons.  Therefore, it is essentially that this
- * never be used against Strings for anything other than searching for values
- * within a single jsonb.
  */
-static int
-compareJsonbScalarValue(JsonbValue *aScalar, JsonbValue *bScalar)
+static bool
+equalsJsonbScalarValue(JsonbValue *aScalar, JsonbValue *bScalar)
 {
        if (aScalar->type == bScalar->type)
        {
                switch (aScalar->type)
                {
                        case jbvNull:
-                               return 0;
+                               return true;
                        case jbvString:
-                               return lengthCompareJsonbStringValue(aScalar, bScalar);
+                               return lengthCompareJsonbStringValue(aScalar, bScalar) == 0;
                        case jbvNumeric:
-                               return DatumGetInt32(DirectFunctionCall2(numeric_cmp,
+                               return DatumGetBool(DirectFunctionCall2(numeric_eq,
                                                                           PointerGetDatum(aScalar->val.numeric),
                                                                         PointerGetDatum(bScalar->val.numeric)));
                        case jbvBool:
-                               if (aScalar->val.boolean != bScalar->val.boolean)
-                                       return (aScalar->val.boolean > bScalar->val.boolean) ? 1 : -1;
-                               else
-                                       return 0;
+                               return aScalar->val.boolean == bScalar->val.boolean;
+
                        default:
                                elog(ERROR, "invalid jsonb scalar type");
                }
@@ -1152,22 +1144,43 @@ compareJsonbScalarValue(JsonbValue *aScalar, JsonbValue *bScalar)
 }
 
 /*
- * Standard lexical qsort() comparator of jsonb strings.
+ * Compare two scalar JsonbValues, returning -1, 0, or 1.
  *
- * Sorts strings lexically, using the default database collation.  Used by
- * B-Tree operators, where a lexical sort order is generally expected.
+ * Strings are compared using the default collation.  Used by B-tree
+ * operators, where a lexical sort order is generally expected.
  */
 static int
-lexicalCompareJsonbStringValue(const void *a, const void *b)
+compareJsonbScalarValue(JsonbValue *aScalar, JsonbValue *bScalar)
 {
-       const JsonbValue *va = (const JsonbValue *) a;
-       const JsonbValue *vb = (const JsonbValue *) b;
-
-       Assert(va->type == jbvString);
-       Assert(vb->type == jbvString);
-
-       return varstr_cmp(va->val.string.val, va->val.string.len, vb->val.string.val,
-                                         vb->val.string.len, DEFAULT_COLLATION_OID);
+       if (aScalar->type == bScalar->type)
+       {
+               switch (aScalar->type)
+               {
+                       case jbvNull:
+                               return 0;
+                       case jbvString:
+                               return varstr_cmp(aScalar->val.string.val,
+                                                                 aScalar->val.string.len,
+                                                                 bScalar->val.string.val,
+                                                                 bScalar->val.string.len,
+                                                                 DEFAULT_COLLATION_OID);
+                       case jbvNumeric:
+                               return DatumGetInt32(DirectFunctionCall2(numeric_cmp,
+                                                                          PointerGetDatum(aScalar->val.numeric),
+                                                                        PointerGetDatum(bScalar->val.numeric)));
+                       case jbvBool:
+                               if (aScalar->val.boolean == bScalar->val.boolean)
+                                       return 0;
+                               else if (aScalar->val.boolean > bScalar->val.boolean)
+                                       return 1;
+                               else
+                                       return -1;
+                       default:
+                               elog(ERROR, "invalid jsonb scalar type");
+               }
+       }
+       elog(ERROR, "jsonb scalar type mismatch");
+       return -1;
 }