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

Commit0483608

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 parenta0dc922 commit0483608

File tree

6 files changed

+58
-35
lines changed

6 files changed

+58
-35
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,7 @@ flatten_join_alias_vars_mutator(Node *node,
748748
newvar= (Node*)lfirst(l);
749749
attnum++;
750750
/* Ignore dropped columns */
751-
if (IsA(newvar,Const))
751+
if (newvar==NULL)
752752
continue;
753753

754754
/*
@@ -778,6 +778,7 @@ flatten_join_alias_vars_mutator(Node *node,
778778
/* Expand join alias reference */
779779
Assert(var->varattno>0);
780780
newvar= (Node*)list_nth(rte->joinaliasvars,var->varattno-1);
781+
Assert(newvar!=NULL);
781782

782783
/*
783784
* If we are expanding an alias carried down from an upper query, must

‎src/backend/parser/parse_relation.c

Lines changed: 19 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
}
@@ -1715,19 +1717,26 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
17151717
* deleted columns in the join; but we have to check since
17161718
* this routine is also used by the rewriter, and joins
17171719
* found in stored rules might have join columns for
1718-
* since-deleted columns. This will be signaled by aNULL
1719-
*Const in the alias-vars list.
1720+
* since-deleted columns. This will be signaled by anull
1721+
*pointer in the alias-vars list.
17201722
*/
1721-
if (IsA(avar,Const))
1723+
if (avar==NULL)
17221724
{
17231725
if (include_dropped)
17241726
{
17251727
if (colnames)
17261728
*colnames=lappend(*colnames,
17271729
makeString(pstrdup("")));
17281730
if (colvars)
1731+
{
1732+
/*
1733+
* Can't use join's column type here (it might
1734+
* be dropped!); but it doesn't really matter
1735+
* what type the Const claims to be.
1736+
*/
17291737
*colvars=lappend(*colvars,
1730-
copyObject(avar));
1738+
makeNullConst(INT4OID,-1));
1739+
}
17311740
}
17321741
continue;
17331742
}
@@ -2102,6 +2111,7 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
21022111

21032112
Assert(attnum>0&&attnum <=list_length(rte->joinaliasvars));
21042113
aliasvar= (Node*)list_nth(rte->joinaliasvars,attnum-1);
2114+
Assert(aliasvar!=NULL);
21052115
*vartype=exprType(aliasvar);
21062116
*vartypmod=exprTypmod(aliasvar);
21072117
}
@@ -2162,7 +2172,7 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
21622172
* but one in a stored rule might contain columns that were
21632173
* dropped from the underlying tables, if said columns are
21642174
* nowhere explicitly referenced in the rule. This will be
2165-
* signaled to us by aNULL Const in the joinaliasvars list.
2175+
* signaled to us by anull pointer in the joinaliasvars list.
21662176
*/
21672177
Var*aliasvar;
21682178

@@ -2171,7 +2181,7 @@ get_rte_attribute_is_dropped(RangeTblEntry *rte, AttrNumber attnum)
21712181
elog(ERROR,"invalid varattno %d",attnum);
21722182
aliasvar= (Var*)list_nth(rte->joinaliasvars,attnum-1);
21732183

2174-
result=IsA(aliasvar,Const);
2184+
result= (aliasvar==NULL);
21752185
}
21762186
break;
21772187
caseRTE_FUNCTION:

‎src/backend/parser/parse_target.c

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

293293
Assert(attnum>0&&attnum <=list_length(rte->joinaliasvars));
294294
aliasvar= (Var*)list_nth(rte->joinaliasvars,attnum-1);
295+
/* We intentionally don't strip implicit coercions here */
295296
markTargetListOrigin(pstate,tle,aliasvar,netlevelsup);
296297
}
297298
break;
@@ -1329,6 +1330,8 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
13291330
/* Join RTE --- recursively inspect the alias variable */
13301331
Assert(attnum>0&&attnum <=list_length(rte->joinaliasvars));
13311332
expr= (Node*)list_nth(rte->joinaliasvars,attnum-1);
1333+
Assert(expr!=NULL);
1334+
/* We intentionally don't strip implicit coercions here */
13321335
if (IsA(expr,Var))
13331336
returnexpandRecordVariable(pstate, (Var*)expr,netlevelsup);
13341337
/* 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
@@ -17,6 +17,7 @@
1717
#include"catalog/pg_type.h"
1818
#include"nodes/makefuncs.h"
1919
#include"nodes/nodeFuncs.h"
20+
#include"optimizer/clauses.h"
2021
#include"parser/analyze.h"
2122
#include"parser/parse_coerce.h"
2223
#include"parser/parsetree.h"
@@ -86,9 +87,8 @@ static Query *fireRIRrules(Query *parsetree, List *activeRIRs,
8687
* such a list in a stored rule to include references to dropped columns.
8788
* (If the column is not explicitly referenced anywhere else in the query,
8889
* the dependency mechanism won't consider it used by the rule and so won't
89-
* prevent the column drop.) To support get_rte_attribute_is_dropped(),
90-
* we replace join alias vars that reference dropped columns with NULL Const
91-
* nodes.
90+
* prevent the column drop.) To support get_rte_attribute_is_dropped(), we
91+
* replace join alias vars that reference dropped columns with null pointers.
9292
*
9393
* (In PostgreSQL 8.0, we did not do this processing but instead had
9494
* get_rte_attribute_is_dropped() recurse to detect dropped columns in joins.
@@ -148,8 +148,8 @@ AcquireRewriteLocks(Query *parsetree, bool forUpdatePushedDown)
148148

149149
/*
150150
* Scan the join's alias var list to see if any columns have
151-
* been dropped, and if so replace those Vars withNULL
152-
*Consts.
151+
* been dropped, and if so replace those Vars withnull
152+
*pointers.
153153
*
154154
* Since a join has only two inputs, we can expect to see
155155
* multiple references to the same input RTE; optimize away
@@ -160,16 +160,20 @@ AcquireRewriteLocks(Query *parsetree, bool forUpdatePushedDown)
160160
curinputrte=NULL;
161161
foreach(ll,rte->joinaliasvars)
162162
{
163-
Var*aliasvar= (Var*)lfirst(ll);
163+
Var*aliasitem= (Var*)lfirst(ll);
164+
Var*aliasvar=aliasitem;
165+
166+
/* Look through any implicit coercion */
167+
aliasvar= (Var*)strip_implicit_coercions((Node*)aliasvar);
164168

