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

Lines changed: 11 additions & 6 deletions
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

Lines changed: 16 additions & 9 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy