10000 Introduce an private list in the Plan structure. · postgrespro/aqo@b87a514 · GitHub
[go: up one dir, main page]

Skip to content

Commit b87a514

Browse files
danolivoAndrey Lepikhov
authored andcommitted
Introduce an private list in the Plan structure.
It allows extensions to store an planning info for using during (or after) execution. Introduce the AQOPlanNode structure. Move AQO-related fields of the Plan structure in this structure. Add this structure as an element to the Plan->private field. We allow copying of AQOPlanNode and disallow _read... and _out... functions because it have sense and it needs to teach the Core to serialize/deserialize RestrictInfo and all descendants of this struct. Also, for simplifying the Core patch: 1. replace parallel_workers field with parallel_divisor 2. move IsParallelTuplesProcessing() from the Core into the AQO code. This commit changes the Core patch.
1 parent 97f202e commit b87a514

File tree

7 files changed

+348
-191
lines changed

7 files changed

+348
-191
lines changed

aqo.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ _PG_init(void)
222222
"AQOMemoryContext",
223223
ALLOCSET_DEFAULT_SIZES);
224224
RegisterResourceReleaseCallback(aqo_free_callback, NULL);
225+
RegisterAQ 10000 OPlanNodeMethods();
225226
}
226227

227228
PG_FUNCTION_INFO_V1(invalidate_deactivated_queries_cache);

aqo_master.patch

Lines changed: 59 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -57,24 +57,47 @@ index e81b990092..157f6e2721 100644
5757
else
5858
{
5959
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
60-
index bd87f23784..d0a87fc57e 100644
60+
index bd87f23784..f4d567b8ac 100644
6161
--- a/src/backend/nodes/copyfuncs.c
6262
+++ b/src/backend/nodes/copyfuncs.c
63-
@@ -127,6 +127,12 @@ CopyPlanFields(const Plan *from, Plan *newnode)
64-
COPY_NODE_FIELD(lefttree);
65-
COPY_NODE_FIELD(righttree);
63+
@@ -129,6 +129,7 @@ CopyPlanFields(const Plan *from, Plan *newnode)
6664
COPY_NODE_FIELD(initPlan);
67-
+ COPY_SCALAR_FIELD(had_path);
68-
+ COPY_NODE_FIELD(path_clauses);
69-
+ COPY_NODE_FIELD(path_relids);
70-
+ COPY_SCALAR_FIELD(path_jointype);
71-
+ COPY_SCALAR_FIELD(path_parallel_workers);
72-
+ COPY_SCALAR_FIELD(was_parametrized);
7365
COPY_BITMAPSET_FIELD(extParam);
7466
COPY_BITMAPSET_FIELD(allParam);
67+
+ COPY_NODE_FIELD(private);
7568
}
69+
70+
/*
71+
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
72+
index e32b92e299..53b6188ff3 100644
73+
--- a/src/backend/nodes/outfuncs.c
74+
+++ b/src/backend/nodes/outfuncs.c
75+
@@ -342,6 +342,7 @@ _outPlanInfo(StringInfo str, const Plan *node)
76+
WRITE_NODE_FIELD(initPlan);
77+
WRITE_BITMAPSET_FIELD(extParam);
78+
WRITE_BITMAPSET_FIELD(allParam);
79+
+ /*WRITE_NODE_FIELD(private); */
80+
}
81+
82+
/*
83+
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
84+
index f0b34ecfac..cf6dfd37f9 100644
85+
--- a/src/backend/nodes/readfuncs.c
86+
+++ b/src/backend/nodes/readfuncs.c
87+
@@ -1628,6 +1628,11 @@ ReadCommonPlan(Plan *local_node)
88+
READ_NODE_FIELD(initPlan);
89+
READ_BITMAPSET_FIELD(extParam);
90+
READ_BITMAPSET_FIELD(allParam);
91+
+ local_node->private = NIL;
92+
+ /* READ_NODE_FIELD(private);
93+
+ * Don't serialize this field. It is required to serialize RestrictInfo and
94+
+ * EqualenceClass.
95+
+ */
96+
}
97+
98+
/*
7699
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
77-
index 8577c7b138..02e59233e2 100644
100+
index 8577c7b138..bf7c625537 100644
78101
--- a/src/backend/optimizer/path/costsize.c
79102
+++ b/src/backend/optimizer/path/costsize.c
80103
@@ -98,6 +98,11 @@
@@ -97,87 +120,6 @@ index 8577c7b138..02e59233e2 100644
97120

98121

99122
/*
100-
@@ -269,7 +273,7 @@ cost_seqscan(Path *path, PlannerInfo *root,
101-
/* Adjust costing for parallelism, if used. */
102-
if (path->parallel_workers > 0)
103-
{
104-
- double parallel_divisor = get_parallel_divisor(path);
105-
+ double parallel_divisor = get_parallel_divisor(path->parallel_workers);
106-
107-
/* The CPU cost is divided among all the workers. */
108-
cpu_run_cost /= parallel_divisor;
109-
@@ -748,7 +752,7 @@ cost_index(IndexPath *path, PlannerInfo *root, double loop_count,
110-
/* Adjust costing for parallelism, if used. */
111-
if (path->path.parallel_workers > 0)
112-
{
113-
- double parallel_divisor = get_parallel_divisor(&path->path);
114-
+ double parallel_divisor = get_parallel_divisor(path->path.parallel_workers);
115-
116-
path->path.rows = clamp_row_est(path->path.rows / parallel_divisor);
117-
118-
@@ -1029,7 +1033,7 @@ cost_bitmap_heap_scan(Path *path, PlannerInfo *root, RelOptInfo *baserel,
119-
/* Adjust costing for parallelism, if used. */
120-
if (path->parallel_workers > 0)
121-
{
122-
- double parallel_divisor = get_parallel_divisor(path);
123-
+ double parallel_divisor = get_parallel_divisor(path->parallel_workers);
124-
125-
/* The CPU cost is divided among all the workers. */
126-
cpu_run_cost /= parallel_divisor;
127-
@@ -2228,7 +2232,7 @@ cost_append(AppendPath *apath)
128-
else /* parallel-aware */
129-
{
130-
int i = 0;
131-
- double parallel_divisor = get_parallel_divisor(&apath->path);
132-
+ double parallel_divisor = get_parallel_divisor(apath->path.parallel_workers);
133-
134-
/* Parallel-aware Append never produces ordered output. */
135-
Assert(apath->path.pathkeys == NIL);
136-
@@ -2262,7 +2266,7 @@ cost_append(AppendPath *apath)
137-
{
138-
double subpath_parallel_divisor;
139-
140-
- subpath_parallel_divisor = get_parallel_divisor(subpath);
141-
+ subpath_parallel_divisor = get_parallel_divisor(subpath->parallel_workers);
142-
apath->path.rows += subpath->rows * (subpath_parallel_divisor /
143-
parallel_divisor);
144-
apath->path.total_cost += subpath->total_cost;
145-
@@ -3002,7 +3006,7 @@ final_cost_nestloop(PlannerInfo *root, NestPath *path,
146-
/* For partial paths, scale row estimate. */
147-
if (path->path.parallel_workers > 0)
148-
{
149-
- double parallel_divisor = get_parallel_divisor(&path->path);
150-
+ double parallel_divisor = get_parallel_divisor(path->path.parallel_workers);
151-
152-
path->path.rows =
153-
clamp_row_est(path->path.rows / parallel_divisor);
154-
@@ -3448,7 +3452,7 @@ final_cost_mergejoin(PlannerInfo *root, MergePath *path,
155-
/* For partial paths, scale row estimate. */
156-
if (path->jpath.path.parallel_workers > 0)
157-
{
158-
- double parallel_divisor = get_parallel_divisor(&path->jpath.path);
159-
+ double parallel_divisor = get_parallel_divisor(path->jpath.path.parallel_workers);
160-
161-
path->jpath.path.rows =
162-
clamp_row_est(path->jpath.path.rows / parallel_divisor);
163-
@@ -3782,7 +3786,7 @@ initial_cost_hashjoin(PlannerInfo *root, JoinCostWorkspace *workspace,
164-
* number, so we need to undo the division.
165-
*/
166-
if (parallel_hash)
167-
- inner_path_rows_total *= get_parallel_divisor(inner_path);
168-
+ inner_path_rows_total *= get_parallel_divisor(inner_path->parallel_workers);
169-
170-
/*
171-
* Get hash table size that executor would use for inner relation.
172-
@@ -3879,7 +3883,7 @@ final_cost_hashjoin(PlannerInfo *root, HashPath *path,
173-
/* For partial paths, scale row estimate. */
174-
if (path->jpath.path.parallel_workers > 0)
175-
{
176-
- double parallel_divisor = get_parallel_divisor(&path->jpath.path);
177-
+ double parallel_divisor = get_parallel_divisor(path->jpath.path.parallel_workers);
178-
179-
path->jpath.path.rows =
180-
clamp_row_est(path->jpath.path.rows / parallel_divisor);
181123
@@ -4908,6 +4912,58 @@ approx_tuple_count(PlannerInfo *root, JoinPath *path, List *quals)
182124
}
183125

@@ -410,46 +352,17 @@ index 8577c7b138..02e59233e2 100644
410352

411353
cost_qual_eval(&rel->baserestrictcost, rel->baserestrictinfo, root);
412354

413-
@@ -6035,14 +6161,25 @@ page_size(double tuples, int width)
414-
return ceil(relation_byte_size(tuples, width) / BLCKSZ);
415-
}
416-
417-
+bool
418-
+IsParallelTuplesProcessing(const Plan *plan)
419-
+{
420-
+ if (plan->path_parallel_workers > 0 && (
421-
+ plan->parallel_aware || nodeTag(plan) == T_HashJoin ||
422-
+ nodeTag(plan) == T_MergeJoin ||
423-
+ nodeTag(plan) == T_NestLoop))
424-
+ return true;
425-
+ return false;
426-
+}
427-
+
428-
/*
355+
@@ -6039,7 +6165,7 @@ page_size(double tuples, int width)
429356
* Estimate the fraction of the work that each worker will do given the
430357
* number of workers budgeted for the path.
431358
*/
432359
-static double
433-
-get_parallel_divisor(Path *path)
434360
+double
435-
+get_parallel_divisor(int parallel_workers)
361+
get_parallel_divisor(Path *path)
436362
{
437-
- double parallel_divisor = path->parallel_workers;
438-
+ double parallel_divisor = parallel_workers;
439-
440-
/*
441-
* Early experience with parallel query suggests that when there is only
442-
@@ -6059,7 +6196,7 @@ get_parallel_divisor(Path *path)
443-
{
444-
double leader_contribution;
445-
446-
- leader_contribution = 1.0 - (0.3 * path->parallel_workers);
447-
+ leader_contribution = 1.0 - (0.3 * parallel_workers);
448-
if (leader_contribution > 0)
449-
parallel_divisor += leader_contribution;
450-
}
363+
double parallel_divisor = path->parallel_workers;
451364
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
452-
index 439e6b6426..deadcfabb6 100644
365+
index 439e6b6426..8dd516d8c8 100644
453366
--- a/src/backend/optimizer/plan/createplan.c
454367
+++ b/src/backend/optimizer/plan/createplan.c
455368
@@ -71,6 +71,7 @@
@@ -471,6 +384,14 @@ index 439e6b6426..deadcfabb6 100644
471384
return plan;
472385
}
473386

387+
@@ -5276,6 +5281,7 @@ copy_generic_path_info(Plan *dest, Path *src)
388+
dest->plan_width = src->pathtarget->width;
389+
dest->parallel_aware = src->parallel_aware;
390+
dest->parallel_safe = src->parallel_safe;
391+
+ dest->private = NIL;
392+
}
393+
394+
/*
474395
diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
475396
index e105a4d5f1..392bed5222 100644
476397
--- a/src/backend/optimizer/util/relnode.c
@@ -556,31 +477,21 @@ index b7b2817a5d..a53b625e9e 100644
556477

557478

558479
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
559-
index aaa3b65d04..bc126f8982 100644
480+
index aaa3b65d04..5a49998c51 100644
560481
--- a/src/include/nodes/plannodes.h
561482
+++ b/src/include/nodes/plannodes.h
562-
@@ -145,6 +145,19 @@ typedef struct Plan
563-
List *initPlan; /* Init Plan nodes (un-correlated expr
564-
* subselects) */
565-
566-
+ /*
567-
+ * information for adaptive query optimization
568-
+ */
569-
+ bool had_path;
570-
+ List *path_clauses;
571-
+ List *path_relids;
572-
+ JoinType path_jointype;
573-
+ int path_parallel_workers;
574-
+ bool was_parametrized;
575-
+ /* For Adaptive optimization DEBUG purposes */
576-
+ double predicted_cardinality;
577-
+ int fss_hash;
483+
@@ -158,6 +158,9 @@ typedef struct Plan
484+
*/
485+
Bitmapset *extParam;
486+
Bitmapset *allParam;
578487
+
579-
/*
580-
* Information for management of parameter-change-driven rescanning
581-
*
488+
+ /* Additional field for an extension purposes. */
489+
+ List *private;
490+
} Plan;
491+
492+
/* ----------------
582493
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
583-
index 0fe60d82e4..892b8bb7ba 100644
494+
index 0fe60d82e4..e3198d0cc9 100644
584495
--- a/src/include/optimizer/cost.h
585496
+++ b/src/include/optimizer/cost.h
586497
@@ -39,6 +39,37 @@ typedef enum
@@ -656,12 +567,11 @@ index 0fe60d82e4..892b8bb7ba 100644
656567
extern void set_subquery_size_estimates(PlannerInfo *root, RelOptInfo *rel);
657568
extern void set_function_size_estimates(PlannerInfo *root, RelOptInfo *rel);
658569
extern void set_values_size_estimates(PlannerInfo *root, RelOptInfo *rel);
659-
@@ -207,5 +255,7 @@ extern void set_foreign_size_estimates(PlannerInfo *root, RelOptInfo *rel);
570+
@@ -207,5 +255,6 @@ extern void set_foreign_size_estimates(PlannerInfo *root, RelOptInfo *rel);
660571
extern PathTarget *set_pathtarget_cost_width(PlannerInfo *root, PathTarget *target);
661572
extern double compute_bitmap_pages(PlannerInfo *root, RelOptInfo *baserel,
662573
Path *bitmapqual, int loop_count, Cost *cost, double *tuple);
663-
+extern bool IsParallelTuplesProcessing(const Plan *plan);
664-
+extern double get_parallel_divisor(int parallel_workers);
574+
+extern double get_parallel_divisor(Path *path);
665575

666576
#endif /* COST_H */
667577
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h

cardinality_estimation.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* General method for prediction the cardinality of given relation.
2323
*/
2424
double
25-
predict_for_relation(List *restrict_clauses, List *selectivities,
25+
predict_for_relation(List *clauses, List *selectivities,
2626
List *relids, int *fss_hash)
2727
{
2828
int nfeatures;
@@ -33,7 +33,7 @@ predict_for_relation(List *restrict_clauses, List *selectivities,
3333
int rows;
3434
int i;
3535

36-
*fss_hash = get_fss_for_object(relids, restrict_clauses,
36+
*fss_hash = get_fss_for_object(relids, clauses,
3737
selectivities, &nfeatures, &features);
3838

3939
if (nfeatures > 0)

ignorance.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "aqo.h"
22
#include "ignorance.h"
3+
#include "path_utils.h"
34

45
#include "access/heapam.h"
56
#include "access/parallel.h"
@@ -92,6 +93,7 @@ update_ignorance(int qhash, int fhash, int fss_hash, Plan *plan)
9293
LOCKTAG tag;
9394
Oid nspid = get_aqo_schema();
9495
char *nspname;
96+
AQOPlanNode *aqo_node = get_aqo_plan_node(plan, false);
9597

9698
if (!OidIsValid(nspid))
9799
elog(PANIC, "AQO schema does not exists!");
@@ -128,7 +130,7 @@ update_ignorance(int qhash, int fhash, int fss_hash, Plan *plan)
128130

129131
if (!index_getnext_slot(scan, ForwardScanDirection, slot))
130132
{
131-
if (plan->predicted_cardinality < 0.)
133+
if (aqo_node->prediction < 0.)
132134
{
133135
char nodestr[1024];
134136
char *qplan = nodeToString(plan);

0 commit comments

Comments
 (0)
0