165169
/*
166170
* If the list item isn't a simple Var, then it must
167171
* represent a merged column, ie a USING column, and so it
168172
* couldn't possibly be dropped, since it's referenced in
169-
* the join clause. (Conceivably it could also be aNULL
170-
*constant already? But that's OK too.)
173+
* the join clause. (Conceivably it could also be anull
174+
*pointer already? But that's OK too.)
171175
*/
172-
if (IsA(aliasvar,Var))
176+
if (aliasvar&&IsA(aliasvar,Var))
173177
{
174178
/*
175179
* The elements of an alias list have to refer to
@@ -193,15 +197,11 @@ AcquireRewriteLocks(Query *parsetree, bool forUpdatePushedDown)
193197
if (get_rte_attribute_is_dropped(curinputrte,
194198
aliasvar->varattno))
195199
{
196-
/*
197-
* can't use vartype here, since that might be a
198-
* now-dropped type OID, but it doesn't really
199-
* matter what type the Const claims to be.
200-
*/
201-
aliasvar= (Var*)makeNullConst(INT4OID,-1);
200+
/* Replace the join alias item with a NULL */
201+
aliasitem=NULL;
202202
}
203203
}
204-
newaliasvars=lappend(newaliasvars,aliasvar);
204+
newaliasvars=lappend(newaliasvars,aliasitem);
205205
}
206206
rte->joinaliasvars=newaliasvars;
207207
break;

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

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

37393739
aliasvar= (Var*)list_nth(rte->joinaliasvars,attnum-1);
3740-
if (IsA(aliasvar,Var))
3740+
/* we intentionally don't strip implicit coercions here */
3741+
if (aliasvar&&IsA(aliasvar,Var))
37413742
{
37423743
returnget_variable(aliasvar,var->varlevelsup+levelsup,
37433744
istoplevel,context);
@@ -4014,6 +4015,8 @@ get_name_for_var_field(Var *var, int fieldno,
40144015
elog(ERROR,"cannot decompile join alias var in plan tree");
40154016
Assert(attnum>0&&attnum <=list_length(rte->joinaliasvars));
40164017
expr= (Node*)list_nth(rte->joinaliasvars,attnum-1);
4018+
Assert(expr!=NULL);
4019+
/* we intentionally don't strip implicit coercions here */
40174020
if (IsA(expr,Var))
40184021
returnget_name_for_var_field((Var*)expr,fieldno,
40194022
var->varlevelsup+levelsup,

‎src/include/nodes/parsenodes.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ typedef struct XmlSerialize
614614
* a stored rule might contain entries for columns dropped since the rule
615615
* was created.(This is only possible for columns not actually referenced
616616
* in the rule.) When loading a stored rule, we replace the joinaliasvars
617-
* items for any such columns withNULL Consts.(We can't simply delete
617+
* items for any such columns withnull pointers.(We can't simply delete
618618
* them from the joinaliasvars list, because that would affect the attnums
619619
* of Vars referencing the rest of the list.)
620620
*
@@ -684,13 +684,19 @@ typedef struct RangeTblEntry
684684
/*
685685
* Fields valid for a join RTE (else NULL/zero):
686686
*
687-
* joinaliasvars is a list of Vars or COALESCE expressions corresponding
688-
* to the columns of the join result. An alias Var referencing column K
689-
* of the join result can be replaced by the K'th element of joinaliasvars
690-
* --- but to simplify the task of reverse-listing aliases correctly, we
691-
* do not do that until planning time.In a Query loaded from a stored
692-
* rule, it is also possible for joinaliasvars items to be NULL Consts,
693-
* denoting columns dropped since the rule was made.
687+
* joinaliasvars is a list of (usually) Vars corresponding to the columns
688+
* of the join result.An alias Var referencing column K of the join
689+
* result can be replaced by the K'th element of joinaliasvars --- but to
690+
* simplify the task of reverse-listing aliases correctly, we do not do
691+
* that until planning time. In detail: an element of joinaliasvars can
692+
* be a Var of one of the join's input relations, or such a Var with an
693+
* implicit coercion to the join's output column type, or a COALESCE
694+
* expression containing the two input column Vars (possibly coerced).
695+
* Within a Query loaded from a stored rule, it is also possible for
696+
* joinaliasvars items to be null pointers, which are placeholders for
697+
* (necessarily unreferenced) columns dropped since the rule was made.
698+
* Also, once planning begins, joinaliasvars items can be almost anything,
699+
* as a result of subquery-flattening substitutions.
694700
*/
695701
JoinTypejointype;/* type of join */
696702
List*joinaliasvars;/* list of alias-var expansions */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp