Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd08c44f

Browse files
committed
Fix mvdistinct and dependencies size calculations
The formulas used to calculate size while (de)serializing mvndistinctand functional dependencies were based on offset() of the structs. Butthat is incorrect, because the structures are not copied directly, wewe copy the individual fields directly.At the moment this works fine, because there is no alignment paddingon any platform we support. But it might break if we ever added somefields into any of the structs, for example. It's also confusing.Fixed by reworking the macros to directly sum sizes of serializedfields. The macros are now useful only for serialiation, so there isno point in keeping them in the public header file. So make themprivate by moving them to the .c files.Also adds a couple more asserts to check the serialization, and fixesan incorrect allocation of MVDependency instead of (MVDependency *).Reported-By: Tom LaneDiscussion:https://postgr.es/m/29785.1555365602@sss.pgh.pa.us
1 parentbfbc150 commitd08c44f

File tree

3 files changed

+56
-40
lines changed

3 files changed

+56
-40
lines changed

‎src/backend/statistics/dependencies.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,20 @@
3232
#include"utils/syscache.h"
3333
#include"utils/typcache.h"
3434

35+
/* size of the struct header fields (magic, type, ndeps) */
36+
#defineSizeOfHeader(3 * sizeof(uint32))
37+
38+
/* size of a serialized dependency (degree, natts, atts) */
39+
#defineSizeOfItem(natts) \
40+
(sizeof(double) + sizeof(AttrNumber) * (1 + (natts)))
41+
42+
/* minimal size of a dependency (with two attributes) */
43+
#defineMinSizeOfItemSizeOfItem(2)
44+
45+
/* minimal size of dependencies, when all deps are minimal */
46+
#defineMinSizeOfItems(ndeps) \
47+
(SizeOfHeader + (ndeps) * MinSizeOfItem)
48+
3549
/*
3650
* Internal state for DependencyGenerator of dependencies. Dependencies are similar to
3751
* k-permutations of n elements, except that the order does not matter for the
@@ -408,7 +422,7 @@ statext_dependencies_build(int numrows, HeapTuple *rows, Bitmapset *attrs,
408422
dependencies->ndeps++;
409423
dependencies= (MVDependencies*)repalloc(dependencies,
410424
offsetof(MVDependencies,deps)
411-
+dependencies->ndeps*sizeof(MVDependency));
425+
+dependencies->ndeps*sizeof(MVDependency*));
412426

413427
dependencies->deps[dependencies->ndeps-1]=d;
414428
}
@@ -436,12 +450,11 @@ statext_dependencies_serialize(MVDependencies *dependencies)
436450
Sizelen;
437451

438452
/* we need to store ndeps, with a number of attributes for each one */
439-
len=VARHDRSZ+SizeOfDependencies
440-
+dependencies->ndeps*SizeOfDependency;
453+
len=VARHDRSZ+SizeOfHeader;
441454

442455
/* and also include space for the actual attribute numbers and degrees */
443456
for (i=0;i<dependencies->ndeps;i++)
444-
len+=(sizeof(AttrNumber)*dependencies->deps[i]->nattributes);
457+
len+=SizeOfItem(dependencies->deps[i]->nattributes);
445458

446459
output= (bytea*)palloc0(len);
447460
SET_VARSIZE(output,len);
@@ -461,15 +474,22 @@ statext_dependencies_serialize(MVDependencies *dependencies)
461474
{
462475
MVDependency*d=dependencies->deps[i];
463476

464-
memcpy(tmp,d,SizeOfDependency);
465-
tmp+=SizeOfDependency;
477+
memcpy(tmp,&d->degree,sizeof(double));
478+
tmp+=sizeof(double);
479+
480+
memcpy(tmp,&d->nattributes,sizeof(AttrNumber));
481+
tmp+=sizeof(AttrNumber);
466482

467483
memcpy(tmp,d->attributes,sizeof(AttrNumber)*d->nattributes);
468484
tmp+=sizeof(AttrNumber)*d->nattributes;
469485

486+
/* protect against overflow */
470487
Assert(tmp <= ((char*)output+len));
471488
}
472489

490+
/* make sure we've produced exactly the right amount of data */
491+
Assert(tmp== ((char*)output+len));
492+
473493
returnoutput;
474494
}
475495

@@ -487,9 +507,9 @@ statext_dependencies_deserialize(bytea *data)
487507
if (data==NULL)
488508
returnNULL;
489509

490-
if (VARSIZE_ANY_EXHDR(data)<SizeOfDependencies)
510+
if (VARSIZE_ANY_EXHDR(data)<SizeOfHeader)
491511
elog(ERROR,"invalid MVDependencies size %zd (expected at least %zd)",
492-
VARSIZE_ANY_EXHDR(data),SizeOfDependencies);
512+
VARSIZE_ANY_EXHDR(data),SizeOfHeader);
493513

494514
/* read the MVDependencies header */
495515
dependencies= (MVDependencies*)palloc0(sizeof(MVDependencies));
@@ -519,9 +539,7 @@ statext_dependencies_deserialize(bytea *data)
519539
errmsg("invalid zero-length item array in MVDependencies")));
520540

521541
/* what minimum bytea size do we expect for those parameters */
522-
min_expected_size=SizeOfDependencies+
523-
dependencies->ndeps* (SizeOfDependency+
524-
sizeof(AttrNumber)*2);
542+
min_expected_size=SizeOfItem(dependencies->ndeps);
525543

526544
if (VARSIZE_ANY_EXHDR(data)<min_expected_size)
527545
elog(ERROR,"invalid dependencies size %zd (expected at least %zd)",

‎src/backend/statistics/mvdistinct.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,20 @@ static double estimate_ndistinct(double totalrows, int numrows, int d, int f1);
4343
staticintn_choose_k(intn,intk);
4444
staticintnum_combinations(intn);
4545

46+
/* size of the struct header fields (magic, type, nitems) */
47+
#defineSizeOfHeader(3 * sizeof(uint32))
48+
49+
/* size of a serialized ndistinct item (coefficient, natts, atts) */
50+
#defineSizeOfItem(natts) \
51+
(sizeof(double) + sizeof(int) + (natts) * sizeof(AttrNumber))
52+
53+
/* minimal size of a ndistinct item (with two attributes) */
54+
#defineMinSizeOfItemSizeOfItem(2)
55+
56+
/* minimal size of mvndistinct, when all items are minimal */
57+
#defineMinSizeOfItems(nitems)\
58+
(SizeOfHeader + (nitems) * MinSizeOfItem)
59+
4660
/* Combination generator API */
4761

4862
/* internal state for generator of k-combinations of n elements */
@@ -168,8 +182,7 @@ statext_ndistinct_serialize(MVNDistinct *ndistinct)
168182
* Base size is size of scalar fields in the struct, plus one base struct
169183
* for each item, including number of items for each.
170184
*/
171-
len=VARHDRSZ+SizeOfMVNDistinct+
172-
ndistinct->nitems* (offsetof(MVNDistinctItem,attrs)+sizeof(int));
185+
len=VARHDRSZ+SizeOfHeader;
173186

174187
/* and also include space for the actual attribute numbers */
175188
for (i=0;i<ndistinct->nitems;i++)
@@ -178,7 +191,8 @@ statext_ndistinct_serialize(MVNDistinct *ndistinct)
178191

179192
nmembers=bms_num_members(ndistinct->items[i].attrs);
180193
Assert(nmembers >=2);
181-
len+=sizeof(AttrNumber)*nmembers;
194+
195+
len+=SizeOfItem(nmembers);
182196
}
183197

184198
output= (bytea*)palloc(len);
@@ -195,8 +209,7 @@ statext_ndistinct_serialize(MVNDistinct *ndistinct)
195209
tmp+=sizeof(uint32);
196210

197211
/*
198-
* store number of attributes and attribute numbers for each ndistinct
199-
* entry
212+
* store number of attributes and attribute numbers for each entry
200213
*/
201214
for (i=0;i<ndistinct->nitems;i++)
202215
{
@@ -218,9 +231,13 @@ statext_ndistinct_serialize(MVNDistinct *ndistinct)
218231
tmp+=sizeof(AttrNumber);
219232
}
220233

234+
/* protect against overflows */
221235
Assert(tmp <= ((char*)output+len));
222236
}
223237

238+
/* check we used exactly the expected space */
239+
Assert(tmp== ((char*)output+len));
240+
224241
returnoutput;
225242
}
226243

@@ -241,9 +258,9 @@ statext_ndistinct_deserialize(bytea *data)
241258
returnNULL;
242259

