8000 Merge remote-tracking branch 'origin/piggyback_master' into increment… · mpws2013n1/postgres@a4d3726 · GitHub
[go: up one dir, main page]

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

Appearance settings

Commit a4d3726

Browse files
committed
Merge remote-tracking branch 'origin/piggyback_master' into incrementalFD
Conflicts: src/backend/executor/execProcnode.c
2 parents 44526a0 + 90d1dbf commit a4d3726

File tree

5 files changed

+106
-19
lines changed

5 files changed

+106
-19
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# Output files
2+
util/q.sql
3+
util/r.html
4+
5+
# Own script file
6+
util/run_query.sh
7+
18
# Global excludes across all subdirectories
29
*.o
310
*.so

src/backend/executor/execMain.c

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,11 @@ InitPlan(QueryDesc *queryDesc, int eflags)
983983
*maxValue = INT_MIN;
984984
*maxValueTemp = INT_MIN;
985985

986+
piggyback->resultStatistics->columnStatistics[i].n_distinctIsFinal = 1;
987+
piggyback->resultStatistics->columnStatistics[i].minValueIsFinal = 1;
988+
piggyback->resultStatistics->columnStatistics[i].maxValueIsFinal = 1;
989+
piggyback->resultStatistics->columnStatistics[i].mostFrequentValueIsFinal = 1;
990+
986991
piggyback->resultStatistics->columnStatistics[i].n_distinct = -2;
987992
piggyback->resultStatistics->columnStatistics[i].minValue = minValue;
988993
piggyback->resultStatistics->columnStatistics[i].maxValue = maxValue;
@@ -994,7 +999,9 @@ InitPlan(QueryDesc *queryDesc, int eflags)
994999
}
9951000

9961001
// ExecInitNode needs existing piggyback->resultStatistics->columnStatistics for all result columns
1002+
piggyback->tableOids = NULL;
9971003
planstate = ExecInitNode(plan, estate, eflags);
1004+
list_free(piggyback->tableOids);
9981005

9991006
if (plan->targetlist != NULL) {
10001007
ListCell *tlist;
@@ -1006,34 +1013,43 @@ InitPlan(QueryDesc *queryDesc, int eflags)
10061013
// the name seems to be written inside of ExecInitNode
10071014
piggyback->resultStatistics->columnStatistics[i].columnDescriptor->rescolumnname = name;
10081015

1009-
int useDistinctStatsFromBaseStats = !nodeHasFilter(planstate);
1010-
//useDistinctStatsFromBaseStats = 0;
1011-
if (piggyback->resultStatistics->columnStatistics[i].n_distinctIsFinal == 0 && useDistinctStatsFromBaseStats == 1) {
1012-
unsigned int relOid = tle->resorigtbl;
1016+
unsigned int relOid = tle->resorigtbl;
1017+
HeapTuple statsTuple = NULL;
1018+
HeapTuple relTuple = NULL;
1019+
if (relOid != 0) { // This can happen for aggregate columns
10131020
int attnum = get_attnum(relOid, name);
1014-
HeapTuple statsTuple = SearchSysCache3(STATRELATTINH,
1021+
statsTuple = SearchSysCache3(STATRELATTINH,
10151022
ObjectIdGetDatum(relOid), Int16GetDatum(attnum),
10161023
BoolGetDatum(false));
1017-
HeapTuple relTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
1024+
relTuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
1025+
}
10181026

1019-
if (HeapTupleIsValid(statsTuple) && HeapTupleIsValid(relTuple)) {
1020-
Form_pg_statistic statStruct = (Form_pg_statistic) GETSTRUCT(statsTuple);
1021-
float4 n_distinct = statStruct->stadistinct;
1022-
Form_pg_class pg_class = (Form_pg_class) GETSTRUCT(relTuple);
1023-
float4 numTuple = ((Form_pg_class) GETSTRUCT(relTuple))->reltuples;
1027+
if (HeapTupleIsValid(statsTuple) && HeapTupleIsValid(relTuple)) {
1028+
Form_pg_statistic statStruct = (Form_pg_statistic) GETSTRUCT(statsTuple);
1029+
Form_pg_class pg_class = (Form_pg_class) GETSTRUCT(relTuple);
1030+
float4 numTuple = ((Form_pg_class) GETSTRUCT(relTuple))->reltuples;
10241031

1032+
// do not read distinct values from base statistics if there are already valid values for n_distinct
1033+
if (-2 == piggyback->resultStatistics->columnStatistics[i].n_distinct) {
1034+
float4 n_distinct = statStruct->stadistinct;
10251035
if (-1 == n_distinct) {
10261036
piggyback->resultStatistics->columnStatistics[i].n_distinct = numTuple;
10271037
} else if (n_distinct < 0 && n_distinct > -1) {
10281038
piggyback->resultStatistics->columnStatistics[i].n_distinct = numTuple * n_distinct * -1;
10291039
} else {
10301040
piggyback->resultStatistics->columnStatistics[i].n_distinct = n_distinct;
10311041
}
1032-
1033-
ReleaseSysCache(statsTuple);
1034-
ReleaseSysCache(relTuple);
10351042
}
1043+
1044+
ReleaseSysCache(statsTuple);
1045+
ReleaseSysCache(relTuple);
1046+
} else {
1047+
piggyback->resultStatistics->columnStatistics[i].n_distinctIsFinal = 0;
10361048
}
1049+
1050+
piggyback->resultStatistics->columnStatistics[i].minValueIsFinal = 0;
1051+
piggyback->resultStatistics->columnStatistics[i].maxValueIsFinal = 0;
1052+
piggyback->resultStatistics->columnStatistics[i].mostFrequentValueIsFinal = 0;
10371053
i++;
10381054
}
10391055

src/backend/executor/execProcnode.c

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ extern Piggyback *piggyback;
130130
void fillFDCandidateMaps();
131131
void addToTwoColumnCombinationHashSet(int from, char* valueToConcat, int to, char* value);
132132
void LookForFilterWithEquality(PlanState* result, Oid tableOid, List* qual);
133-
133+
void InvalidateStatisticsForTables(List* oldTableOids);
134+
void InvalidateStatisticsForTable(int tableOid);
134135
/* ------------------------------------------------------------------------
135136
* ExecInitNode
136137
*
@@ -155,6 +156,7 @@ ExecInitNode(Plan *node, EState *estate, int eflags) {
155156
SeqScanState* resultAsScanState;
156157
IndexScanState* resultAsIndexScan;
157158
IndexOnlyScanState* resultAsIndexOnlyScan;
159+
List* oids = NULL;
158160
int tableOid = -1;
159161
/*
160162
* do nothing when we get to the end of a leaf on tree.
@@ -214,7 +216,10 @@ ExecInitNode(Plan *node, EState *estate, int eflags) {
214216

215217
if (tableOid != -1 && piggyback != NULL)
216218
{
219+
int* tableOidPtr = (int*) malloc(sizeof(int));
220+
*tableOidPtr = tableOid;
217221
LookForFilterWithEquality(result, tableOid, result->qual);
222+
piggyback->tableOids = lappend(piggyback->tableOids, tableOidPtr);
218223
}
219224
break;
220225

@@ -230,7 +235,10 @@ ExecInitNode(Plan *node, EState *estate, int eflags) {
230235

231236
if (tableOid != -1)
232237
{
238+
int* tableOidPtr = (int*) malloc(sizeof(int));
239+
*tableOidPtr = tableOid;
233240
LookForFilterWithEquality(result, tableOid, resultAsIndexScan->indexqualorig);
241+
piggyback->tableOids = lappend(piggyback->tableOids, tableOidPtr);
234242
}
235243
break;
236244

@@ -247,71 +255,89 @@ ExecInitNode(Plan *node, EState *estate, int eflags) {
247255

248256
if (tableOid != -1)
249257
{
258+
int* tableOidPtr = (int*) malloc(sizeof(int));
259+
*tableOidPtr = tableOid;
250260
LookForFilterWithEquality(result, tableOid, resultAsIndexOnlyScan->indexqual);
261+
piggyback->tableOids = lappend(piggyback->tableOids, tableOidPtr);
251262
}
252263
break;
253264

254265
case T_BitmapIndexScan:
255266
result = (PlanState *) ExecInitBitmapIndexScan((BitmapIndexScan *) node,
256267
estate, eflags);
268+
printf(" Bitmap ");
257269
break;
258270

259271
case T_BitmapHeapScan:
260272
result = (PlanState *) ExecInitBitmapHeapScan((BitmapHeapScan *) node,
261273
estate, eflags);
274+
printf(" BitmapHeap ");
262275
break;
263276

264277
case T_TidScan:
265278
result = (PlanState *) ExecInitTidScan((TidScan *) node, estate,
266279
eflags);
280+
printf(" Tid ");
267281
break;
268282

269283
case T_SubqueryScan:
270284
result = (PlanState *) ExecInitSubqueryScan((SubqueryScan *) node,
271285
estate, eflags);
286+
printf(" Subquery ");
272287
break;
273288

274289
case T_FunctionScan:
275290
result = (PlanState *) ExecInitFunctionScan((FunctionScan *) node,
276291
estate, eflags);
292+
printf(" Function ");
277293
break;
278294

279295
case T_ValuesScan:
280296
result = (PlanState *) ExecInitValuesScan((ValuesScan *) node, estate,
281297
eflags);
298+
printf(" Values ");
282299
break;
283300

284301
case T_CteScan:
285302
result = (PlanState *) ExecInitCteScan((CteScan *) node, estate,
286303
eflags);
304+
printf(" Cte ");
287305
break;
288306

289307
case T_WorkTableScan:
290308
result = (PlanState *) ExecInitWorkTableScan((WorkTableScan *) node,
291309
estate, eflags);
310+
printf(" WorkTable ");
292311
break;
293312

294313
case T_ForeignScan:
295314
result = (PlanState *) ExecInitForeignScan((ForeignScan *) node, estate,
296315
eflags);
316+
printf(" Foreign ");
297317
break;
298318

299319
/*
300320
* join nodes
301321
*/
302322
case T_NestLoop:
323+
oids = piggyback->tableOids;
303324
result = (PlanState *) ExecInitNestLoop((NestLoop *) node, estate,
304325
eflags);
326+
InvalidateStatisticsForTables(oids);
305327
break;
306328

307329
case T_MergeJoin:
330+
oids = piggyback->tableOids;
308331
result = (PlanState *) ExecInitMergeJoin((MergeJoin *) node, estate,
309332
eflags);
333+
InvalidateStatisticsForTables(oids);
310334
break;
311335

312336
case T_HashJoin:
337+
oids = piggyback->tableOids;
313338
result = (PlanState *) ExecInitHashJoin((HashJoin *) node, estate,
314-
eflags);
339+
eflags);
340+
InvalidateStatisticsForTables(oids);
315341
break;
316342

317343
/*
@@ -327,11 +353,14 @@ ExecInitNode(Plan *node, EState *estate, int eflags) {
327353
break;
328354

329355
case T_Group:
356+
oids = piggyback->tableOids;
330357
result = (PlanState *) ExecInitGroup((Group *) node, estate, eflags);
358+
InvalidateStatisticsForTables(oids);
331359
break;
332360

361+
// we do not want to invalid the statistic values, because they do not change the values from the original tables
333362
case T_Agg:
334-
result = ExecInitAgg((Agg *) node, estate, eflags);
363+
result = (PlanState *) ExecInitAgg((Agg *) node, estate, eflags);
335364
break;
336365

337366
case T_WindowAgg:
@@ -389,6 +418,36 @@ ExecInitNode(Plan *node, EState *estate, int eflags) {
389418
return result;
390419
}
391420

421+
void
422+
InvalidateStatisticsForTables(List* oldTableOids)
423+
{
424+
List* relevantTableOids = NULL;
425+
ListCell* l;
426+
relevantTableOids = list_difference(piggyback->tableOids, oldTableOids);
427+
foreach (l, relevantTableOids)
428+
{
429+
int currentOid = *((int*)lfirst(l));
430+
InvalidateStatisticsForTable(currentOid);
431+
}
432+
}
433+
434+
void
435+
InvalidateStatisticsForTable(int tableOid)
436+
{
437+
int i = 0;
438+
for (; i < piggyback->numberOfAttributes; i++)
439+
{
440+
if (tableOid == piggyback->resultStatistics->columnStatistics[i].columnDescriptor->srctableid)
441+
{
442+
// this columnStatistic is obsolete
443+
piggyback->resultStatistics->columnStatistics[i].n_distinctIsFinal = 0;
444+
piggyback->resultStatistics->columnStatistics[i].minValueIsFinal = 0;
445+
piggyback->resultStatistics->columnStatistics[i].maxValueIsFinal = 0;
446+
piggyback->resultStatistics->columnStatistics[i].mostFrequentValueIsFinal = 0;
447+
}
448+
}
449+
}
450+
392451
void
393452
LookForFilterWithEquality(PlanState* result, Oid tableOid, List* qual)
394453
{
@@ -407,8 +466,6 @@ LookForFilterWithEquality(PlanState* result, Oid tableOid, List* qual)
407466
break;
408467
}
409468

410-
// TODO: if (i < piggyback->numberOfAttributes) set useBaseStatistics to false
411-
412469
if(opno == 94 || opno == 96 || opno == 410 || opno == 416 || opno == 1862 || opno == 1868 || opno == 15 || opno == 532 || opno == 533) { // it is a equality like number_of_tracks = 3
413470
int numberOfAttributes = result->plan->targetlist->length;
414471

@@ -439,6 +496,11 @@ LookForFilterWithEquality(PlanState* result, Oid tableOid, List* qual)
439496
printf("there are statistics results from the selection that are not part of the result table\n");
440497
}
441498
}
499+
else {
500+
printf("this opno is no equality: %d (for column id %d)\n", opno, columnId);
501+
// found a selection, therefore we cannot use old statistics
502+
InvalidateStatisticsForTable(tableOid);
503+
}
442504
}
443505
}
444506

src/include/piggyback/piggyback.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ typedef struct _piggyback {
101101
char **slotValues;
102102
int numberOfAttributes;
103103
int numberOfTuples;
104+
List* tableOids;
104105
} Piggyback;
105106

106107
extern void initPiggyback();

src/interfaces/libpq/fe-exec.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
162162
result->curBlock = NULL;
163163
result->curOffset = 0;
164164
result->spaceLeft = 0;
165+
result->statistics = NULL;
165166

166167
if (conn)
167168
{

0 commit comments

Comments
 (0)
0