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

Commit9459db8

Browse files
committed
Cause view/rule display to work as expected after rename of an underlying
table or column, or of an output column of the view itself.
1 parentd176fad commit9459db8

File tree

2 files changed

+100
-56
lines changed

2 files changed

+100
-56
lines changed

‎src/backend/parser/parse_relation.c

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.76 2002/08/0801:44:30 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.77 2002/08/0817:00:19 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1499,29 +1499,36 @@ get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum)
14991499
return"*";
15001500

15011501
/*
1502-
* If there is an alias, use it. (This path should always be taken
1503-
* for non-relation RTEs.)
1502+
* If there is a user-written column alias, use it.
15041503
*/
1505-
if (attnum>0&&attnum <=length(rte->eref->colnames))
1506-
returnstrVal(nth(attnum-1,rte->eref->colnames));
1504+
if (rte->alias&&
1505+
attnum>0&&attnum <=length(rte->alias->colnames))
1506+
returnstrVal(nth(attnum-1,rte->alias->colnames));
15071507

15081508
/*
1509-
* Can get here for a system attribute (which never has an alias), or
1510-
* if alias name list is too short (which probably can't happen
1511-
* anymore). Neither of these cases is valid for a non-relation RTE.
1509+
* If the RTE is a relation, go to the system catalogs not the
1510+
* eref->colnames list. This is a little slower but it will give
1511+
* the right answer if the column has been renamed since the eref
1512+
* list was built (which can easily happen for rules).
15121513
*/
1513-
if (rte->rtekind!=RTE_RELATION)
1514-
elog(ERROR,"Invalid attnum %d for rangetable entry %s",
1515-
attnum,rte->eref->aliasname);
1514+
if (rte->rtekind==RTE_RELATION)
1515+
{
1516+
attname=get_attname(rte->relid,attnum);
1517+
if (attname==NULL)
1518+
elog(ERROR,"cache lookup of attribute %d in relation %u failed",
1519+
attnum,rte->relid);
1520+
returnattname;
1521+
}
15161522

15171523
/*
1518-
*Usethereal nameof the table's column
1524+
*Otherwise usethecolumn namefrom eref. There should always be one.
15191525
*/
1520-
attname=get_attname(rte->relid,attnum);
1521-
if (attname==NULL)
1522-
elog(ERROR,"cache lookup of attribute %d in relation %u failed",
1523-
attnum,rte->relid);
1524-
returnattname;
1526+
if (attnum>0&&attnum <=length(rte->eref->colnames))
1527+
returnstrVal(nth(attnum-1,rte->eref->colnames));
1528+
1529+
elog(ERROR,"Invalid attnum %d for rangetable entry %s",
1530+
attnum,rte->eref->aliasname);
1531+
returnNULL;/* keep compiler quiet */
15251532
}
15261533

15271534
/*

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

Lines changed: 76 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*back to source text
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.113 2002/08/0801:44:31 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.114 2002/08/0817:00:19 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -118,15 +118,19 @@ static char *query_getviewrule = "SELECT * FROM pg_catalog.pg_rewrite WHERE ev_c
118118
statictext*pg_do_getviewdef(Oidviewoid);
119119
staticvoidmake_ruledef(StringInfobuf,HeapTupleruletup,TupleDescrulettc);
120120
staticvoidmake_viewdef(StringInfobuf,HeapTupleruletup,TupleDescrulettc);
121-
staticvoidget_query_def(Query*query,StringInfobuf,List*parentnamespace);
122-
staticvoidget_select_query_def(Query*query,deparse_context*context);
121+
staticvoidget_query_def(Query*query,StringInfobuf,List*parentnamespace,
122+
TupleDescresultDesc);
123+
staticvoidget_select_query_def(Query*query,deparse_context*context,
124+
TupleDescresultDesc);
123125
staticvoidget_insert_query_def(Query*query,deparse_context*context);
124126
staticvoidget_update_query_def(Query*query,deparse_context*context);
125127
staticvoidget_delete_query_def(Query*query,deparse_context*context);
126128
staticvoidget_utility_query_def(Query*query,deparse_context*context);
127-
staticvoidget_basic_select_query(Query*query,deparse_context*context);
129+
staticvoidget_basic_select_query(Query*query,deparse_context*context,
130+
TupleDescresultDesc);
128131
staticvoidget_setop_query(Node*setOp,Query*query,
129-
deparse_context*context);
132+
deparse_context*context,
133+
TupleDescresultDesc);
130134
staticNode*get_rule_sortgroupclause(SortClause*srt,List*tlist,
131135
boolforce_colno,
132136
deparse_context*context);
@@ -936,25 +940,22 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc)
936940
foreach(action,actions)
937941
{
938942
query= (Query*)lfirst(action);
939-
get_query_def(query,buf,NIL);
943+
get_query_def(query,buf,NIL,NULL);
940944
appendStringInfo(buf,"; ");
941945
}
942946
appendStringInfo(buf,");");
943947
}
948+
elseif (length(actions)==0)
949+
{
950+
appendStringInfo(buf,"NOTHING;");
951+
}
944952
else
945953
{
946-
if (length(actions)==0)
947-
{
948-
appendStringInfo(buf,"NOTHING;");
949-
}
950-
else
951-
{
952-
Query*query;
954+
Query*query;
953955

954-
query= (Query*)lfirst(actions);
955-
get_query_def(query,buf,NIL);
956-
appendStringInfo(buf,";");
957-
}
956+
query= (Query*)lfirst(actions);
957+
get_query_def(query,buf,NIL,NULL);
958+
appendStringInfo(buf,";");
958959
}
959960
}
960961

@@ -975,6 +976,7 @@ make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc)
975976
char*ev_qual;
976977
char*ev_action;
977978
List*actions=NIL;
979+
Relationev_relation;
978980
intfno;
979981
boolisnull;
980982

@@ -1010,25 +1012,31 @@ make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc)
10101012
query= (Query*)lfirst(actions);
10111013

10121014
if (ev_type!='1'||ev_attr >=0|| !is_instead||
1013-
strcmp(ev_qual,"<>")!=0)
1015+
strcmp(ev_qual,"<>")!=0||query->commandType!=CMD_SELECT)
10141016
{
10151017
appendStringInfo(buf,"Not a view");
10161018
return;
10171019
}
10181020

1019-
get_query_def(query,buf,NIL);
1021+
ev_relation=heap_open(ev_class,AccessShareLock);
1022+
1023+
get_query_def(query,buf,NIL,RelationGetDescr(ev_relation));
10201024
appendStringInfo(buf,";");
1025+
1026+
heap_close(ev_relation,AccessShareLock);
10211027
}
10221028

10231029

10241030
/* ----------
1025-
* get_query_def- Parse back one action from
1026-
* the parsetree in the actions
1027-
* list
1031+
* get_query_def- Parse back one query parsetree
1032+
*
1033+
* If resultDesc is not NULL, then it is the output tuple descriptor for
1034+
* the view represented by a SELECT query.
10281035
* ----------
10291036
*/
10301037
staticvoid
1031-
get_query_def(Query*query,StringInfobuf,List*parentnamespace)
1038+
get_query_def(Query*query,StringInfobuf,List*parentnamespace,
1039+
TupleDescresultDesc)
10321040
{
10331041
deparse_contextcontext;
10341042
deparse_namespacedpns;
@@ -1044,7 +1052,7 @@ get_query_def(Query *query, StringInfo buf, List *parentnamespace)
10441052
switch (query->commandType)
10451053
{
10461054
caseCMD_SELECT:
1047-
get_select_query_def(query,&context);
1055+
get_select_query_def(query,&context,resultDesc);
10481056
break;
10491057

10501058
caseCMD_UPDATE:
@@ -1080,7 +1088,8 @@ get_query_def(Query *query, StringInfo buf, List *parentnamespace)
10801088
* ----------
10811089
*/
10821090
staticvoid
1083-
get_select_query_def(Query*query,deparse_context*context)
1091+
get_select_query_def(Query*query,deparse_context*context,
1092+
TupleDescresultDesc)
10841093
{
10851094
StringInfobuf=context->buf;
10861095
boolforce_colno;
@@ -1094,13 +1103,13 @@ get_select_query_def(Query *query, deparse_context *context)
10941103
*/
10951104
if (query->setOperations)
10961105
{
1097-
get_setop_query(query->setOperations,query,context);
1106+
get_setop_query(query->setOperations,query,context,resultDesc);
10981107
/* ORDER BY clauses must be simple in this case */
10991108
force_colno= true;
11001109
}
11011110
else
11021111
{
1103-
get_basic_select_query(query,context);
1112+
get_basic_select_query(query,context,resultDesc);
11041113
force_colno= false;
11051114
}
11061115

@@ -1151,11 +1160,13 @@ get_select_query_def(Query *query, deparse_context *context)
11511160
}
11521161

11531162
staticvoid
1154-
get_basic_select_query(Query*query,deparse_context*context)
1163+
get_basic_select_query(Query*query,deparse_context*context,
1164+
TupleDescresultDesc)
11551165
{
11561166
StringInfobuf=context->buf;
11571167
char*sep;
11581168
List*l;
1169+
intcolno;
11591170

11601171
/*
11611172
* Build up the query string - first we say SELECT
@@ -1186,23 +1197,37 @@ get_basic_select_query(Query *query, deparse_context *context)
11861197

11871198
/* Then we tell what to select (the targetlist) */
11881199
sep=" ";
1200+
colno=0;
11891201
foreach(l,query->targetList)
11901202
{
11911203
TargetEntry*tle= (TargetEntry*)lfirst(l);
11921204
booltell_as= false;
1205+
char*colname;
11931206

11941207
if (tle->resdom->resjunk)
11951208
continue;/* ignore junk entries */
11961209

11971210
appendStringInfo(buf,sep);
11981211
sep=", ";
1212+
colno++;
11991213

12001214
/* Do NOT use get_tle_expr here; see its comments! */
12011215
get_rule_expr(tle->expr,context);
12021216

1217+
/*
1218+
* Figure out what the result column should be called. In the
1219+
* context of a view, use the view's tuple descriptor (so as to
1220+
* pick up the effects of any column RENAME that's been done on the
1221+
* view). Otherwise, just use what we can find in the TLE.
1222+
*/
1223+
if (resultDesc&&colno <=resultDesc->natts)
1224+
colname=NameStr(resultDesc->attrs[colno-1]->attname);
1225+
else
1226+
colname=tle->resdom->resname;
1227+
12031228
/* Check if we must say AS ... */
12041229
if (!IsA(tle->expr,Var))
1205-
tell_as= (strcmp(tle->resdom->resname,"?column?")!=0);
1230+
tell_as= (strcmp(colname,"?column?")!=0);
12061231
else
12071232
{
12081233
Var*var= (Var*) (tle->expr);
@@ -1212,13 +1237,12 @@ get_basic_select_query(Query *query, deparse_context *context)
12121237

12131238
get_names_for_var(var,context,&schemaname,&refname,&attname);
12141239
tell_as= (attname==NULL||
1215-
strcmp(attname,tle->resdom->resname)!=0);
1240+
strcmp(attname,colname)!=0);
12161241
}
12171242

12181243
/* and do if so */
12191244
if (tell_as)
1220-
appendStringInfo(buf," AS %s",
1221-
quote_identifier(tle->resdom->resname));
1245+
appendStringInfo(buf," AS %s",quote_identifier(colname));
12221246
}
12231247

12241248
/* Add the FROM clause if needed */
@@ -1256,7 +1280,8 @@ get_basic_select_query(Query *query, deparse_context *context)
12561280
}
12571281

12581282
staticvoid
1259-
get_setop_query(Node*setOp,Query*query,deparse_context*context)
1283+
get_setop_query(Node*setOp,Query*query,deparse_context*context,
1284+
TupleDescresultDesc)
12601285
{
12611286
StringInfobuf=context->buf;
12621287

@@ -1267,14 +1292,14 @@ get_setop_query(Node *setOp, Query *query, deparse_context *context)
12671292
Query*subquery=rte->subquery;
12681293

12691294
Assert(subquery!=NULL);
1270-
get_query_def(subquery,buf,context->namespaces);
1295+
get_query_def(subquery,buf,context->namespaces,resultDesc);
12711296
}
12721297
elseif (IsA(setOp,SetOperationStmt))
12731298
{
12741299
SetOperationStmt*op= (SetOperationStmt*)setOp;
12751300

12761301
appendStringInfo(buf,"((");
1277-
get_setop_query(op->larg,query,context);
1302+
get_setop_query(op->larg,query,context,resultDesc);
12781303
switch (op->op)
12791304
{
12801305
caseSETOP_UNION:
@@ -1294,7 +1319,7 @@ get_setop_query(Node *setOp, Query *query, deparse_context *context)
12941319
appendStringInfo(buf,"ALL (");
12951320
else
12961321
appendStringInfo(buf,"(");
1297-
get_setop_query(op->rarg,query,context);
1322+
get_setop_query(op->rarg,query,context,resultDesc);
12981323
appendStringInfo(buf,"))");
12991324
}
13001325
else
@@ -1405,7 +1430,7 @@ get_insert_query_def(Query *query, deparse_context *context)
14051430
appendStringInfoChar(buf,')');
14061431
}
14071432
else
1408-
get_query_def(select_rte->subquery,buf,NIL);
1433+
get_query_def(select_rte->subquery,buf,NIL,NULL);
14091434
}
14101435

