diff --git a/doc/src/sgml/json.sgml b/doc/src/sgml/json.sgml index 54648c459c1..206eadb8f7b 100644 --- a/doc/src/sgml/json.sgml +++ b/doc/src/sgml/json.sgml @@ -584,12 +584,13 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @@ '$.tags[*] == "qui"'; The btree ordering for jsonb datums is seldom of great interest, but for completeness it is: -Object > Array > Boolean > Number > String > Null +Object > Array > Boolean > Number > String > null Object with n pairs > object with n - 1 pairs Array with n elements > array with n - 1 elements + with the exception that (for historical reasons) an empty top level array sorts less than null. Objects with equal numbers of pairs are compared in the order: key-1, value-1, key-2 ... diff --git a/src/backend/utils/adt/jsonb_util.c b/src/backend/utils/adt/jsonb_util.c index 806d1aa3a98..773f3690c7b 100644 --- a/src/backend/utils/adt/jsonb_util.c +++ b/src/backend/utils/adt/jsonb_util.c @@ -246,6 +246,13 @@ compareJsonbContainers(JsonbContainer *a, JsonbContainer *b) */ if (va.val.array.rawScalar != vb.val.array.rawScalar) res = (va.val.array.rawScalar) ? -1 : 1; + + /* + * There should be an "else" here, to prevent us from + * overriding the above, but we can't change the sort + * order now, so there is a mild anomaly that an empty + * top level array sorts less than null. + */ if (va.val.array.nElems != vb.val.array.nElems) res = (va.val.array.nElems > vb.val.array.nElems) ? 1 : -1; break;