diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2011-10-07 20:13:02 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2011-10-07 20:14:13 -0400 |
commit | a2822fb9337a21f98ac4ce850bb4145acf47ca27 (patch) | |
tree | c239fe9a32ff0225e906711a76348cee1567f0d8 /src/backend/optimizer/util/var.c | |
parent | caa1054df8408b165e5f66ff25c87b6dd0a0a1e7 (diff) | |
download | postgresql-a2822fb9337a21f98ac4ce850bb4145acf47ca27.tar.gz |
Support index-only scans using the visibility map to avoid heap fetches.
When a btree index contains all columns required by the query, and the
visibility map shows that all tuples on a target heap page are
visible-to-all, we don't need to fetch that heap page. This patch depends
on the previous patches that made the visibility map reliable.
There's a fair amount left to do here, notably trying to figure out a less
chintzy way of estimating the cost of an index-only scan, but the core
functionality seems ready to commit.
Robert Haas and Ibrar Ahmed, with some previous work by Heikki Linnakangas.
Diffstat (limited to 'src/backend/optimizer/util/var.c')
-rw-r--r-- | src/backend/optimizer/util/var.c | 43 |
1 files changed, 29 insertions, 14 deletions
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); } |