14111436

@@ -2418,7 +2443,7 @@ get_sublink_expr(Node *node, deparse_context *context)
24182443
if (need_paren)
24192444
appendStringInfoChar(buf,'(');
24202445

2421-
get_query_def(query,buf,context->namespaces);
2446+
get_query_def(query,buf,context->namespaces,NULL);
24222447

24232448
if (need_paren)
24242449
appendStringInfo(buf,"))");
@@ -2491,7 +2516,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
24912516
caseRTE_SUBQUERY:
24922517
/* Subquery RTE */
24932518
appendStringInfoChar(buf,'(');
2494-
get_query_def(rte->subquery,buf,context->namespaces);
2519+
get_query_def(rte->subquery,buf,context->namespaces,NULL);
24952520
appendStringInfoChar(buf,')');
24962521
break;
24972522
caseRTE_FUNCTION:
@@ -2521,6 +2546,18 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
25212546
appendStringInfoChar(buf,')');
25222547
}
25232548
}
2549+
elseif (rte->rtekind==RTE_RELATION&&
2550+
strcmp(rte->eref->aliasname,get_rel_name(rte->relid))!=0)
2551+
{
2552+
/*
2553+
* Apparently the rel has been renamed since the rule was made.
2554+
* Emit a fake alias clause so that variable references will
2555+
* still work. This is not a 100% solution but should work in
2556+
* most reasonable situations.
2557+
*/
2558+
appendStringInfo(buf," %s",
2559+
quote_identifier(rte->eref->aliasname));
2560+
}
25242561
}
25252562
elseif (IsA(jtnode,JoinExpr))
25262563
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp