diff options
Diffstat (limited to 'src/backend/optimizer/util')
-rw-r--r-- | src/backend/optimizer/util/pathnode.c | 8 | ||||
-rw-r--r-- | src/backend/optimizer/util/plancat.c | 1 | ||||
-rw-r--r-- | src/backend/optimizer/util/var.c | 43 |
3 files changed, 36 insertions, 16 deletions
diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index 4a1c94affb..8ed55a3d0e 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -25,8 +25,8 @@ #include "optimizer/paths.h" #include "optimizer/tlist.h" #include "parser/parsetree.h" -#include "utils/selfuncs.h" #include "utils/lsyscache.h" +#include "utils/selfuncs.h" static List *translate_sub_tlist(List *tlist, int relid); @@ -418,6 +418,7 @@ create_seqscan_path(PlannerInfo *root, RelOptInfo *rel) * 'indexscandir' is ForwardScanDirection or BackwardScanDirection * for an ordered index, or NoMovementScanDirection for * an unordered index. + * 'indexonly' is true if an index-only scan is wanted. * 'outer_rel' is the outer relation if this is a join inner indexscan path. * (pathkeys and indexscandir are ignored if so.) NULL if not. * @@ -430,6 +431,7 @@ create_index_path(PlannerInfo *root, List *indexorderbys, List *pathkeys, ScanDirection indexscandir, + bool indexonly, RelOptInfo *outer_rel) { IndexPath *pathnode = makeNode(IndexPath); @@ -468,6 +470,7 @@ create_index_path(PlannerInfo *root, pathnode->isjoininner = (outer_rel != NULL); pathnode->indexscandir = indexscandir; + pathnode->indexonly = indexonly; if (outer_rel != NULL) { @@ -506,7 +509,8 @@ create_index_path(PlannerInfo *root, pathnode->rows = rel->rows; } - cost_index(pathnode, root, index, indexquals, indexorderbys, outer_rel); + cost_index(pathnode, root, index, indexquals, indexorderbys, + indexonly, outer_rel); return pathnode; } diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 8a3a5d85e2..742e7a880a 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -210,6 +210,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, info->relam = indexRelation->rd_rel->relam; info->amcostestimate = indexRelation->rd_am->amcostestimate; info->amcanorderbyop = indexRelation->rd_am->amcanorderbyop; + info->amcanreturn = indexRelation->rd_am->amcanreturn; info->amoptionalkey = indexRelation->rd_am->amoptionalkey; info->amsearchnulls = indexRelation->rd_am->amsearchnulls; info->amhasgettuple = OidIsValid(indexRelation->rd_am->amgettuple); diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c index 8ce7ee41a1..888f6f67a8 100644 --- a/src/backend/optimizer/util/var.c +++ b/src/backend/optimizer/util/var.c @@ -36,6 +36,12 @@ typedef struct typedef struct { + Bitmapset *varattnos; + Index varno; +} pull_varattnos_context; + +typedef struct +{ int var_location; int sublevels_up; } locate_var_of_level_context; @@ -70,7 +76,7 @@ typedef struct static bool pull_varnos_walker(Node *node, pull_varnos_context *context); -static bool pull_varattnos_walker(Node *node, Bitmapset **varattnos); +static bool pull_varattnos_walker(Node *node, pull_varattnos_context *context); static bool contain_var_clause_walker(Node *node, void *context); static bool contain_vars_of_level_walker(Node *node, int *sublevels_up); static bool locate_var_of_level_walker(Node *node, @@ -177,23 +183,31 @@ pull_varnos_walker(Node *node, pull_varnos_context *context) * pull_varattnos * Find all the distinct attribute numbers present in an expression tree, * and add them to the initial contents of *varattnos. - * Only Vars that reference RTE 1 of rtable level zero are considered. + * Only Vars of the given varno and rtable level zero are considered. * * Attribute numbers are offset by FirstLowInvalidHeapAttributeNumber so that * we can include system attributes (e.g., OID) in the bitmap representation. * - * Currently, this does not support subqueries nor expressions containing - * references to multiple tables; not needed since it's only applied to - * index expressions and predicates. + * Currently, this does not support unplanned subqueries; that is not needed + * for current uses. It will handle already-planned SubPlan nodes, though, + * looking into only the "testexpr" and the "args" list. (The subplan cannot + * contain any other references to Vars of the current level.) */ void -pull_varattnos(Node *node, Bitmapset **varattnos) +pull_varattnos(Node *node, Index varno, Bitmapset **varattnos) { - (void) pull_varattnos_walker(node, varattnos); + pull_varattnos_context context; + + context.varattnos = *varattnos; + context.varno = varno; + + (void) pull_varattnos_walker(node, &context); + + *varattnos = context.varattnos; } static bool -pull_varattnos_walker(Node *node, Bitmapset **varattnos) +pull_varattnos_walker(Node *node, pull_varattnos_context *context) { if (node == NULL) return false; @@ -201,17 +215,18 @@ pull_varattnos_walker(Node *node, Bitmapset **varattnos) { Var *var = (Var *) node; - Assert(var->varno == 1); - *varattnos = bms_add_member(*varattnos, - var->varattno - FirstLowInvalidHeapAttributeNumber); + if (var->varno == context->varno && var->varlevelsup == 0) + context->varattnos = + bms_add_member(context->varattnos, + var->varattno - FirstLowInvalidHeapAttributeNumber); return false; } - /* Should not find a subquery or subplan */ + + /* Should not find an unplanned subquery */ Assert(!IsA(node, Query)); - Assert(!IsA(node, SubPlan)); return expression_tree_walker(node, pull_varattnos_walker, - (void *) varattnos); + (void *) context); } |