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.
This commit is contained in:
Heikki Linnakangas 2014-05-28 23:44:31 +03:00
parent b3e5cfd5f9
commit d1d50bff24

View 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,10 +1116,38 @@ JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash)
/*
* Are two scalar JsonbValues of the same type a and b equal?
*/
static bool
equalsJsonbScalarValue(JsonbValue *aScalar, JsonbValue *bScalar)
{
if (aScalar->type == bScalar->type)
{
switch (aScalar->type)
{
case jbvNull:
return true;
case jbvString:
return lengthCompareJsonbStringValue(aScalar, bScalar) == 0;
case jbvNumeric:
return DatumGetBool(DirectFunctionCall2(numeric_eq,
PointerGetDatum(aScalar->val.numeric),
PointerGetDatum(bScalar->val.numeric)));
case jbvBool:
return aScalar->val.boolean == bScalar->val.boolean;
default:
elog(ERROR, "invalid jsonb scalar type");
}
}
elog(ERROR, "jsonb scalar type mismatch");
return -1;
}
/*
* Compare two scalar JsonbValues, returning -1, 0, or 1.
*
* 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.
* Strings are compared using the default collation. Used by B-tree
* operators, where a lexical sort order is generally expected.
*/
static int
compareJsonbScalarValue(JsonbValue *aScalar, JsonbValue *bScalar)
@ -1133,16 +1159,22 @@ compareJsonbScalarValue(JsonbValue *aScalar, JsonbValue *bScalar)
case jbvNull:
return 0;
case jbvString:
return lengthCompareJsonbStringValue(aScalar, bScalar);
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 (aScalar->val.boolean > bScalar->val.boolean) ? 1 : -1;
else
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");
}
@ -1151,25 +1183,6 @@ compareJsonbScalarValue(JsonbValue *aScalar, JsonbValue *bScalar)
return -1;
}
/*
* Standard lexical qsort() comparator of jsonb strings.
*
* Sorts strings lexically, using the default database collation. Used by
* B-Tree operators, where a lexical sort order is generally expected.
*/
static int
lexicalCompareJsonbStringValue(const void *a, const void *b)
{
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);
}
/*
* Functions for manipulating the resizeable buffer used by convertJsonb and