summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util')
-rw-r--r--src/backend/optimizer/util/pathnode.c8
-rw-r--r--src/backend/optimizer/util/plancat.c1
-rw-r--r--src/backend/optimizer/util/var.c43
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);
}