From: Peter Geoghegan Date: Sun, 16 Mar 2014 07:55:24 +0000 (-0700) Subject: Notes on pair deduplication X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=0fdda610eec93bb115fc298884a5597bd7da5141;p=users%2Fandresfreund%2Fpostgres.git Notes on pair deduplication --- diff --git a/src/backend/utils/adt/jsonb_util.c b/src/backend/utils/adt/jsonb_util.c index 584f1b0271..ea6bea0b87 100644 --- a/src/backend/utils/adt/jsonb_util.c +++ b/src/backend/utils/adt/jsonb_util.c @@ -983,8 +983,9 @@ deepContains(JsonbIterator ** val, JsonbIterator ** mContained) } /* - * Convert a Postgres text array to a JsonbSortedArray, with de-duplicated key - * elements. + * Convert a Postgres text array to a Jsonb array, sorted and with + * de-duplicated key elements. This is used for searching for items in the + * array. */ JsonbValue * arrayToJsonbSortedArray(ArrayType *a) @@ -995,6 +996,8 @@ arrayToJsonbSortedArray(ArrayType *a) JsonbValue *result; int i, j; + Size maxn = Min(MaxAllocSize / sizeof(JsonbPair), + JENTRY_POSMASK / sizeof(JsonbPair)); /* Extract data for sorting */ deconstruct_array(a, TEXTOID, -1, false, 'i', &key_datums, &key_nulls, @@ -1010,11 +1013,11 @@ arrayToJsonbSortedArray(ArrayType *a) * assumption. Therefore, use an explicit check rather than relying on * palloc() to complain. */ - if (key_count > MaxAllocSize / sizeof(JsonbPair)) + if (key_count > maxn) ereport(ERROR, (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), errmsg("number of pairs (%d) exceeds the maximum allowed (%zu)", - key_count, MaxAllocSize / sizeof(JsonbPair)))); + key_count, maxn))); result = palloc(sizeof(JsonbValue)); result->type = jbvArray; @@ -1664,7 +1667,7 @@ lengthCompareJsonbStringValue(const void *a, const void *b, void *binequal) * same "arg setting" hack will be applied here in respect of the pair's key * values. * - * N.B: String comparions here are "length-wise" + * N.B: String comparisons here are "length-wise" * * Pairs with equals keys are ordered such that the order field is respected. */ diff --git a/src/include/utils/jsonb.h b/src/include/utils/jsonb.h index 0c360db65f..04a74a2e51 100644 --- a/src/include/utils/jsonb.h +++ b/src/include/utils/jsonb.h @@ -195,7 +195,14 @@ struct JsonbValue }; }; -/* Pair within an Object */ +/* + * Pair within an Object. + * + * Pairs with duplicate keys are de-duplicated. We store the order for the + * benefit of doing so in a well-defined way with respect to the original + * observed order (which is "last observed wins"). This is only stored when + * originally constructing a Jsonb. + */ struct JsonbPair { JsonbValue key; /* Must be a jbvString */