3434
3535static void fillJsonbValue (JEntry * array ,int index ,char * base_addr ,
3636JsonbValue * result );
37+ static bool equalsJsonbScalarValue (JsonbValue * a ,JsonbValue * b );
3738static int compareJsonbScalarValue (JsonbValue * a ,JsonbValue * b );
38- static int lexicalCompareJsonbStringValue (const void * a ,const void * b );
3939static Jsonb * convertToJsonb (JsonbValue * val );
4040static void convertJsonbValue (StringInfo buffer ,JEntry * header ,JsonbValue * val ,int level );
4141static void convertJsonbArray (StringInfo buffer ,JEntry * header ,JsonbValue * val ,int level );
@@ -161,8 +161,6 @@ compareJsonbContainers(JsonbContainer *a, JsonbContainer *b)
161161switch (va .type )
162162{
163163case jbvString :
164- res = lexicalCompareJsonbStringValue (& va ,& vb );
165- break ;
166164case jbvNull :
167165case jbvNumeric :
168166case jbvBool :
@@ -289,7 +287,7 @@ findJsonbValueFromContainer(JsonbContainer *container, uint32 flags,
289287
290288if (key -> type == result -> type )
291289{
292- if (compareJsonbScalarValue (key ,result )== 0 )
290+ if (equalsJsonbScalarValue (key ,result ))
293291return result ;
294292}
295293}
@@ -917,7 +915,7 @@ JsonbDeepContains(JsonbIterator **val, JsonbIterator **mContained)
917915}
918916else if (IsAJsonbScalar (lhsVal ))
919917{
920- if (compareJsonbScalarValue (lhsVal ,& vcontained )!= 0 )
918+ if (! equalsJsonbScalarValue (lhsVal ,& vcontained ))
921919return false;
922920}
923921else
@@ -1118,31 +1116,25 @@ JsonbHashScalarValue(const JsonbValue *scalarVal, uint32 *hash)
11181116
11191117/*
11201118 * Are two scalar JsonbValues of the same type a and b equal?
1121- *
1122- * Does not use lexical comparisons. Therefore, it is essentially that this
1123- * never be used against Strings for anything other than searching for values
1124- * within a single jsonb.
11251119 */
1126- static int
1127- compareJsonbScalarValue (JsonbValue * aScalar ,JsonbValue * bScalar )
1120+ static bool
1121+ equalsJsonbScalarValue (JsonbValue * aScalar ,JsonbValue * bScalar )
11281122{
11291123if (aScalar -> type == bScalar -> type )
11301124{
11311125switch (aScalar -> type )
11321126{
11331127case jbvNull :
1134- return 0 ;
1128+ return true ;
11351129case jbvString :
1136- return lengthCompareJsonbStringValue (aScalar ,bScalar );
1130+ return lengthCompareJsonbStringValue (aScalar ,bScalar )== 0 ;
11371131case jbvNumeric :
1138- return DatumGetInt32 (DirectFunctionCall2 (numeric_cmp ,
1132+ return DatumGetBool (DirectFunctionCall2 (numeric_eq ,
11391133PointerGetDatum (aScalar -> val .numeric ),
11401134PointerGetDatum (bScalar -> val .numeric )));
11411135case jbvBool :
1142- if (aScalar -> val .boolean != bScalar -> val .boolean )
1143- return (aScalar -> val .boolean > bScalar -> val .boolean ) ?1 :-1 ;
1144- else
1145- return 0 ;
1136+ return aScalar -> val .boolean == bScalar -> val .boolean ;
1137+
11461138default :
11471139elog (ERROR ,"invalid jsonb scalar type" );
11481140}
@@ -1152,22 +1144,43 @@ compareJsonbScalarValue(JsonbValue *aScalar, JsonbValue *bScalar)
11521144}
11531145
11541146/*
1155- *Standard lexical qsort() comparator of jsonb strings .
1147+ *Compare two scalar JsonbValues, returning -1, 0, or 1 .
11561148 *
1157- *Sorts strings lexically, using the defaultdatabase collation. Used by
1158- *B-Tree operators, where a lexical sort order is generally expected.
1149+ *Strings are compared using the default collation. Used by B-tree
1150+ * operators, where a lexical sort order is generally expected.
11591151 */
11601152static int
1161- lexicalCompareJsonbStringValue ( const void * a , const void * b )
1153+ compareJsonbScalarValue ( JsonbValue * aScalar , JsonbValue * bScalar )
11621154{
1163- const JsonbValue * va = (const JsonbValue * )a ;
1164- const JsonbValue * vb = (const JsonbValue * )b ;
1165-
1166- Assert (va -> type == jbvString );
1167- Assert (vb -> type == jbvString );
1168-
1169- return varstr_cmp (va -> val .string .val ,va -> val .string .len ,vb -> val .string .val ,
1170- vb -> val .string .len ,DEFAULT_COLLATION_OID );
1155+ if (aScalar -> type == bScalar -> type )
1156+ {
1157+ switch (aScalar -> type )
1158+ {
1159+ case jbvNull :
1160+ return 0 ;
1161+ case jbvString :
1162+ return varstr_cmp (aScalar -> val .string .val ,
1163+ aScalar -> val .string .len ,
1164+ bScalar -> val .string .val ,
1165+ bScalar -> val .string .len ,
1166+ DEFAULT_COLLATION_OID );
1167+ case jbvNumeric :
1168+ return DatumGetInt32 (DirectFunctionCall2 (numeric_cmp ,
1169+ PointerGetDatum (aScalar -> val .numeric ),
1170+ PointerGetDatum (bScalar -> val .numeric )));
1171+ case jbvBool :
1172+ if (aScalar -> val .boolean == bScalar -> val .boolean )
1173+ return 0 ;
1174+ else if (aScalar -> val .boolean > bScalar -> val .boolean )
1175+ return 1 ;
1176+ else
1177+ return -1 ;
1178+ default :
1179+ elog (ERROR ,"invalid jsonb scalar type" );
1180+ }
1181+ }
1182+ elog (ERROR ,"jsonb scalar type mismatch" );
1183+ return -1 ;
11711184}
11721185
11731186