mirror of https://github.com/postgres/postgres
Fix contrib/postgres_fdw to handle multiple join conditions properly.
The previous coding supposed that it could consider just a single join condition in any one parameterized path for the foreign table. But in reality, the parameterized-path machinery forces all join clauses that are "movable to" the foreign table to be evaluated at that node; including clauses that we might not consider safe to send across. Such cases would result in an Assert failure in an assert-enabled build, and otherwise in sending an unsafe clause to the foreign server, which might result in errors or silently-wrong answers. A lesser problem was that the cost/rowcount estimates generated for the parameterized path failed to account for any additional join quals that get assigned to the scan. To fix, rewrite postgresGetForeignPaths so that it correctly collects all the movable quals for any one outer relation when generating parameterized paths; we'll now generate just one path per outer relation not one per join qual. Also fix bogus assumptions in postgresGetForeignPlan and estimate_path_cost_size that only safe-to-send join quals will be presented. Based on complaint from Etsuro Fujita that the path costs were being miscalculated, though this is significantly different from his proposed patch.
This commit is contained in:
parent
4ea2e2d474
commit
83204e100c
|
@ -134,14 +134,15 @@ static void deparseArrayExpr(ArrayExpr *node, deparse_expr_cxt *context);
|
|||
|
||||
|
||||
/*
|
||||
* Examine each restriction clause in baserel's baserestrictinfo list,
|
||||
* and classify them into two groups, which are returned as two lists:
|
||||
* Examine each qual clause in input_conds, and classify them into two groups,
|
||||
* which are returned as two lists:
|
||||
* - remote_conds contains expressions that can be evaluated remotely
|
||||
* - local_conds contains expressions that can't be evaluated remotely
|
||||
*/
|
||||
void
|
||||
classifyConditions(PlannerInfo *root,
|
||||
RelOptInfo *baserel,
|
||||
List *input_conds,
|
||||
List **remote_conds,
|
||||
List **local_conds)
|
||||
{
|
||||
|
@ -150,7 +151,7 @@ classifyConditions(PlannerInfo *root,
|
|||
*remote_conds = NIL;
|
||||
*local_conds = NIL;
|
||||
|
||||
foreach(lc, baserel->baserestrictinfo)
|
||||
foreach(lc, input_conds)
|
||||
{
|
||||
RestrictInfo *ri = (RestrictInfo *) lfirst(lc);
|
||||
|
||||
|
|
|
@ -468,6 +468,130 @@ SELECT * FROM ft2 a, ft2 b WHERE a.c1 = 47 AND b.c1 = a.c2;
|
|||
47 | 7 | 00047 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo | 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo
|
||||
(1 row)
|
||||
|
||||
-- check both safe and unsafe join conditions
|
||||
EXPLAIN (VERBOSE, COSTS false)
|
||||
SELECT * FROM ft2 a, ft2 b
|
||||
WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7);
|
||||
QUERY PLAN
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
Nested Loop
|
||||
Output: a.c1, a.c2, a.c3, a.c4, a.c5, a.c6, a.c7, a.c8, b.c1, b.c2, b.c3, b.c4, b.c5, b.c6, b.c7, b.c8
|
||||
-> Foreign Scan on public.ft2 a
|
||||
Output: a.c1, a.c2, a.c3, a.c4, a.c5, a.c6, a.c7, a.c8
|
||||
Filter: (a.c8 = 'foo'::user_enum)
|
||||
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((c2 = 6))
|
||||
-> Foreign Scan on public.ft2 b
|
||||
Output: b.c1, b.c2, b.c3, b.c4, b.c5, b.c6, b.c7, b.c8
|
||||
Filter: (upper((a.c7)::text) = (b.c7)::text)
|
||||
Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (($1::integer = "C 1"))
|
||||
(10 rows)
|
||||
|
||||
SELECT * FROM ft2 a, ft2 b
|
||||
WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7);
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8
|
||||
-----+----+-------+------------------------------+--------------------------+----+------------+-----+-----+----+-------+------------------------------+--------------------------+----+------------+-----
|
||||
6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
||||
16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
||||
26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
||||
36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
||||
46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
||||
56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
||||
66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
||||
76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
||||
86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
||||
96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
||||
106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
||||
116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
||||
126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
||||
136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
||||
146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
||||
156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
||||
166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
||||
176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
||||
186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
||||
196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
||||
206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
||||
216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
||||
226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
||||
236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
||||
246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
||||
256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
||||
266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
||||
276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
||||
286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
||||
296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
||||
306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
||||
316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
||||
326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
||||
336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
||||
346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
||||
356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
||||
366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
||||
376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
||||
386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
||||
396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
||||
406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
||||
416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
||||
426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
||||
436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
||||
446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
||||
456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
||||
466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
||||
476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
||||
486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
||||
496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
||||
506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
||||
516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
||||
526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
||||
536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
||||
546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
||||
556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
||||
566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
||||
576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
||||
586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
||||
596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
||||
606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
||||
616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
||||
626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
||||
636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
||||
646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
||||
656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
||||
666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
||||
676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
||||
686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
||||
696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
||||
706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
||||
716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
||||
726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
||||
736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
||||
746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
||||
756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
||||
766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
||||
776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
||||
786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
||||
796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
||||
806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
||||
816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
||||
826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
||||
836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
||||
846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
||||
856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
||||
866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
||||
876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
||||
886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
||||
896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
||||
906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo
|
||||
916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo
|
||||
926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo
|
||||
936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo
|
||||
946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo
|
||||
956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo
|
||||
966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo
|
||||
976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo
|
||||
986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo
|
||||
996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo
|
||||
(100 rows)
|
||||
|
||||
-- ===================================================================
|
||||
-- parameterized queries
|
||||
-- ===================================================================
|
||||
|
|
|
@ -444,7 +444,7 @@ postgresGetForeignRelSize(PlannerInfo *root,
|
|||
* Identify which baserestrictinfo clauses can be sent to the remote
|
||||
* server and which can't.
|
||||
*/
|
||||
classifyConditions(root, baserel,
|
||||
classifyConditions(root, baserel, baserel->baserestrictinfo,
|
||||
&fpinfo->remote_conds, &fpinfo->local_conds);
|
||||
|
||||
/*
|
||||
|
@ -540,12 +540,7 @@ postgresGetForeignPaths(PlannerInfo *root,
|
|||
{
|
||||
PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) baserel->fdw_private;
|
||||
ForeignPath *path;
|
||||
List *join_quals;
|
||||
Relids required_outer;
|
||||
double rows;
|
||||
int width;
|
||||
Cost startup_cost;
|
||||
Cost total_cost;
|
||||
List *ppi_list;
|
||||
ListCell *lc;
|
||||
|
||||
/*
|
||||
|
@ -573,15 +568,25 @@ postgresGetForeignPaths(PlannerInfo *root,
|
|||
return;
|
||||
|
||||
/*
|
||||
* As a crude first hack, we consider each available join clause and try
|
||||
* to make a parameterized path using just that clause. Later we should
|
||||
* consider combinations of clauses, probably.
|
||||
* Thumb through all join clauses for the rel to identify which outer
|
||||
* relations could supply one or more safe-to-send-to-remote join clauses.
|
||||
* We'll build a parameterized path for each such outer relation.
|
||||
*
|
||||
* It's convenient to manage this by representing each candidate outer
|
||||
* relation by the ParamPathInfo node for it. We can then use the
|
||||
* ppi_clauses list in the ParamPathInfo node directly as a list of the
|
||||
* interesting join clauses for that rel. This takes care of the
|
||||
* possibility that there are multiple safe join clauses for such a rel,
|
||||
* and also ensures that we account for unsafe join clauses that we'll
|
||||
* still have to enforce locally (since the parameterized-path machinery
|
||||
* insists that we handle all movable clauses).
|
||||
*/
|
||||
|
||||
/* Scan the rel's join clauses */
|
||||
ppi_list = NIL;
|
||||
foreach(lc, baserel->joininfo)
|
||||
{
|
||||
RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
|
||||
Relids required_outer;
|
||||
ParamPathInfo *param_info;
|
||||
|
||||
/* Check if clause can be moved to this rel */
|
||||
if (!join_clause_is_movable_to(rinfo, baserel))
|
||||
|
@ -591,31 +596,29 @@ postgresGetForeignPaths(PlannerInfo *root,
|
|||
if (!is_foreign_expr(root, baserel, rinfo->clause))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* OK, get a cost estimate from the remote, and make a path.
|
||||
*/
|
||||
join_quals = list_make1(rinfo);
|
||||
estimate_path_cost_size(root, baserel, join_quals,
|
||||
&rows, &width,
|
||||
&startup_cost, &total_cost);
|
||||
|
||||
/* Must calculate required outer rels for this path */
|
||||
/* Calculate required outer rels for the resulting path */
|
||||
required_outer = bms_union(rinfo->clause_relids,
|
||||
baserel->lateral_relids);
|
||||
/* We do not want the foreign rel itself listed in required_outer */
|
||||
required_outer = bms_del_member(required_outer, baserel->relid);
|
||||
/* Enforce convention that required_outer is exactly NULL if empty */
|
||||
if (bms_is_empty(required_outer))
|
||||
required_outer = NULL;
|
||||
|
||||
path = create_foreignscan_path(root, baserel,
|
||||
rows,
|
||||
startup_cost,
|
||||
total_cost,
|
||||
NIL, /* no pathkeys */
|
||||
required_outer,
|
||||
NIL); /* no fdw_private list */
|
||||
add_path(baserel, (Path *) path);
|
||||
/*
|
||||
* required_outer probably can't be empty here, but if it were, we
|
||||
* couldn't make a parameterized path.
|
||||
*/
|
||||
if (bms_is_empty(required_outer))
|
||||
continue;
|
||||
|
||||
/* Get the ParamPathInfo */
|
||||
param_info = get_baserel_parampathinfo(root, baserel,
|
||||
required_outer);
|
||||
Assert(param_info != NULL);
|
||||
|
||||
/*
|
||||
* Add it to list unless we already have it. Testing pointer equality
|
||||
* is OK since get_baserel_parampathinfo won't make duplicates.
|
||||
*/
|
||||
ppi_list = list_append_unique_ptr(ppi_list, param_info);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -629,8 +632,8 @@ postgresGetForeignPaths(PlannerInfo *root,
|
|||
* We repeatedly scan the eclass list looking for column references
|
||||
* (or expressions) belonging to the foreign rel. Each time we find
|
||||
* one, we generate a list of equivalence joinclauses for it, and then
|
||||
* try to make those into foreign paths. Repeat till there are no
|
||||
* more candidate EC members.
|
||||
* see if any are safe to send to the remote. Repeat till there are
|
||||
* no more candidate EC members.
|
||||
*/
|
||||
ec_member_foreign_arg arg;
|
||||
|
||||
|
@ -658,6 +661,8 @@ postgresGetForeignPaths(PlannerInfo *root,
|
|||
foreach(lc, clauses)
|
||||
{
|
||||
RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
|
||||
Relids required_outer;
|
||||
ParamPathInfo *param_info;
|
||||
|
||||
/* Check if clause can be moved to this rel */
|
||||
if (!join_clause_is_movable_to(rinfo, baserel))
|
||||
|
@ -667,35 +672,60 @@ postgresGetForeignPaths(PlannerInfo *root,
|
|||
if (!is_foreign_expr(root, baserel, rinfo->clause))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* OK, get a cost estimate from the remote, and make a path.
|
||||
*/
|
||||
join_quals = list_make1(rinfo);
|
||||
estimate_path_cost_size(root, baserel, join_quals,
|
||||
&rows, &width,
|
||||
&startup_cost, &total_cost);
|
||||
|
||||
/* Must calculate required outer rels for this path */
|
||||
/* Calculate required outer rels for the resulting path */
|
||||
required_outer = bms_union(rinfo->clause_relids,
|
||||
baserel->lateral_relids);
|
||||
required_outer = bms_del_member(required_outer, baserel->relid);
|
||||
if (bms_is_empty(required_outer))
|
||||
required_outer = NULL;
|
||||
continue;
|
||||
|
||||
path = create_foreignscan_path(root, baserel,
|
||||
rows,
|
||||
startup_cost,
|
||||
total_cost,
|
||||
NIL, /* no pathkeys */
|
||||
required_outer,
|
||||
NIL); /* no fdw_private */
|
||||
add_path(baserel, (Path *) path);
|
||||
/* Get the ParamPathInfo */
|
||||
param_info = get_baserel_parampathinfo(root, baserel,
|
||||
required_outer);
|
||||
Assert(param_info != NULL);
|
||||
|
||||
/* Add it to list unless we already have it */
|
||||
ppi_list = list_append_unique_ptr(ppi_list, param_info);
|
||||
}
|
||||
|
||||
/* Try again, now ignoring the expression we found this time */
|
||||
arg.already_used = lappend(arg.already_used, arg.current);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now build a path for each useful outer relation.
|
||||
*/
|
||||
foreach(lc, ppi_list)
|
||||
{
|
||||
ParamPathInfo *param_info = (ParamPathInfo *) lfirst(lc);
|
||||
double rows;
|
||||
int width;
|
||||
Cost startup_cost;
|
||||
Cost total_cost;
|
||||
|
||||
/* Get a cost estimate from the remote */
|
||||
estimate_path_cost_size(root, baserel,
|
||||
param_info->ppi_clauses,
|
||||
&rows, &width,
|
||||
&startup_cost, &total_cost);
|
||||
|
||||
/*
|
||||
* ppi_rows currently won't get looked at by anything, but still we
|
||||
* may as well ensure that it matches our idea of the rowcount.
|
||||
*/
|
||||
param_info->ppi_rows = rows;
|
||||
|
||||
/* Make the path */
|
||||
path = create_foreignscan_path(root, baserel,
|
||||
rows,
|
||||
startup_cost,
|
||||
total_cost,
|
||||
NIL, /* no pathkeys */
|
||||
param_info->ppi_req_outer,
|
||||
NIL); /* no fdw_private list */
|
||||
add_path(baserel, (Path *) path);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -725,14 +755,13 @@ postgresGetForeignPlan(PlannerInfo *root,
|
|||
* those that can't. baserestrictinfo clauses that were previously
|
||||
* determined to be safe or unsafe by classifyConditions are shown in
|
||||
* fpinfo->remote_conds and fpinfo->local_conds. Anything else in the
|
||||
* scan_clauses list should be a join clause that was found safe by
|
||||
* postgresGetForeignPaths.
|
||||
* scan_clauses list will be a join clause, which we have to check for
|
||||
* remote-safety.
|
||||
*
|
||||
* Note: for clauses extracted from EquivalenceClasses, it's possible that
|
||||
* what we get here is a different representation of the clause than what
|
||||
* postgresGetForeignPaths saw; for example we might get a commuted
|
||||
* version of the clause. So we can't insist on simple equality as we do
|
||||
* for the baserestrictinfo clauses.
|
||||
* Note: the join clauses we see here should be the exact same ones
|
||||
* previously examined by postgresGetForeignPaths. Possibly it'd be worth
|
||||
* passing forward the classification work done then, rather than
|
||||
* repeating it here.
|
||||
*
|
||||
* This code must match "extract_actual_clauses(scan_clauses, false)"
|
||||
* except for the additional decision about remote versus local execution.
|
||||
|
@ -754,11 +783,10 @@ postgresGetForeignPlan(PlannerInfo *root,
|
|||
remote_conds = lappend(remote_conds, rinfo);
|
||||
else if (list_member_ptr(fpinfo->local_conds, rinfo))
|
||||
local_exprs = lappend(local_exprs, rinfo->clause);
|
||||
else
|
||||
{
|
||||
Assert(is_foreign_expr(root, baserel, rinfo->clause));
|
||||
else if (is_foreign_expr(root, baserel, rinfo->clause))
|
||||
remote_conds = lappend(remote_conds, rinfo);
|
||||
}
|
||||
else
|
||||
local_exprs = lappend(local_exprs, rinfo->clause);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1689,9 +1717,20 @@ estimate_path_cost_size(PlannerInfo *root,
|
|||
*/
|
||||
if (fpinfo->use_remote_estimate)
|
||||
{
|
||||
List *remote_join_conds;
|
||||
List *local_join_conds;
|
||||
StringInfoData sql;
|
||||
List *retrieved_attrs;
|
||||
PGconn *conn;
|
||||
Selectivity local_sel;
|
||||
QualCost local_cost;
|
||||
|
||||
/*
|
||||
* join_conds might contain both clauses that are safe to send across,
|
||||
* and clauses that aren't.
|
||||
*/
|
||||
classifyConditions(root, baserel, join_conds,
|
||||
&remote_join_conds, &local_join_conds);
|
||||
|
||||
/*
|
||||
* Construct EXPLAIN query including the desired SELECT, FROM, and
|
||||
|
@ -1705,8 +1744,8 @@ estimate_path_cost_size(PlannerInfo *root,
|
|||
if (fpinfo->remote_conds)
|
||||
appendWhereClause(&sql, root, baserel, fpinfo->remote_conds,
|
||||
true, NULL);
|
||||
if (join_conds)
|
||||
appendWhereClause(&sql, root, baserel, join_conds,
|
||||
if (remote_join_conds)
|
||||
appendWhereClause(&sql, root, baserel, remote_join_conds,
|
||||
(fpinfo->remote_conds == NIL), NULL);
|
||||
|
||||
/* Get the remote estimate */
|
||||
|
@ -1717,12 +1756,22 @@ estimate_path_cost_size(PlannerInfo *root,
|
|||
|
||||
retrieved_rows = rows;
|
||||
|
||||
/* Factor in the selectivity of the local_conds */
|
||||
rows = clamp_row_est(rows * fpinfo->local_conds_sel);
|
||||
/* Factor in the selectivity of the locally-checked quals */
|
||||
local_sel = clauselist_selectivity(root,
|
||||
local_join_conds,
|
||||
baserel->relid,
|
||||
JOIN_INNER,
|
||||
NULL);
|
||||
local_sel *= fpinfo->local_conds_sel;
|
||||
|
||||
/* Add in the eval cost of the local_conds */
|
||||
rows = clamp_row_est(rows * local_sel);
|
||||
|
||||
/* Add in the eval cost of the locally-checked quals */
|
||||
startup_cost += fpinfo->local_conds_cost.startup;
|
||||
total_cost += fpinfo->local_conds_cost.per_tuple * retrieved_rows;
|
||||
cost_qual_eval(&local_cost, local_join_conds, root);
|
||||
startup_cost += local_cost.startup;
|
||||
total_cost += local_cost.per_tuple * retrieved_rows;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -41,6 +41,7 @@ extern int ExtractConnectionOptions(List *defelems,
|
|||
/* in deparse.c */
|
||||
extern void classifyConditions(PlannerInfo *root,
|
||||
RelOptInfo *baserel,
|
||||
List *input_conds,
|
||||
List **remote_conds,
|
||||
List **local_conds);
|
||||
extern bool is_foreign_expr(PlannerInfo *root,
|
||||
|
|
|
@ -194,6 +194,12 @@ EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c8 = 'foo'; -- can't
|
|||
EXPLAIN (VERBOSE, COSTS false)
|
||||
SELECT * FROM ft2 a, ft2 b WHERE a.c1 = 47 AND b.c1 = a.c2;
|
||||
SELECT * FROM ft2 a, ft2 b WHERE a.c1 = 47 AND b.c1 = a.c2;
|
||||
-- check both safe and unsafe join conditions
|
||||
EXPLAIN (VERBOSE, COSTS false)
|
||||
SELECT * FROM ft2 a, ft2 b
|
||||
WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7);
|
||||
SELECT * FROM ft2 a, ft2 b
|
||||
WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7);
|
||||
|
||||
-- ===================================================================
|
||||
-- parameterized queries
|
||||
|
|
Loading…
Reference in New Issue