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);
switch (va.type)
{
case jbvString:
- res = lexicalCompareJsonbStringValue(&va, &vb);
- break;
case jbvNull:
case jbvNumeric:
case jbvBool:
if (key->type == result->type)
{
- if (compareJsonbScalarValue(key, result) == 0)
+ if (equalsJsonbScalarValue(key, result))
return result;
}
}
}
else if (IsAJsonbScalar(lhsVal))
{
- if (compareJsonbScalarValue(lhsVal, &vcontained) != 0)
+ if (!equalsJsonbScalarValue(lhsVal, &vcontained))
return false;
}
else
/*
* 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");
}
}
/*
- * 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;
}