Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc1f51ed

Browse files
committed
Change post-rewriter representation of dropped columns in joinaliasvars.
It's possible to drop a column from an input table of a JOIN clause in aview, if that column is nowhere actually referenced in the view. But itwill still be there in the JOIN clause's joinaliasvars list. We used toreplace such entries with NULL Const nodes, which is handy for generationof RowExpr expansion of a whole-row reference to the view. The troublewith that is that it can't be distinguished from the situation aftersubquery pull-up of a constant subquery output expression below the JOIN.Instead, replace such joinaliasvars with null pointers (empty expressiontrees), which can't be confused with pulled-up expressions. expandRTE()still emits the old convention, though, for convenience of RowExprgeneration and to reduce the risk of breaking extension code.In HEAD and 9.3, this patch also fixes a problem with some new code inruleutils.c that was failing to cope with implicitly-casted joinaliasvarsentries, as per recent report from Feike Steenbergen. That oversight wasbecause of an inadequate description of the data structure in parsenodes.h,which I've now corrected. There were some pre-existing oversights of thesame ilk elsewhere, which I believe are now all fixed.
1 parente23adef commitc1f51ed

File tree

6 files changed

+59
-35
lines changed

6 files changed

+59
-35
lines changed

‎src/backend/optimizer/util/var.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,7 @@ flatten_join_alias_vars_mutator(Node *node,
777777
newvar= (Node*)lfirst(l);
778778
attnum++;
779779
/* Ignore dropped columns */
780-
if (IsA(newvar,Const))
780+
if (newvar==NULL)
781781
continue;
782782

783783
/*
@@ -807,6 +807,7 @@ flatten_join_alias_vars_mutator(Node *node,
807807
/* Expand join alias reference */
808808
Assert(var->varattno>0);
809809
newvar= (Node*)list_nth(rte->joinaliasvars,var->varattno-1);
810+
Assert(newvar!=NULL);
810811

811812
/*
812813
* If we are expanding an alias carried down from an upper query, must

‎src/backend/parser/parse_relation.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include"funcapi.h"
2525
#include"nodes/makefuncs.h"
2626
#include"nodes/nodeFuncs.h"
27+
#include"optimizer/clauses.h"
2728
#include"parser/parsetree.h"
2829
#include"parser/parse_relation.h"
2930
#include"parser/parse_type.h"
@@ -654,14 +655,15 @@ markRTEForSelectPriv(ParseState *pstate, RangeTblEntry *rte,
654655
* The aliasvar could be either a Var or a COALESCE expression,
655656
* but in the latter case we should already have marked the two
656657
* referent variables as being selected, due to their use in the
657-
* JOIN clause. So we need only be concerned with thesimpleVar
658-
*case.
658+
* JOIN clause. So we need only be concerned with the Var case.
659+
*But we do need to drill down through implicit coercions.
659660
*/
660661
Var*aliasvar;
661662

662663
Assert(col>0&&col <=list_length(rte->joinaliasvars));
663664
aliasvar= (Var*)list_nth(rte->joinaliasvars,col-1);
664-
if (IsA(aliasvar,Var))
665+
aliasvar= (Var*)strip_implicit_coercions((Node*)aliasvar);
666+
if (aliasvar&&IsA(aliasvar,Var))
665667
markVarForSelectPriv(pstate,aliasvar,NULL);
666668
}
667669
}
@@ -1755,19 +1757,27 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
17551757
* deleted columns in the join; but we have to check since
17561758
* this routine is also used by the rewriter, and joins
17571759
* found in stored rules might have join columns for
1758-
* since-deleted columns. This will be signaled by aNULL
1759-
*Const in the alias-vars list.
1760+
* since-deleted columns. This will be signaled by anull
1761+
*pointer in the alias-vars list.
17601762
*/
1761-
if (IsA(avar,Const))
1763+
if (avar==NULL)
17621764
{
17631765
if (include_dropped)
17641766
{
17651767
if (colnames)
17661768
*colnames=lappend(*colnames,
17671769
makeString(pstrdup("")));
17681770
if (colvars)
1771+
{
1772+
/*
1773+
* Can't use join's column type here (it might
1774+
* be dropped!); but it doesn't really matter
1775+
* what type the Const claims to be.
1776+
*/
17691777
*colvars=lappend(*colvars,
1770-
copyObject(avar));
1778+
makeNullConst(INT4OID,-1,
1779+
InvalidOid));
1780+
}
17711781
}
17721782
continue;
17731783
}
@@ -2156,6 +2166,7 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
21562166

