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

Commit248c67d

Browse files
committed
CREATE OR REPLACE VIEW, CREATE OR REPLACE RULE.
Gavin Sherry, Neil Conway, and Tom Lane all got their hands dirtyon this one ...
1 parentc7a165a commit248c67d

File tree

12 files changed

+290
-70
lines changed

12 files changed

+290
-70
lines changed

‎src/backend/commands/view.c

Lines changed: 86 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,43 +6,43 @@
66
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
9-
*$Id: view.c,v 1.68 2002/08/30 19:23:19 tgl Exp $
9+
*
10+
* IDENTIFICATION
11+
* $Header: /cvsroot/pgsql/src/backend/commands/view.c,v 1.69 2002/09/02 02:13:01 tgl Exp $
1012
*
1113
*-------------------------------------------------------------------------
1214
*/
1315
#include"postgres.h"
1416

15-
#include"access/xact.h"
17+
#include"access/heapam.h"
1618
#include"catalog/dependency.h"
17-
#include"catalog/heap.h"
1819
#include"catalog/namespace.h"
1920
#include"commands/tablecmds.h"
2021
#include"commands/view.h"
2122
#include"miscadmin.h"
2223
#include"nodes/makefuncs.h"
2324
#include"parser/parse_relation.h"
24-
#include"parser/parse_type.h"
2525
#include"rewrite/rewriteDefine.h"
2626
#include"rewrite/rewriteManip.h"
27-
#include"rewrite/rewriteRemove.h"
2827
#include"rewrite/rewriteSupport.h"
29-
#include"utils/syscache.h"
28+
#include"utils/acl.h"
29+
#include"utils/lsyscache.h"
3030

3131

3232
/*---------------------------------------------------------------------
3333
* DefineVirtualRelation
3434
*
35-
* Create the "view" relation.
36-
* `DefineRelation' does all the work, we just provide the correct
37-
* arguments!
38-
*
39-
* If the relation already exists, then 'DefineRelation' will abort
40-
* the xact...
35+
* Create the "view" relation. `DefineRelation' does all the work,
36+
* we just provide the correct arguments ... at least when we're
37+
* creating a view. If we're updating an existing view, we have to
38+
* work harder.
4139
*---------------------------------------------------------------------
4240
*/
4341
staticOid
44-
DefineVirtualRelation(constRangeVar*relation,List*tlist)
42+
DefineVirtualRelation(constRangeVar*relation,List*tlist,boolreplace)
4543
{
44+
OidviewOid,
45+
namespaceId;
4646
CreateStmt*createStmt=makeNode(CreateStmt);
4747
List*attrList,
4848
*t;
@@ -52,7 +52,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist)
5252
* the (non-junk) targetlist items from the view's SELECT list.
5353
*/
5454
attrList=NIL;
55-
foreach(t,tlist)
55+
foreach(t,tlist)
5656
{
5757
TargetEntry*entry=lfirst(t);
5858
Resdom*res=entry->resdom;
@@ -83,23 +83,74 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist)
8383
elog(ERROR,"attempted to define virtual relation with no attrs");
8484

8585
/*
86-
* now create the parameters for keys/inheritance etc. All of them are
87-
* nil...
86+
* Check to see if we want to replace an existing view.
8887
*/
89-
createStmt->relation= (RangeVar*)relation;
90-
createStmt->tableElts=attrList;
91-
createStmt->inhRelations=NIL;
92-
createStmt->constraints=NIL;
93-
createStmt->hasoids= false;
88+
namespaceId=RangeVarGetCreationNamespace(relation);
89+
viewOid=get_relname_relid(relation->relname,namespaceId);
9490

95-
/*
96-
* finally create the relation...
97-
*/
98-
returnDefineRelation(createStmt,RELKIND_VIEW);
91+
if (OidIsValid(viewOid)&&replace)
92+
{
93+
Relationrel;
94+
TupleDescdescriptor;
95+
96+
/*
97+
* Yes. Get exclusive lock on the existing view ...
98+
*/
99+
rel=relation_open(viewOid,AccessExclusiveLock);
100+
101+
/*
102+
* Make sure it *is* a view, and do permissions checks.
103+
*/
104+
if (rel->rd_rel->relkind!=RELKIND_VIEW)
105+
elog(ERROR,"%s is not a view",
106+
RelationGetRelationName(rel));
107+
108+
if (!pg_class_ownercheck(viewOid,GetUserId()))
109+
aclcheck_error(ACLCHECK_NOT_OWNER,RelationGetRelationName(rel));
110+
111+
/*
112+
* Create a tuple descriptor to compare against the existing view,
113+
* and verify it matches.
114+
*
115+
* XXX the error message is a bit cheesy here: would be useful to
116+
* give a more specific complaint about the difference in the
117+
* descriptors. No time for it at the moment though.
118+
*/
119+
descriptor=BuildDescForRelation(attrList);
120+
if (!equalTupleDescs(descriptor,rel->rd_att))
121+
elog(ERROR,"Cannot change column set of existing view %s",
122+
RelationGetRelationName(rel));
123+
124+
/*
125+
* Seems okay, so return the OID of the pre-existing view.
126+
*/
127+
relation_close(rel,NoLock);/* keep the lock! */
128+
129+
returnviewOid;
130+
}
131+
else
132+
{
133+
/*
134+
* now create the parameters for keys/inheritance etc. All of them are
135+
* nil...
136+
*/
137+
createStmt->relation= (RangeVar*)relation;
138+
createStmt->tableElts=attrList;
139+
createStmt->inhRelations=NIL;
140+
createStmt->constraints=NIL;
141+
createStmt->hasoids= false;
142+
143+
/*
144+
* finally create the relation (this will error out if there's
145+
* an existing view, so we don't need more code to complain
146+
* if "replace" is false).
147+
*/
148+
returnDefineRelation(createStmt,RELKIND_VIEW);
149+
}
99150
}
100151

101152
staticRuleStmt*
102-
FormViewRetrieveRule(constRangeVar*view,Query*viewParse)
153+
FormViewRetrieveRule(constRangeVar*view,Query*viewParse,boolreplace)
103154
{
104155
RuleStmt*rule;
105156

@@ -114,12 +165,13 @@ FormViewRetrieveRule(const RangeVar *view, Query *viewParse)
114165
rule->event=CMD_SELECT;
115166
rule->instead= true;
116167
rule->actions=makeList1(viewParse);
168+
rule->replace=replace;
117169

118170
returnrule;
119171
}
120172

121173
staticvoid
122-
DefineViewRules(constRangeVar*view,Query*viewParse)
174+
DefineViewRules(constRangeVar*view,Query*viewParse,boolreplace)
123175
{
124176
RuleStmt*retrieve_rule;
125177

@@ -129,10 +181,9 @@ DefineViewRules(const RangeVar *view, Query *viewParse)
129181
RuleStmt*delete_rule;
130182
#endif
131183

132-
retrieve_rule=FormViewRetrieveRule(view,viewParse);
184+
retrieve_rule=FormViewRetrieveRule(view,viewParse,replace);
133185

134186
#ifdefNOTYET
135-
136187
replace_rule=FormViewReplaceRule(view,viewParse);
137188
append_rule=FormViewAppendRule(view,viewParse);
138189
delete_rule=FormViewDeleteRule(view,viewParse);
@@ -221,16 +272,18 @@ UpdateRangeTableOfViewParse(Oid viewOid, Query *viewParse)
221272
*-------------------------------------------------------------------
222273
*/
223274
void
224-
DefineView(constRangeVar*view,Query*viewParse)
275+
DefineView(constRangeVar*view,Query*viewParse,boolreplace)
225276
{
226277
OidviewOid;
227278

228279
/*
229280
* Create the view relation
230281
*
231-
* NOTE: if it already exists, the xact will be aborted.
282+
* NOTE: if it already exists and replace is false, the xact will
283+
* be aborted.
232284
*/
233-
viewOid=DefineVirtualRelation(view,viewParse->targetList);
285+
286+
viewOid=DefineVirtualRelation(view,viewParse->targetList,replace);
234287

235288
/*
236289
* The relation we have just created is not visible to any other
@@ -248,7 +301,7 @@ DefineView(const RangeVar *view, Query *viewParse)
248301
/*
249302
* Now create the rules associated with the view.
250303
*/
251-
DefineViewRules(view,viewParse);
304+
DefineViewRules(view,viewParse,replace);
252305
}
253306

254307
/*

‎src/backend/nodes/copyfuncs.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.209 2002/08/31 22:10:43 tgl Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.210 2002/09/02 02:13:01 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -2173,6 +2173,7 @@ _copyRuleStmt(RuleStmt *from)
21732173
Node_Copy(from,newnode,whereClause);
21742174
newnode->event=from->event;
21752175
newnode->instead=from->instead;
2176+
newnode->replace=from->replace;
21762177
Node_Copy(from,newnode,actions);
21772178

21782179
returnnewnode;
@@ -2238,6 +2239,7 @@ _copyViewStmt(ViewStmt *from)
22382239
Node_Copy(from,newnode,view);
22392240
Node_Copy(from,newnode,aliases);
22402241
Node_Copy(from,newnode,query);
2242+
newnode->replace=from->replace;
22412243

22422244
returnnewnode;
22432245
}

‎src/backend/nodes/equalfuncs.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* Portions Copyright (c) 1994, Regents of the University of California
2121
*
2222
* IDENTIFICATION
23-
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.157 2002/08/31 22:10:43 tgl Exp $
23+
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.158 2002/09/02 02:13:01 tgl Exp $
2424
*
2525
*-------------------------------------------------------------------------
2626
*/
@@ -1003,6 +1003,8 @@ _equalRuleStmt(RuleStmt *a, RuleStmt *b)
10031003
return false;
10041004
if (a->instead!=b->instead)
10051005
return false;
1006+
if (a->replace!=b->replace)
1007+
return false;
10061008
if (!equal(a->actions,b->actions))
10071009
return false;
10081010

@@ -1067,6 +1069,8 @@ _equalViewStmt(ViewStmt *a, ViewStmt *b)
10671069
return false;
10681070
if (!equal(a->query,b->query))
10691071
return false;
1072+
if (a->replace!=b->replace)
1073+
return false;
10701074

10711075
return true;
10721076
}

‎src/backend/parser/gram.y

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.364 2002/08/29 00:17:04 tgl Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.365 2002/09/02 02:13:01 tgl Exp $
1515
*
1616
* HISTORY
1717
* AUTHORDATEMAJOR EVENT
@@ -3346,18 +3346,19 @@ opt_column: COLUMN{ $$ = COLUMN; }
33463346
*
33473347
*****************************************************************************/
33483348

3349-
RuleStmt:CREATE RULE name AS
3349+
RuleStmt:CREATEopt_or_replaceRULE name AS
33503350
{ QueryIsRule=TRUE; }
33513351
ON event TO qualified_name where_clause
33523352
DO opt_instead RuleActionList
33533353
{
33543354
RuleStmt *n = makeNode(RuleStmt);
3355-
n->relation =$9;
3356-
n->rulename =$3;
3357-
n->whereClause =$10;
3358-
n->event =$7;
3359-
n->instead =$12;
3360-
n->actions =$13;
3355+
n->replace =$2;
3356+
n->relation =$10;
3357+
n->rulename =$4;
3358+
n->whereClause =$11;
3359+
n->event =$8;
3360+
n->instead =$13;
3361+
n->actions =$14;
33613362
$$ = (Node *)n;
33623363
QueryIsRule=FALSE;
33633364
}
@@ -3537,12 +3538,14 @@ opt_trans:WORK{}
35373538
*
35383539
*****************************************************************************/
35393540

3540-
ViewStmt:CREATE VIEW qualified_name opt_column_list AS SelectStmt
3541+
ViewStmt:CREATE opt_or_replace VIEW qualified_name opt_column_list
3542+
AS SelectStmt
35413543
{
35423544
ViewStmt *n = makeNode(ViewStmt);
3543-
n->view =$3;
3544-
n->aliases =$4;
3545-
n->query = (Query *)$6;
3545+
n->replace =$2;
3546+
n->view =$4;
3547+
n->aliases =$5;
3548+
n->query = (Query *)$7;
35463549
$$ = (Node *)n;
35473550
}
35483551
;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp