summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/util/var.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/util/var.c')
-rw-r--r--src/backend/optimizer/util/var.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/src/backend/optimizer/util/var.c b/src/backend/optimizer/util/var.c
index 13702b7d465..c501c827922 100644
--- a/src/backend/optimizer/util/var.c
+++ b/src/backend/optimizer/util/var.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.69 2007/01/05 22:19:33 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.70 2007/06/11 01:16:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -111,6 +111,14 @@ pull_varnos_walker(Node *node, pull_varnos_context *context)
context->varnos = bms_add_member(context->varnos, var->varno);
return false;
}
+ if (IsA(node, CurrentOfExpr))
+ {
+ CurrentOfExpr *cexpr = (CurrentOfExpr *) node;
+
+ if (context->sublevels_up == 0)
+ context->varnos = bms_add_member(context->varnos, cexpr->cvarno);
+ return false;
+ }
if (IsA(node, Query))
{
/* Recurse into RTE subquery or not-yet-planned sublink subquery */
@@ -217,6 +225,8 @@ contain_var_clause_walker(Node *node, void *context)
return true; /* abort the tree traversal and return true */
return false;
}
+ if (IsA(node, CurrentOfExpr))
+ return true;
return expression_tree_walker(node, contain_var_clause_walker, context);
}
@@ -249,6 +259,13 @@ contain_vars_of_level_walker(Node *node, int *sublevels_up)
{
if (((Var *) node)->varlevelsup == *sublevels_up)
return true; /* abort tree traversal and return true */
+ return false;
+ }
+ if (IsA(node, CurrentOfExpr))
+ {
+ if (*sublevels_up == 0)
+ return true;
+ return false;
}
if (IsA(node, Query))
{
@@ -376,6 +393,29 @@ find_minimum_var_level_walker(Node *node,
}
}
}
+ if (IsA(node, CurrentOfExpr))
+ {
+ int varlevelsup = 0;
+
+ /* convert levelsup to frame of reference of original query */
+ varlevelsup -= context->sublevels_up;
+ /* ignore local vars of subqueries */
+ if (varlevelsup >= 0)
+ {
+ if (context->min_varlevel < 0 ||
+ context->min_varlevel > varlevelsup)
+ {
+ context->min_varlevel = varlevelsup;
+
+ /*
+ * As soon as we find a local variable, we can abort the tree
+ * traversal, since min_varlevel is then certainly 0.
+ */
+ if (varlevelsup == 0)
+ return true;
+ }
+ }
+ }
/*
* An Aggref must be treated like a Var of its level. Normally we'd get