21572167
Assert(attnum>0&&attnum <=list_length(rte->joinaliasvars));
21582168
aliasvar= (Node*)list_nth(rte->joinaliasvars,attnum-1);
2169+
Assert(aliasvar!=NULL);
21592170
*vartype=exprType(aliasvar);
21602171
*vartypmod=exprTypmod(aliasvar);
21612172
*varcollid=exprCollation(aliasvar);
@@ -2218,7 +2229,7 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
22182229
* but one in a stored rule might contain columns that were
22192230
* dropped from the underlying tables, if said columns are
22202231
* nowhere explicitly referenced in the rule. This will be
2221-
* signaled to us by aNULL Const in the joinaliasvars list.
2232+
* signaled to us by anull pointer in the joinaliasvars list.
22222233
*/
22232234
Var*aliasvar;
22242235

@@ -2227,7 +2238,7 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
22272238
elog(ERROR,"invalid varattno %d",attnum);
22282239
aliasvar= (Var*)list_nth(rte->joinaliasvars,attnum-1);
22292240

2230-
result=IsA(aliasvar,Const);
2241+
result= (aliasvar==NULL);
22312242
}
22322243
break;
22332244
caseRTE_FUNCTION:

‎src/backend/parser/parse_target.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
304304

305305
Assert(attnum>0&&attnum <=list_length(rte->joinaliasvars));
306306
aliasvar= (Var*)list_nth(rte->joinaliasvars,attnum-1);
307+
/* We intentionally don't strip implicit coercions here */
307308
markTargetListOrigin(pstate,tle,aliasvar,netlevelsup);
308309
}
309310
break;
@@ -1419,6 +1420,8 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
14191420
/* Join RTE --- recursively inspect the alias variable */
14201421
Assert(attnum>0&&attnum <=list_length(rte->joinaliasvars));
14211422
expr= (Node*)list_nth(rte->joinaliasvars,attnum-1);
1423+
Assert(expr!=NULL);
1424+
/* We intentionally don't strip implicit coercions here */
14221425
if (IsA(expr,Var))
14231426
returnexpandRecordVariable(pstate, (Var*)expr,netlevelsup);
14241427
/* else fall through to inspect the expression */

‎src/backend/rewrite/rewriteHandler.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include"catalog/pg_type.h"
1919
#include"nodes/makefuncs.h"
2020
#include"nodes/nodeFuncs.h"
21+
#include"optimizer/clauses.h"
2122
#include"parser/analyze.h"
2223
#include"parser/parse_coerce.h"
2324
#include"parser/parsetree.h"
@@ -89,9 +90,8 @@ static Query *fireRIRrules(Query *parsetree, List *activeRIRs,
8990
* such a list in a stored rule to include references to dropped columns.
9091
* (If the column is not explicitly referenced anywhere else in the query,
9192
* the dependency mechanism won't consider it used by the rule and so won't
92-
* prevent the column drop.) To support get_rte_attribute_is_dropped(),
93-
* we replace join alias vars that reference dropped columns with NULL Const
94-
* nodes.
93+
* prevent the column drop.) To support get_rte_attribute_is_dropped(), we
94+
* replace join alias vars that reference dropped columns with null pointers.
9595
*
9696
* (In PostgreSQL 8.0, we did not do this processing but instead had
9797
* get_rte_attribute_is_dropped() recurse to detect dropped columns in joins.
@@ -158,8 +158,8 @@ AcquireRewriteLocks(Query *parsetree, bool forUpdatePushedDown)
158158

159159
/*
160160
* Scan the join's alias var list to see if any columns have
161-
* been dropped, and if so replace those Vars withNULL
162-
*Consts.
161+
* been dropped, and if so replace those Vars withnull
162+
*pointers.
163163
*
164164
* Since a join has only two inputs, we can expect to see
165165
* multiple references to the same input RTE; optimize away
@@ -170,16 +170,20 @@ AcquireRewriteLocks(Query *parsetree, bool forUpdatePushedDown)
170170
curinputrte=NULL;
171171
foreach(ll,rte->joinaliasvars)
172172
{
173-
Var*aliasvar= (Var*)lfirst(ll);
173+
Var*aliasitem= (Var*)lfirst(ll);
174+
Var*aliasvar=aliasitem;
175+
176+
/* Look through any implicit coercion */
177+
aliasvar= (Var*)strip_implicit_coercions((Node*)aliasvar);
174178

175179
/*
176180
* If the list item isn't a simple Var, then it must
177181
* represent a merged column, ie a USING column, and so it
178182
* couldn't possibly be dropped, since it's referenced in
179-
* the join clause. (Conceivably it could also be aNULL
180-
*constant already? But that's OK too.)
183+
* the join clause. (Conceivably it could also be anull
184+
*pointer already? But that's OK too.)
181185
*/
182-
if (IsA(aliasvar,Var))
186+
if (aliasvar&&IsA(aliasvar,Var))
183187
{
184188
/*
185189
* The elements of an alias list have to refer to
@@ -203,15 +207,11 @@ AcquireRewriteLocks(Query *parsetree, bool forUpdatePushedDown)
203207
if (get_rte_attribute_is_dropped(curinputrte,
204208
aliasvar->varattno))
205209
{
206-
/*
207-
* can't use vartype here, since that might be a
208-
* now-dropped type OID, but it doesn't really
209-
* matter what type the Const claims to be.
210-
*/
211-
aliasvar= (Var*)makeNullConst(INT4OID,-1,InvalidOid);
210+
/* Replace the join alias item with a NULL */
211+
aliasitem=NULL;
212212
}
213213
}
214-
newaliasvars=lappend(newaliasvars,aliasvar);
214+
newaliasvars=lappend(newaliasvars,aliasitem);
215215
}
216216
rte->joinaliasvars=newaliasvars;
217217
break;

‎src/backend/utils/adt/ruleutils.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3870,7 +3870,8 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
38703870
Var*aliasvar;
38713871

38723872
aliasvar= (Var*)list_nth(rte->joinaliasvars,attnum-1);
3873-
if (IsA(aliasvar,Var))
3873+
/* we intentionally don't strip implicit coercions here */
3874+
if (aliasvar&&IsA(aliasvar,Var))
38743875
{
38753876
returnget_variable(aliasvar,var->varlevelsup+levelsup,
38763877
istoplevel,context);
@@ -4162,6 +4163,8 @@ get_name_for_var_field(Var *var, int fieldno,
41624163
elog(ERROR,"cannot decompile join alias var in plan tree");
41634164
Assert(attnum>0&&attnum <=list_length(rte->joinaliasvars));
41644165
expr= (Node*)list_nth(rte->joinaliasvars,attnum-1);
4166+
Assert(expr!=NULL);
4167+
/* we intentionally don't strip implicit coercions here */
41654168
if (IsA(expr,Var))
41664169
returnget_name_for_var_field((Var*)expr,fieldno,
41674170
var->varlevelsup+levelsup,

‎src/include/nodes/parsenodes.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ typedef struct XmlSerialize
639639
* a stored rule might contain entries for columns dropped since the rule
640640
* was created.(This is only possible for columns not actually referenced
641641
* in the rule.) When loading a stored rule, we replace the joinaliasvars
642-
* items for any such columns withNULL Consts.(We can't simply delete
642+
* items for any such columns withnull pointers.(We can't simply delete
643643
* them from the joinaliasvars list, because that would affect the attnums
644644
* of Vars referencing the rest of the list.)
645645
*
@@ -709,13 +709,19 @@ typedef struct RangeTblEntry
709709
/*
710710
* Fields valid for a join RTE (else NULL/zero):
711711
*
712-
* joinaliasvars is a list of Vars or COALESCE expressions corresponding
713-
* to the columns of the join result. An alias Var referencing column K
714-
* of the join result can be replaced by the K'th element of joinaliasvars
715-
* --- but to simplify the task of reverse-listing aliases correctly, we
716-
* do not do that until planning time.In a Query loaded from a stored
717-
* rule, it is also possible for joinaliasvars items to be NULL Consts,
718-
* denoting columns dropped since the rule was made.
712+
* joinaliasvars is a list of (usually) Vars corresponding to the columns
713+
* of the join result.An alias Var referencing column K of the join
714+
* result can be replaced by the K'th element of joinaliasvars --- but to
715+
* simplify the task of reverse-listing aliases correctly, we do not do
716+
* that until planning time. In detail: an element of joinaliasvars can
717+
* be a Var of one of the join's input relations, or such a Var with an
718+
* implicit coercion to the join's output column type, or a COALESCE
719+
* expression containing the two input column Vars (possibly coerced).
720+
* Within a Query loaded from a stored rule, it is also possible for
721+
* joinaliasvars items to be null pointers, which are placeholders for
722+
* (necessarily unreferenced) columns dropped since the rule was made.
723+
* Also, once planning begins, joinaliasvars items can be almost anything,
724+
* as a result of subquery-flattening substitutions.
719725
*/
720726
JoinTypejointype;/* type of join */
721727
List*joinaliasvars;/* list of alias-var expansions */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp