aboutsummaryrefslogtreecommitdiff
path: root/contrib/postgres_fdw/deparse.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2017-04-11 11:58:59 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2017-04-11 11:59:09 -0400
commit28b047875554b29837cded70a19384dae107c61a (patch)
tree10f55c34df844cdf0fb0c17dc30a2e1e88446944 /contrib/postgres_fdw/deparse.c
parentff7bce174390ae063c122ab04020bd4ee070d6ad (diff)
downloadpostgresql-28b047875554b29837cded70a19384dae107c61a.tar.gz
postgresql-28b047875554b29837cded70a19384dae107c61a.zip
Handle restriction clause lists more uniformly in postgres_fdw.
Clauses in the lists retained by postgres_fdw during planning were sometimes bare boolean clauses, sometimes RestrictInfos, and sometimes a mixture of the two in the same list. The comment about that situation didn't come close to telling the full truth, either. Aside from being confusing, this had a couple of bad practical consequences: * waste of planning cycles due to inability to cache per-clause selectivity and cost estimates; * sometimes, RestrictInfos would sneak into the fdw_private list of a finished Plan node, causing failures if, for example, we tried to ship the Plan tree to a parallel worker. (It may well be that it's a bug in the parallel-query logic that we would ever try to ship such a plan to a parallel worker, but in any case this deserves to be cleaned up.) To fix, rearrange so that clause lists in PgFdwRelationInfo are always lists of RestrictInfos, and then strip the RestrictInfos at the last minute when making a Plan node. In passing do a bit of refactoring and comment cleanup in postgresGetForeignPlan and foreign_join_ok. Although the messiness here dates back at least to 9.6, there's no evidence that it causes anything worse than wasted planning cycles in 9.6, so no back-patch for now. Per fuzz testing by Andreas Seltenreich. Tom Lane and Ashutosh Bapat Discussion: https://postgr.es/m/87tw5x4vcu.fsf@credativ.de
Diffstat (limited to 'contrib/postgres_fdw/deparse.c')
-rw-r--r--contrib/postgres_fdw/deparse.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c
index c5149a071da..1d5aa837635 100644
--- a/contrib/postgres_fdw/deparse.c
+++ b/contrib/postgres_fdw/deparse.c
@@ -210,7 +210,7 @@ classifyConditions(PlannerInfo *root,
foreach(lc, input_conds)
{
- RestrictInfo *ri = (RestrictInfo *) lfirst(lc);
+ RestrictInfo *ri = lfirst_node(RestrictInfo, lc);
if (is_foreign_expr(root, baserel, ri->clause))
*remote_conds = lappend(*remote_conds, ri);
@@ -869,6 +869,7 @@ build_tlist_to_deparse(RelOptInfo *foreignrel)
{
List *tlist = NIL;
PgFdwRelationInfo *fpinfo = (PgFdwRelationInfo *) foreignrel->fdw_private;
+ ListCell *lc;
/*
* For an upper relation, we have already built the target list while
@@ -884,9 +885,14 @@ build_tlist_to_deparse(RelOptInfo *foreignrel)
tlist = add_to_flat_tlist(tlist,
pull_var_clause((Node *) foreignrel->reltarget->exprs,
PVC_RECURSE_PLACEHOLDERS));
- tlist = add_to_flat_tlist(tlist,
- pull_var_clause((Node *) fpinfo->local_conds,
- PVC_RECURSE_PLACEHOLDERS));
+ foreach(lc, fpinfo->local_conds)
+ {
+ RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc);
+
+ tlist = add_to_flat_tlist(tlist,
+ pull_var_clause((Node *) rinfo->clause,
+ PVC_RECURSE_PLACEHOLDERS));
+ }
return tlist;
}
@@ -1049,6 +1055,7 @@ deparseSelectSql(List *tlist, bool is_subquery, List **retrieved_attrs,
* "buf".
*
* quals is the list of clauses to be included in the WHERE clause.
+ * (These may or may not include RestrictInfo decoration.)
*/
static void
deparseFromExpr(List *quals, deparse_expr_cxt *context)
@@ -1262,6 +1269,9 @@ deparseLockingClause(deparse_expr_cxt *context)
*
* The conditions in the list are assumed to be ANDed. This function is used to
* deparse WHERE clauses, JOIN .. ON clauses and HAVING clauses.
+ *
+ * Depending on the caller, the list elements might be either RestrictInfos
+ * or bare clauses.
*/
static void
appendConditions(List *exprs, deparse_expr_cxt *context)
@@ -1278,16 +1288,9 @@ appendConditions(List *exprs, deparse_expr_cxt *context)
{
Expr *expr = (Expr *) lfirst(lc);
- /*
- * Extract clause from RestrictInfo, if required. See comments in
- * declaration of PgFdwRelationInfo for details.
- */
+ /* Extract clause from RestrictInfo, if required */
if (IsA(expr, RestrictInfo))
- {
- RestrictInfo *ri = (RestrictInfo *) expr;
-
- expr = ri->clause;
- }
+ expr = ((RestrictInfo *) expr)->clause;
/* Connect expressions with "AND" and parenthesize each condition. */
if (!is_first)