diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2014-05-28 23:44:31 +0300 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2014-05-28 23:48:02 +0300 |
commit | d1d50bff247f189a6a1477596cdbd52d097089a0 (patch) | |
tree | c20a56e5bafb3cfe872a3bc10d53a11d40081411 /src/backend/utils/adt/jsonb_util.c | |
parent | b3e5cfd5f979054e31d60adafd9e75bf9c38549a (diff) | |
download | postgresql-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.c | 73 |
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; } |