aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/jsonb_util.c
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-05-28 23:44:31 +0300
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-05-28 23:48:02 +0300
commitd1d50bff247f189a6a1477596cdbd52d097089a0 (patch)
treec20a56e5bafb3cfe872a3bc10d53a11d40081411 /src/backend/utils/adt/jsonb_util.c
parentb3e5cfd5f979054e31d60adafd9e75bf9c38549a (diff)
downloadpostgresql-d1d50bff247f189a6a1477596cdbd52d097089a0.tar.gz
postgresql-d1d50bff247f189a6a1477596cdbd52d097089a0.zip
Minor refactoring of jsonb_util.c
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.
Diffstat (limited to 'src/backend/utils/adt/jsonb_util.c')
-rw-r--r--src/backend/utils/adt/jsonb_util.c73
1 files changed, 43 insertions, 30 deletions
diff --git a/src/backend/utils/adt/jsonb_util.c b/src/backend/utils/adt/jsonb_util.c
index 434c68bd24e..93bb148232e 100644
--- a/src/backend/utils/adt/jsonb_util.c
+++ b/src/backend/utils/adt/jsonb_util.c
@@ -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;
}