*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.128 2004/12/31 22:00:27 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.129 2005/01/13 17:19:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "utils/typcache.h"
-static void markTargetListOrigin(ParseState *pstate, Resdom *res, Var *var);
+static void markTargetListOrigin(ParseState *pstate, Resdom *res,
+ Var *var, int levelsup);
static Node *transformAssignmentIndirection(ParseState *pstate,
Node *basenode,
const char *targetName,
{
TargetEntry *tle = (TargetEntry *) lfirst(l);
- markTargetListOrigin(pstate, tle->resdom, (Var *) tle->expr);
+ markTargetListOrigin(pstate, tle->resdom, (Var *) tle->expr, 0);
}
}
* markTargetListOrigin()
* If 'var' is a Var of a plain relation, mark 'res' with its origin
*
+ * levelsup is an extra offset to interpret the Var's varlevelsup correctly.
+ *
* This is split out so it can recurse for join references. Note that we
* do not drill down into views, but report the view as the column owner.
*/
static void
-markTargetListOrigin(ParseState *pstate, Resdom *res, Var *var)
+markTargetListOrigin(ParseState *pstate, Resdom *res, Var *var, int levelsup)
{
+ int netlevelsup;
RangeTblEntry *rte;
AttrNumber attnum;
if (var == NULL || !IsA(var, Var))
return;
- rte = GetRTEByRangeTablePosn(pstate, var->varno, var->varlevelsup);
+ netlevelsup = var->varlevelsup + levelsup;
+ rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup);
attnum = var->varattno;
switch (rte->rtekind)
Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
- markTargetListOrigin(pstate, res, aliasvar);
+ markTargetListOrigin(pstate, res, aliasvar, netlevelsup);
}
break;
case RTE_SPECIAL:
* back to source text
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.187 2004/12/13 00:33:06 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.188 2005/01/13 17:19:10 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
static Node *get_rule_sortgroupclause(SortClause *srt, List *tlist,
bool force_colno,
deparse_context *context);
-static void get_names_for_var(Var *var, deparse_context *context,
+static void get_names_for_var(Var *var, int levelsup, deparse_context *context,
char **schemaname, char **refname, char **attname);
static RangeTblEntry *find_rte_by_refname(const char *refname,
deparse_context *context);
char *refname;
char *attname;
- get_names_for_var(var, context,
+ get_names_for_var(var, 0, context,
&schemaname, &refname, &attname);
tell_as = (attname == NULL ||
strcmp(attname, colname) != 0);
/*
* Get the schemaname, refname and attname for a (possibly nonlocal) Var.
*
+ * In some cases (currently only when recursing into an unnamed join)
+ * the Var's varlevelsup has to be interpreted with respect to a context
+ * above the current one; levelsup indicates the offset.
+ *
* schemaname is usually returned as NULL. It will be non-null only if
* use of the unqualified refname would find the wrong RTE.
*
* distinguish this case.)
*/
static void
-get_names_for_var(Var *var, deparse_context *context,
+get_names_for_var(Var *var, int levelsup, deparse_context *context,
char **schemaname, char **refname, char **attname)
{
+ int netlevelsup;
deparse_namespace *dpns;
RangeTblEntry *rte;
/* Find appropriate nesting depth */
- if (var->varlevelsup >= list_length(context->namespaces))
- elog(ERROR, "bogus varlevelsup: %d", var->varlevelsup);
+ netlevelsup = var->varlevelsup + levelsup;
+ if (netlevelsup >= list_length(context->namespaces))
+ elog(ERROR, "bogus varlevelsup: %d offset %d",
+ var->varlevelsup, levelsup);
dpns = (deparse_namespace *) list_nth(context->namespaces,
- var->varlevelsup);
+ netlevelsup);
/* Find the relevant RTE */
if (var->varno >= 1 && var->varno <= list_length(dpns->rtable))
var->varattno-1);
if (IsA(aliasvar, Var))
{
- get_names_for_var(aliasvar, context,
+ get_names_for_var(aliasvar, netlevelsup, context,
schemaname, refname, attname);
return;
}
char *refname;
char *attname;
- get_names_for_var(var, context,
+ get_names_for_var(var, 0, context,
&schemaname, &refname, &attname);
if (refname && (context->varprefix || attname == NULL))
{