Skip to content

Commit

Permalink
Optimize and rename ColumnList() to mongo_get_column_list().
Browse files Browse the repository at this point in the history
MongoGetForeignPlan() builds the list of columns used for projection
and restriction clauses in scan_var_list. Pass this list to
ColumnList() to avoid duplication of work, and use it to retrieve a
list of foreign table columns. Also, rename ColumnList() to
mongo_get_column_list().

FDW-391, Vaibhav Dalvi, reviewed by Suraj Kharage and Jeevan Ladhe.
  • Loading branch information
jeevanladhe committed Oct 26, 2021
1 parent 3205c5b commit 67ae36c
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 59 deletions.
10 changes: 8 additions & 2 deletions mongo_fdw.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,8 +482,14 @@ MongoGetForeignPlan(PlannerInfo *root,
local_exprs = lappend(local_exprs, rinfo->clause);
}

/* We don't need to serialize column list as lists are copiable */
columnList = ColumnList(foreignrel);
/* Add local expression Var nodes to scan_var_list. */
scan_var_list = list_concat_unique(NIL, scan_var_list);
scan_var_list = list_concat_unique(scan_var_list,
pull_var_clause((Node *) local_exprs,
PVC_RECURSE_PLACEHOLDERS));

/* Form column list required for query execution from scan_var_list. */
columnList = mongo_get_column_list(foreignrel, scan_var_list);

/* Construct foreign plan with query document and column list */
foreignPrivateList = list_make2(columnList, remote_exprs);
Expand Down
3 changes: 2 additions & 1 deletion mongo_fdw.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,8 @@ extern void mongo_release_connection(MONGO_CONN *conn);
extern BSON *QueryDocument(Oid relationId,
List *opExpressionList,
ForeignScanState *scanStateNode);
extern List *ColumnList(RelOptInfo *baserel);
extern List *mongo_get_column_list(RelOptInfo *foreignrel,
List *scan_var_list);
extern bool mongo_is_foreign_expr(PlannerInfo *root, RelOptInfo *baserel,
Expr *expression);

Expand Down
71 changes: 15 additions & 56 deletions mongo_query.c
Original file line number Diff line number Diff line change
Expand Up @@ -664,72 +664,31 @@ AppendMongoValue(BSON *queryDocument, const char *keyName, Datum value,
}

/*
* ColumnList
* Takes in the planner's information about this foreign table. The
* function then finds all columns needed for query execution, including
* those used in projections, joins, and filter clauses, de-duplicates
* these columns, and returns them in a new list.
* mongo_get_column_list
* Process scan_var_list to find all columns needed for query execution
* and return them.
*/
List *
ColumnList(RelOptInfo *baserel)
mongo_get_column_list(RelOptInfo *foreignrel, List *scan_var_list)
{
List *columnList = NIL;
List *neededColumnList;
AttrNumber columnIndex;
AttrNumber columnCount = baserel->max_attr;
ListCell *lc;

#if PG_VERSION_NUM >= 90600
List *targetColumnList = baserel->reltarget->exprs;
#else
List *targetColumnList = baserel->reltargetlist;
#endif
List *restrictInfoList = baserel->baserestrictinfo;
ListCell *restrictInfoCell;

/* First add the columns used in joins and projections */
neededColumnList = pull_var_clause((Node *)targetColumnList,
#if PG_VERSION_NUM < 90600
PVC_RECURSE_AGGREGATES,
#endif
PVC_RECURSE_PLACEHOLDERS);

/* Then walk over all restriction clauses, and pull up any used columns */
foreach(restrictInfoCell, restrictInfoList)
foreach(lc, scan_var_list)
{
RestrictInfo *restrictInfo = (RestrictInfo *) lfirst(restrictInfoCell);
Node *restrictClause = (Node *) restrictInfo->clause;
List *clauseColumnList = NIL;

/* Recursively pull up any columns used in the restriction clause */
clauseColumnList = pull_var_clause(restrictClause,
#if PG_VERSION_NUM < 90600
PVC_RECURSE_AGGREGATES,
#endif
PVC_RECURSE_PLACEHOLDERS);

neededColumnList = list_union(neededColumnList, clauseColumnList);
}
Var *var = (Var *) lfirst(lc);

/* Walk over all column definitions, and de-duplicate column list */
for (columnIndex = 1; columnIndex <= columnCount; columnIndex++)
{
ListCell *neededColumnCell;
Var *column = NULL;
Assert(IsA(var, Var));

/* Look for this column in the needed column list */
foreach(neededColumnCell, neededColumnList)
{
Var *neededColumn = (Var *) lfirst(neededColumnCell);
/* Var belongs to foreign table? */
if (!bms_is_member(var->varno, foreignrel->relids))
continue;

if (neededColumn->varattno == columnIndex)
{
column = neededColumn;
break;
}
}
/* Do not support whole-row reference */
if (var->varattno == 0)
continue;

if (column != NULL)
columnList = lappend(columnList, column);
columnList = lappend(columnList, var);
}

return columnList;
Expand Down

0 comments on commit 67ae36c

Please sign in to comment.