Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit c06b31d

Browse files
committed
get_names_for_var didn't do recursion for unnamed JOIN vars quite right;
got it wrong when the JOIN was in an outer query level. Per example from Laurie Burrow. Also fix same issue in markTargetListOrigin. I think the latter is only a latent bug since we currently don't apply markTargetListOrigin except at the outer level ... but should do it right anyway.
1 parent c2eef62 commit c06b31d

File tree

2 files changed

+27
-15
lines changed

2 files changed

+27
-15
lines changed

src/backend/parser/parse_target.c

+11-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.128 2004/12/31 22:00:27 pgsql Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.129 2005/01/13 17:19:09 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -29,7 +29,8 @@
2929
#include "utils/typcache.h"
3030

3131

32-
static void markTargetListOrigin(ParseState *pstate, Resdom *res, Var *var);
32+
static void markTargetListOrigin(ParseState *pstate, Resdom *res,
33+
Var *var, int levelsup);
3334
static Node *transformAssignmentIndirection(ParseState *pstate,
3435
Node *basenode,
3536
const char *targetName,
@@ -174,26 +175,30 @@ markTargetListOrigins(ParseState *pstate, List *targetlist)
174175
{
175176
TargetEntry *tle = (TargetEntry *) lfirst(l);
176177

177-
markTargetListOrigin(pstate, tle->resdom, (Var *) tle->expr);
178+
markTargetListOrigin(pstate, tle->resdom, (Var *) tle->expr, 0);
178179
}
179180
}
180181

181182
/*
182183
* markTargetListOrigin()
183184
* If 'var' is a Var of a plain relation, mark 'res' with its origin
184185
*
186+
* levelsup is an extra offset to interpret the Var's varlevelsup correctly.
187+
*
185188
* This is split out so it can recurse for join references. Note that we
186189
* do not drill down into views, but report the view as the column owner.
187190
*/
188191
static void
189-
markTargetListOrigin(ParseState *pstate, Resdom *res, Var *var)
192+
markTargetListOrigin(ParseState *pstate, Resdom *res, Var *var, int levelsup)
190193
{
194+
int netlevelsup;
191195
RangeTblEntry *rte;
192196
AttrNumber attnum;
193197

194198
if (var == NULL || !IsA(var, Var))
195199
return;
196-
rte = GetRTEByRangeTablePosn(pstate, var->varno, var->varlevelsup);
200+
netlevelsup = var->varlevelsup + levelsup;
201+
rte = GetRTEByRangeTablePosn(pstate, var->varno, netlevelsup);
197202
attnum = var->varattno;
198203

199204
switch (rte->rtekind)
@@ -223,7 +228,7 @@ markTargetListOrigin(ParseState *pstate, Resdom *res, Var *var)
223228

224229
Assert(attnum > 0 && attnum <= list_length(rte->joinaliasvars));
225230
aliasvar = (Var *) list_nth(rte->joinaliasvars, attnum - 1);
226-
markTargetListOrigin(pstate, res, aliasvar);
231+
markTargetListOrigin(pstate, res, aliasvar, netlevelsup);
227232
}
228233
break;
229234
case RTE_SPECIAL:

src/backend/utils/adt/ruleutils.c

+16-9
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* back to source text
44
*
55
* IDENTIFICATION
6-
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.187 2004/12/13 00:33:06 tgl Exp $
6+
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.188 2005/01/13 17:19:10 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -182,7 +182,7 @@ static void get_setop_query(Node *setOp, Query *query,
182182
static Node *get_rule_sortgroupclause(SortClause *srt, List *tlist,
183183
bool force_colno,
184184
deparse_context *context);
185-
static void get_names_for_var(Var *var, deparse_context *context,
185+
static void get_names_for_var(Var *var, int levelsup, deparse_context *context,
186186
char **schemaname, char **refname, char **attname);
187187
static RangeTblEntry *find_rte_by_refname(const char *refname,
188188
deparse_context *context);
@@ -1998,7 +1998,7 @@ get_basic_select_query(Query *query, deparse_context *context,
19981998
char *refname;
19991999
char *attname;
20002000

2001-
get_names_for_var(var, context,
2001+
get_names_for_var(var, 0, context,
20022002
&schemaname, &refname, &attname);
20032003
tell_as = (attname == NULL ||
20042004
strcmp(attname, colname) != 0);
@@ -2392,6 +2392,10 @@ get_utility_query_def(Query *query, deparse_context *context)
23922392
/*
23932393
* Get the schemaname, refname and attname for a (possibly nonlocal) Var.
23942394
*
2395+
* In some cases (currently only when recursing into an unnamed join)
2396+
* the Var's varlevelsup has to be interpreted with respect to a context
2397+
* above the current one; levelsup indicates the offset.
2398+
*
23952399
* schemaname is usually returned as NULL. It will be non-null only if
23962400
* use of the unqualified refname would find the wrong RTE.
23972401
*
@@ -2404,17 +2408,20 @@ get_utility_query_def(Query *query, deparse_context *context)
24042408
* distinguish this case.)
24052409
*/
24062410
static void
2407-
get_names_for_var(Var *var, deparse_context *context,
2411+
get_names_for_var(Var *var, int levelsup, deparse_context *context,
24082412
char **schemaname, char **refname, char **attname)
24092413
{
2414+
int netlevelsup;
24102415
deparse_namespace *dpns;
24112416
RangeTblEntry *rte;
24122417

24132418
/* Find appropriate nesting depth */
2414-
if (var->varlevelsup >= list_length(context->namespaces))
2415-
elog(ERROR, "bogus varlevelsup: %d", var->varlevelsup);
2419+
netlevelsup = var->varlevelsup + levelsup;
2420+
if (netlevelsup >= list_length(context->namespaces))
2421+
elog(ERROR, "bogus varlevelsup: %d offset %d",
2422+
var->varlevelsup, levelsup);
24162423
dpns = (deparse_namespace *) list_nth(context->namespaces,
2417-
var->varlevelsup);
2424+
netlevelsup);
24182425

24192426
/* Find the relevant RTE */
24202427
if (var->varno >= 1 && var->varno <= list_length(dpns->rtable))
@@ -2467,7 +2474,7 @@ get_names_for_var(Var *var, deparse_context *context,
24672474
var->varattno-1);
24682475
if (IsA(aliasvar, Var))
24692476
{
2470-
get_names_for_var(aliasvar, context,
2477+
get_names_for_var(aliasvar, netlevelsup, context,
24712478
schemaname, refname, attname);
24722479
return;
24732480
}
@@ -2867,7 +2874,7 @@ get_rule_expr(Node *node, deparse_context *context,
28672874
char *refname;
28682875
char *attname;
28692876

2870-
get_names_for_var(var, context,
2877+
get_names_for_var(var, 0, context,
28712878
&schemaname, &refname, &attname);
28722879
if (refname && (context->varprefix || attname == NULL))
28732880
{

0 commit comments

Comments
 (0)