243260
/* we expect at least the basic fields of MVNDistinct struct */
244-
if (VARSIZE_ANY_EXHDR(data)<SizeOfMVNDistinct)
261+
if (VARSIZE_ANY_EXHDR(data)<SizeOfHeader)
245262
elog(ERROR,"invalid MVNDistinct size %zd (expected at least %zd)",
246-
VARSIZE_ANY_EXHDR(data),SizeOfMVNDistinct);
263+
VARSIZE_ANY_EXHDR(data),SizeOfHeader);
247264

248265
/* initialize pointer to the data part (skip the varlena header) */
249266
tmp=VARDATA_ANY(data);
@@ -272,9 +289,7 @@ statext_ndistinct_deserialize(bytea *data)
272289
errmsg("invalid zero-length item array in MVNDistinct")));
273290

274291
/* what minimum bytea size do we expect for those parameters */
275-
minimum_size= (SizeOfMVNDistinct+
276-
ndist.nitems* (SizeOfMVNDistinctItem+
277-
sizeof(AttrNumber)*2));
292+
minimum_size=MinSizeOfItems(ndist.nitems);
278293
if (VARSIZE_ANY_EXHDR(data)<minimum_size)
279294
ereport(ERROR,
280295
(errcode(ERRCODE_DATA_CORRUPTED),
@@ -285,7 +300,7 @@ statext_ndistinct_deserialize(bytea *data)
285300
* Allocate space for the ndistinct items (no space for each item's
286301
* attnos: those live in bitmapsets allocated separately)
287302
*/
288-
ndistinct=palloc0(MAXALIGN(SizeOfMVNDistinct)+
303+
ndistinct=palloc0(MAXALIGN(offsetof(MVNDistinct,items))+
289304
(ndist.nitems*sizeof(MVNDistinctItem)));
290305
ndistinct->magic=ndist.magic;
291306
ndistinct->type=ndist.type;

‎src/include/statistics/statistics.h

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ typedef struct MVNDistinctItem
2929
Bitmapset*attrs;/* attr numbers of items */
3030
}MVNDistinctItem;
3131

32-
/* size of the struct, excluding attribute list */
33-
#defineSizeOfMVNDistinctItem \
34-
(offsetof(MVNDistinctItem, ndistinct) + sizeof(double))
35-
3632
/* A MVNDistinct object, comprising all possible combinations of columns */
3733
typedefstructMVNDistinct
3834
{
@@ -42,13 +38,7 @@ typedef struct MVNDistinct
4238
MVNDistinctItemitems[FLEXIBLE_ARRAY_MEMBER];
4339
}MVNDistinct;
4440

45-
/* size of the struct excluding the items array */
46-
#defineSizeOfMVNDistinct(offsetof(MVNDistinct, nitems) + sizeof(uint32))
47-
48-
49-
/* size of the struct excluding the items array */
50-
#defineSizeOfMVNDistinct(offsetof(MVNDistinct, nitems) + sizeof(uint32))
51-
41+
/* Multivariate functional dependencies */
5242
#defineSTATS_DEPS_MAGIC0xB4549A2C/* marks serialized bytea */
5343
#defineSTATS_DEPS_TYPE_BASIC1/* basic dependencies type */
5444

@@ -63,10 +53,6 @@ typedef struct MVDependency
6353
AttrNumberattributes[FLEXIBLE_ARRAY_MEMBER];/* attribute numbers */
6454
}MVDependency;
6555

66-
/* size of the struct excluding the deps array */
67-
#defineSizeOfDependency \
68-
(offsetof(MVDependency, nattributes) + sizeof(AttrNumber))
69-
7056
typedefstructMVDependencies
7157
{
7258
uint32magic;/* magic constant marker */
@@ -75,9 +61,6 @@ typedef struct MVDependencies
7561
MVDependency*deps[FLEXIBLE_ARRAY_MEMBER];/* dependencies */
7662
}MVDependencies;
7763

78-
/* size of the struct excluding the deps array */
79-
#defineSizeOfDependencies(offsetof(MVDependencies, ndeps) + sizeof(uint32))
80-
8164
/* used to flag stats serialized to bytea */
8265
#defineSTATS_MCV_MAGIC0xE1A651C2/* marks serialized bytea */
8366
#defineSTATS_MCV_TYPE_BASIC1/* basic MCV list type */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp