10000 Further patch rangetypes_selfuncs.c's statistics slot management. · dinesh372/postgres@4509b4e · GitHub
[go: up one dir, main page]

Skip to content

Commit 4509b4e

Browse files
committed
Further patch rangetypes_selfuncs.c's statistics slot management.
Values in a STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM slot are float8, not of the type of the column the statistics are for. This bug is at least partly the fault of sloppy specification comments for get_attstatsslot()/free_attstatsslot(): the type OID they want is that of the stavalues entries, not of the underlying column. (I double-checked other callers and they seem to get this right.) Adjust the comments to be more correct. Per buildfarm. Security: CVE-2017-7484
1 parent 7603952 commit 4509b4e

File tree

3 files changed

+15
-12
lines changed

3 files changed

+15
-12
lines changed

src/backend/utils/adt/rangetypes_selfuncs.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "access/htup_details.h"
2121
#include "catalog/pg_operator.h"
2222
#include "catalog/pg_statistic.h"
23+
#include "catalog/pg_type.h"
2324
#include "utils/builtins.h"
2425
#include "utils/lsyscache.h"
2526
#include "utils/rangetypes.h"
@@ -246,16 +247,17 @@ calc_rangesel(TypeCacheEntry *typcache, VariableStatData *vardata,
246247

247248
/* Try to get fraction of empty ranges */
248249
if (get_attstatsslot(vardata->statsTuple,
249-
vardata->atttype, vardata->atttypmod,
250-
STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM, InvalidOid,
250+
FLOAT8OID, -1,
251+
STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
252+
InvalidOid,
251253
NULL,
252254
NULL, NULL,
253255
&numbers, &nnumbers))
254256
{
255257
if (nnumbers != 1)
256258
elog(ERROR, "invalid empty fraction statistic"); /* shouldn't happen */
257259
empty_frac = numbers[0];
258-
free_attstatsslot(vardata->atttype, NULL, 0, numbers, nnumbers);
260+
free_attstatsslot(FLOAT8OID, NULL, 0, numbers, nnumbers);
259261
}
260262
else
261263
{
@@ -424,7 +426,7 @@ calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata,
424426
{
425427
if (!(HeapTupleIsValid(vardata->statsTuple) &&
426428
get_attstatsslot(vardata->statsTuple,
427-
vardata->atttype, vardata->atttypmod,
429+
FLOAT8OID, -1,
428430
STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM,
429431
InvalidOid,
430432
NULL,
@@ -438,7 +440,7 @@ calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata,
438440
/* check that it's a histogram, not just a dummy entry */
439441
if (length_nhist < 2)
440442
{
441-
free_attstatsslot(vardata->atttype,
443+
free_attstatsslot(FLOAT8OID,
442444
length_hist_values, length_nhist, NULL, 0);
443445
free_attstatsslot(vardata->atttype, hist_values, nhist, NULL, 0);
444446
return -1.0;
@@ -578,7 +580,7 @@ calc_hist_selectivity(TypeCacheEntry *typcache, VariableStatData *vardata,
578580
break;
579581
}
580582

581-
free_attstatsslot(vardata->atttype,
583+
free_attstatsslot(FLOAT8OID,
582584
length_hist_values, length_nhist, NULL, 0);
583585
free_attstatsslot(vardata->atttype, hist_values, nhist, NULL, 0);
584586

src/backend/utils/cache/lsyscache.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2767,17 +2767,17 @@ get_attavgwidth(Oid relid, AttrNumber attnum)
27672767
* that have been provided by a stats hook and didn't really come from
27682768
* pg_statistic.
27692769
*
2770-
* statstuple: pg_statistics tuple to be examined.
2771-
* atttype: type OID of attribute (can be InvalidOid if values == NULL).
2772-
* atttypmod: typmod of attribute (can be 0 if values == NULL).
2770+
* statstuple: pg_statistic tuple to be examined.
2771+
* atttype: type OID of slot's stavalues (can be InvalidOid if values == NULL).
2772+
* atttypmod: typmod of slot's stavalues (can be 0 if values == NULL).
27732773
* reqkind: STAKIND code for desired statistics slot kind.
27742774
* reqop: STAOP value wanted, or InvalidOid if don't care.
27752775
* actualop: if not NULL, *actualop receives the actual STAOP value.
27762776
* values, nvalues: if not NULL, the slot's stavalues are extracted.
27772777
* numbers, nnumbers: if not NULL, the slot's stanumbers are extracted.
27782778
*
27792779
* If assigned, values and numbers are set to point to palloc'd arrays.
2780-
* If the attribute type is pass-by-reference, the values referenced by
2780+
* If the stavalues datatype is pass-by-reference, the values referenced by
27812781
* the values array are themselves palloc'd. The palloc'd stuff can be
27822782
* freed by calling free_attstatsslot.
27832783
*
@@ -2907,7 +2907,8 @@ get_attstatsslot(HeapTuple statstuple,
29072907
* free_attstatsslot
29082908
* Free data allocated by get_attstatsslot
29092909
*
2910-
* atttype need be valid only if values != NULL.
2910+
* atttype is the type of the individual values in values[].
2911+
* It need be valid only if values != NULL.
29112912
*/
29122913
void
29132914
free_attstatsslot(Oid atttype,

src/include/catalog/pg_statistic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ typedef FormData_pg_statistic *Form_pg_statistic;
275275
* fraction of empty ranges. stavalues is a histogram of non-empty lengths, in
276276
* a format similar to STATISTIC_KIND_HISTOGRAM: it contains M (>=2) range
277277
* values that divide the column data values into M-1 bins of approximately
278-
* equal population. The lengths are stores as float8s, as measured by the
278+
* equal population. The lengths are stored as float8s, as measured by the
279279
* range type's subdiff function. Only non-null rows are considered.
280280
*/
281281
#define STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM 6

0 commit comments

Comments
 (0)
0