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

Commitc61e26e

Browse files
committed
Add support for ALTER RULE ... RENAME TO.
Ali Dar, reviewed by Dean Rasheed.
1 parentf806c19 commitc61e26e

File tree

12 files changed

+322
-16
lines changed

12 files changed

+322
-16
lines changed

‎doc/src/sgml/ref/allfiles.sgml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Complete list of usable sgml source files in this directory.
2525
<!ENTITY alterOperatorClass SYSTEM "alter_opclass.sgml">
2626
<!ENTITY alterOperatorFamily SYSTEM "alter_opfamily.sgml">
2727
<!ENTITY alterRole SYSTEM "alter_role.sgml">
28+
<!ENTITY alterRule SYSTEM "alter_rule.sgml">
2829
<!ENTITY alterSchema SYSTEM "alter_schema.sgml">
2930
<!ENTITY alterServer SYSTEM "alter_server.sgml">
3031
<!ENTITY alterSequence SYSTEM "alter_sequence.sgml">

‎doc/src/sgml/ref/alter_rule.sgml

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<!--
2+
doc/src/sgml/ref/alter_rule.sgml
3+
PostgreSQL documentation
4+
-->
5+
6+
<refentry id="SQL-ALTERRULE">
7+
<refmeta>
8+
<refentrytitle>ALTER RULE</refentrytitle>
9+
<manvolnum>7</manvolnum>
10+
<refmiscinfo>SQL - Language Statements</refmiscinfo>
11+
</refmeta>
12+
13+
<refnamediv>
14+
<refname>ALTER RULE</refname>
15+
<refpurpose>change the definition of a rule</refpurpose>
16+
</refnamediv>
17+
18+
<indexterm zone="sql-alterrule">
19+
<primary>ALTER RULE</primary>
20+
</indexterm>
21+
22+
<refsynopsisdiv>
23+
<synopsis>
24+
ALTER RULE <replaceable class="PARAMETER">name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable> RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
25+
</synopsis>
26+
</refsynopsisdiv>
27+
28+
<refsect1>
29+
<title>Description</title>
30+
31+
<para>
32+
<command>ALTER RULE</command> changes properties of an existing
33+
rule. Currently, the only available action is to change the rule's name.
34+
</para>
35+
36+
<para>
37+
To use <command>ALTER RULE</command>, you must own the table or view that
38+
the rule applies to.
39+
</para>
40+
</refsect1>
41+
42+
<refsect1>
43+
<title>Parameters</title>
44+
45+
<variablelist>
46+
<varlistentry>
47+
<term><replaceable class="PARAMETER">name</replaceable></term>
48+
<listitem>
49+
<para>
50+
The name of an existing rule to alter.
51+
</para>
52+
</listitem>
53+
</varlistentry>
54+
55+
<varlistentry>
56+
<term><replaceable class="PARAMETER">table_name</replaceable></term>
57+
<listitem>
58+
<para>
59+
The name (optionally schema-qualified) of the table or view that the
60+
rule applies to.
61+
</para>
62+
</listitem>
63+
</varlistentry>
64+
65+
<varlistentry>
66+
<term><replaceable class="PARAMETER">new_name</replaceable></term>
67+
<listitem>
68+
<para>
69+
The new name for the rule.
70+
</para>
71+
</listitem>
72+
</varlistentry>
73+
</variablelist>
74+
</refsect1>
75+
76+
<refsect1>
77+
<title>Examples</title>
78+
79+
<para>
80+
To rename an existing rule:
81+
<programlisting>
82+
ALTER RULE notify_all ON emp RENAME TO notify_me;
83+
</programlisting></para>
84+
</refsect1>
85+
86+
<refsect1>
87+
<title>Compatibility</title>
88+
89+
<para>
90+
<command>ALTER RULE</command> is a
91+
<productname>PostgreSQL</productname> language extension, as is the
92+
entire query rewrite system.
93+
</para>
94+
</refsect1>
95+
96+
<refsect1>
97+
<title>See Also</title>
98+
99+
<simplelist type="inline">
100+
<member><xref linkend="sql-createrule"></member>
101+
<member><xref linkend="sql-droprule"></member>
102+
</simplelist>
103+
</refsect1>
104+
105+
</refentry>

‎doc/src/sgml/ref/create_rule.sgml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,4 +284,14 @@ UPDATE mytable SET name = 'foo' WHERE id = 42;
284284
entire query rewrite system.
285285
</para>
286286
</refsect1>
287+
288+
<refsect1>
289+
<title>See Also</title>
290+
291+
<simplelist type="inline">
292+
<member><xref linkend="sql-alterrule"></member>
293+
<member><xref linkend="sql-droprule"></member>
294+
</simplelist>
295+
</refsect1>
296+
287297
</refentry>

‎doc/src/sgml/ref/drop_rule.sgml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ DROP RULE newrule ON mytable;
103103
<title>Compatibility</title>
104104

105105
<para>
106-
There is no <command>DROP RULE</command> statement in the SQL standard.
106+
<command>DROP RULE</command> is a
107+
<productname>PostgreSQL</productname> language extension, as is the
108+
entire query rewrite system.
107109
</para>
108110
</refsect1>
109111

@@ -112,6 +114,7 @@ DROP RULE newrule ON mytable;
112114

113115
<simplelist type="inline">
114116
<member><xref linkend="sql-createrule"></member>
117+
<member><xref linkend="sql-alterrule"></member>
115118
</simplelist>
116119
</refsect1>
117120

‎doc/src/sgml/reference.sgml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
&alterOperatorClass;
5454
&alterOperatorFamily;
5555
&alterRole;
56+
&alterRule;
5657
&alterSchema;
5758
&alterSequence;
5859
&alterServer;

‎src/backend/commands/alter.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include"commands/user.h"
5252
#include"parser/parse_func.h"
5353
#include"miscadmin.h"
54+
#include"rewrite/rewriteDefine.h"
5455
#include"tcop/utility.h"
5556
#include"utils/builtins.h"
5657
#include"utils/fmgroids.h"
@@ -324,6 +325,10 @@ ExecRenameStmt(RenameStmt *stmt)
324325
caseOBJECT_ATTRIBUTE:
325326
returnrenameatt(stmt);
326327

328+
caseOBJECT_RULE:
329+
returnRenameRewriteRule(stmt->relation,stmt->subname,
330+
stmt->newname);
331+
327332
caseOBJECT_TRIGGER:
328333
returnrenametrig(stmt);
329334

‎src/backend/parser/gram.y

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7003,6 +7003,16 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
70037003
n->missing_ok =true;
70047004
$$ = (Node *)n;
70057005
}
7006+
|ALTERRULEnameONqualified_nameRENAMETOname
7007+
{
7008+
RenameStmt *n = makeNode(RenameStmt);
7009+
n->renameType = OBJECT_RULE;
7010+
n->relation =$5;
7011+
n->subname =$3;
7012+
n->newname =$8;
7013+
n->missing_ok =false;
7014+
$$ = (Node *)n;
7015+
}
70067016
|ALTERTRIGGERnameONqualified_nameRENAMETOname
70077017
{
70087018
RenameStmt *n = makeNode(RenameStmt);

‎src/backend/rewrite/rewriteDefine.c

Lines changed: 86 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -751,38 +751,99 @@ EnableDisableRule(Relation rel, const char *rulename,
751751
}
752752

753753

754+
/*
755+
* Perform permissions and integrity checks before acquiring a relation lock.
756+
*/
757+
staticvoid
758+
RangeVarCallbackForRenameRule(constRangeVar*rv,Oidrelid,Oidoldrelid,
759+
void*arg)
760+
{
761+
HeapTupletuple;
762+
Form_pg_classform;
763+
764+
tuple=SearchSysCache1(RELOID,ObjectIdGetDatum(relid));
765+
if (!HeapTupleIsValid(tuple))
766+
return;/* concurrently dropped */
767+
form= (Form_pg_class)GETSTRUCT(tuple);
768+
769+
/* only tables and views can have rules */
770+
if (form->relkind!=RELKIND_RELATION&&form->relkind!=RELKIND_VIEW)
771+
ereport(ERROR,
772+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
773+
errmsg("\"%s\" is not a table or view",rv->relname)));
774+
775+
if (!allowSystemTableMods&&IsSystemClass(form))
776+
ereport(ERROR,
777+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
778+
errmsg("permission denied: \"%s\" is a system catalog",
779+
rv->relname)));
780+
781+
/* you must own the table to rename one of its rules */
782+
if (!pg_class_ownercheck(relid,GetUserId()))
783+
aclcheck_error(ACLCHECK_NOT_OWNER,ACL_KIND_CLASS,rv->relname);
784+
785+
ReleaseSysCache(tuple);
786+
}
787+
754788
/*
755789
* Rename an existing rewrite rule.
756-
*
757-
* This is unused code at the moment. Note that it lacks a permissions check.
758790
*/
759-
#ifdefNOT_USED
760-
void
761-
RenameRewriteRule(OidowningRel,constchar*oldName,
791+
Oid
792+
RenameRewriteRule(RangeVar*relation,constchar*oldName,
762793
constchar*newName)
763794
{
795+
Oidrelid;
796+
Relationtargetrel;
764797
Relationpg_rewrite_desc;
765798
HeapTupleruletup;
799+
Form_pg_rewriteruleform;
800+
OidruleOid;
766801

802+
/*
803+
* Look up name, check permissions, and acquire lock (which we will NOT
804+
* release until end of transaction).
805+
*/
806+
relid=RangeVarGetRelidExtended(relation,AccessExclusiveLock,
807+
false, false,
808+
RangeVarCallbackForRenameRule,
809+
NULL);
810+
811+
/* Have lock already, so just need to build relcache entry. */
812+
targetrel=relation_open(relid,NoLock);
813+
814+
/* Prepare to modify pg_rewrite */
767815
pg_rewrite_desc=heap_open(RewriteRelationId,RowExclusiveLock);
768816

817+
/* Fetch the rule's entry (it had better exist) */
769818
ruletup=SearchSysCacheCopy2(RULERELNAME,
770-
ObjectIdGetDatum(owningRel),
819+
ObjectIdGetDatum(relid),
771820
PointerGetDatum(oldName));
772821
if (!HeapTupleIsValid(ruletup))
773822
ereport(ERROR,
774823
(errcode(ERRCODE_UNDEFINED_OBJECT),
775824
errmsg("rule \"%s\" for relation \"%s\" does not exist",
776-
oldName,get_rel_name(owningRel))));
825+
oldName,RelationGetRelationName(targetrel))));
826+
ruleform= (Form_pg_rewrite)GETSTRUCT(ruletup);
827+
ruleOid=HeapTupleGetOid(ruletup);
777828

778-
/* should not already exist */
779-
if (IsDefinedRewriteRule(owningRel,newName))
829+
/*rule with the new nameshould not already exist */
830+
if (IsDefinedRewriteRule(relid,newName))
780831
ereport(ERROR,
781832
(errcode(ERRCODE_DUPLICATE_OBJECT),
782833
errmsg("rule \"%s\" for relation \"%s\" already exists",
783-
newName,get_rel_name(owningRel))));
834+
newName,RelationGetRelationName(targetrel))));
835+
836+
/*
837+
* We disallow renaming ON SELECT rules, because they should always be
838+
* named "_RETURN".
839+
*/
840+
if (ruleform->ev_type==CMD_SELECT+'0')
841+
ereport(ERROR,
842+
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
843+
errmsg("renaming an ON SELECT rule is not allowed")));
784844

785-
namestrcpy(&(((Form_pg_rewrite)GETSTRUCT(ruletup))->rulename),newName);
845+
/* OK, do the update */
846+
namestrcpy(&(ruleform->rulename),newName);
786847

787848
simple_heap_update(pg_rewrite_desc,&ruletup->t_self,ruletup);
788849

@@ -791,6 +852,18 @@ RenameRewriteRule(Oid owningRel, const char *oldName,
791852

792853
heap_freetuple(ruletup);
793854
heap_close(pg_rewrite_desc,RowExclusiveLock);
794-
}
795855

796-
#endif
856+
/*
857+
* Invalidate relation's relcache entry so that other backends (and this
858+
* one too!) are sent SI message to make them rebuild relcache entries.
859+
* (Ideally this should happen automatically...)
860+
*/
861+
CacheInvalidateRelcache(targetrel);
862+
863+
/*
864+
* Close rel, but keep exclusive lock!
865+
*/
866+
relation_close(targetrel,NoLock);
867+
868+
returnruleOid;
869+
}

‎src/bin/psql/tab-complete.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,15 @@ static const SchemaQuery Query_for_list_of_views = {
624624
" (SELECT conrelid FROM pg_catalog.pg_constraint "\
625625
" WHERE pg_catalog.quote_ident(conname)='%s')"
626626

627+
/* the silly-looking length condition is just to eat up the current word */
628+
#defineQuery_for_list_of_tables_for_rule \
629+
"SELECT pg_catalog.quote_ident(relname) "\
630+
" FROM pg_catalog.pg_class"\
631+
" WHERE (%d = pg_catalog.length('%s'))"\
632+
" AND oid IN "\
633+
" (SELECT ev_class FROM pg_catalog.pg_rewrite "\
634+
" WHERE pg_catalog.quote_ident(rulename)='%s')"
635+
627636
/* the silly-looking length condition is just to eat up the current word */
628637
#defineQuery_for_list_of_tables_for_trigger \
629638
"SELECT pg_catalog.quote_ident(relname) "\
@@ -925,7 +934,7 @@ psql_completion(char *text, int start, int end)
925934
{"AGGREGATE","COLLATION","CONVERSION","DATABASE","DEFAULT PRIVILEGES","DOMAIN",
926935
"EXTENSION","FOREIGN DATA WRAPPER","FOREIGN TABLE","FUNCTION",
927936
"GROUP","INDEX","LANGUAGE","LARGE OBJECT","OPERATOR",
928-
"ROLE","SCHEMA","SERVER","SEQUENCE","TABLE",
937+
"ROLE","RULE","SCHEMA","SERVER","SEQUENCE","TABLE",
929938
"TABLESPACE","TEXT SEARCH","TRIGGER","TYPE",
930939
"USER","USER MAPPING FOR","VIEW",NULL};
931940

@@ -1259,6 +1268,26 @@ psql_completion(char *text, int start, int end)
12591268

12601269
COMPLETE_WITH_LIST(list_ALTERVIEW);
12611270
}
1271+
1272+
/* ALTER RULE <name>, add ON */
1273+
elseif (pg_strcasecmp(prev3_wd,"ALTER")==0&&
1274+
pg_strcasecmp(prev2_wd,"RULE")==0)
1275+
COMPLETE_WITH_CONST("ON");
1276+
1277+
/* If we have ALTER RULE <name> ON, then add the correct tablename */
1278+
elseif (pg_strcasecmp(prev4_wd,"ALTER")==0&&
1279+
pg_strcasecmp(prev3_wd,"RULE")==0&&
1280+
pg_strcasecmp(prev_wd,"ON")==0)
1281+
{
1282+
completion_info_charp=prev2_wd;
1283+
COMPLETE_WITH_QUERY(Query_for_list_of_tables_for_rule);
1284+
}
1285+
1286+
/* ALTER RULE <name> ON <name> */
1287+
elseif (pg_strcasecmp(prev5_wd,"ALTER")==0&&
1288+
pg_strcasecmp(prev4_wd,"RULE")==0)
1289+
COMPLETE_WITH_CONST("RENAME TO");
1290+
12621291
/* ALTER TRIGGER <name>, add ON */
12631292
elseif (pg_strcasecmp(prev3_wd,"ALTER")==0&&
12641293
pg_strcasecmp(prev2_wd,"TRIGGER")==0)

‎src/include/rewrite/rewriteDefine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extern Oid DefineQueryRewrite(char *rulename,
3232
boolreplace,
3333
List*action);
3434

35-
externvoidRenameRewriteRule(OidowningRel,constchar*oldName,
35+
externOidRenameRewriteRule(RangeVar*relation,constchar*oldName,
3636
constchar*newName);
3737

3838
externvoidsetRuleCheckAsUser(Node*node,Oiduserid);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp