Re: missing rename support

Started by Ali Darabout 13 years ago8 messages
#1Ali Dar
ali.munir.dar@gmail.com
1 attachment(s)

On Sat, Dec 3, 2011 at 4:46 PM, Peter Eisentraut <peter_e(at)gmx(dot)net> wrote:

I noticed the following object types don't have support for an ALTER ...
RENAME command:

DOMAIN (but ALTER TYPE works)
FOREIGN DATA WRAPPER
OPERATOR
RULE
SERVER

Are there any restrictions why these couldn't be added?

I don't think so. There's no ALTER RULE command; should we add one

(matching ALTER TRIGGER) or make this part of ALTER TABLE? I don't
think constraints can be renamed either, which should probably be
addressed along with rules.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

Find attached an initial patch for ALTER RENAME RULE feature. Please
note that it does not have any documentation yet.

Attachments:

Alter_Rule_Rename.patchapplication/octet-stream; name=Alter_Rule_Rename.patchDownload
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index 9e271c3..85703b6 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -107,6 +107,10 @@ ExecRenameStmt(RenameStmt *stmt)
 			RenameRole(stmt->subname, stmt->newname);
 			break;
 
+		case OBJECT_RULE:
+			RenameRewriteRule(stmt->relation, stmt->subname, stmt->newname);
+			break;
+
 		case OBJECT_SCHEMA:
 			RenameSchema(stmt->subname, stmt->newname);
 			break;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index ad98b36..e993c5a 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -7028,6 +7028,16 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
 					n->missing_ok = false;
 					$$ = (Node *)n;
 				}
+			| ALTER RULE name ON any_name RENAME TO name
+				{
+					RenameStmt *n = makeNode(RenameStmt);
+					n->renameType = OBJECT_RULE;
+					n->relation = makeRangeVarFromAnyName($5, @5, yyscanner);
+					n->subname = $3;
+					n->newname = $8;
+					n->missing_ok = false;
+					$$ = (Node *)n;
+				}
 			| ALTER USER RoleId RENAME TO RoleId
 				{
 					RenameStmt *n = makeNode(RenameStmt);
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index 55b0fed..d8d0dd6 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -750,35 +750,55 @@ EnableDisableRule(Relation rel, const char *rulename,
 
 /*
  * Rename an existing rewrite rule.
- *
- * This is unused code at the moment.  Note that it lacks a permissions check.
  */
-#ifdef NOT_USED
 void
-RenameRewriteRule(Oid owningRel, const char *oldName,
+RenameRewriteRule(RangeVar* relation, const char *oldName,
 				  const char *newName)
 {
 	Relation	pg_rewrite_desc;
 	HeapTuple	ruletup;
+	Oid owningRel;
+
+	owningRel = RangeVarGetRelid(relation, AccessExclusiveLock, false);
+
+	/*
+	 * check if user has permission to rename rule on this relation.
+	 */
+	if (!pg_class_ownercheck(owningRel, GetUserId()))
+		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
+					   get_rel_name(owningRel));
 
 	pg_rewrite_desc = heap_open(RewriteRelationId, RowExclusiveLock);
 
 	ruletup = SearchSysCacheCopy2(RULERELNAME,
 								  ObjectIdGetDatum(owningRel),
 								  PointerGetDatum(oldName));
+
+	/* old rule should already exist */
 	if (!HeapTupleIsValid(ruletup))
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("rule \"%s\" for relation \"%s\" does not exist",
 						oldName, get_rel_name(owningRel))));
 
-	/* should not already exist */
+	/* rule with the new name should not already exist */
 	if (IsDefinedRewriteRule(owningRel, newName))
 		ereport(ERROR,
 				(errcode(ERRCODE_DUPLICATE_OBJECT),
 				 errmsg("rule \"%s\" for relation \"%s\" already exists",
 						newName, get_rel_name(owningRel))));
 
+	/* ON SELECT rule must always be named "_RETURN" */
+	if (((Form_pg_rewrite) GETSTRUCT(ruletup))->ev_type - '0' == CMD_SELECT)
+	{
+		if (strcmp(newName, ViewSelectRuleName) != 0)
+			ereport(ERROR,
+			(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+				errmsg("view rule for \"%s\" must be named \"%s\"",
+					get_rel_name(owningRel),
+					ViewSelectRuleName)));
+	}
+
 	namestrcpy(&(((Form_pg_rewrite) GETSTRUCT(ruletup))->rulename), newName);
 
 	simple_heap_update(pg_rewrite_desc, &ruletup->t_self, ruletup);
@@ -789,5 +809,3 @@ RenameRewriteRule(Oid owningRel, const char *oldName,
 	heap_freetuple(ruletup);
 	heap_close(pg_rewrite_desc, RowExclusiveLock);
 }
-
-#endif
diff --git a/src/include/rewrite/rewriteDefine.h b/src/include/rewrite/rewriteDefine.h
index 6061725..d7e0def 100644
--- a/src/include/rewrite/rewriteDefine.h
+++ b/src/include/rewrite/rewriteDefine.h
@@ -32,7 +32,7 @@ extern void DefineQueryRewrite(char *rulename,
 				   bool replace,
 				   List *action);
 
-extern void RenameRewriteRule(Oid owningRel, const char *oldName,
+extern void RenameRewriteRule(RangeVar* relation, const char *oldName,
 				  const char *newName);
 
 extern void setRuleCheckAsUser(Node *node, Oid userid);
#2Stephen Frost
sfrost@snowman.net
In reply to: Ali Dar (#1)

* Ali Dar (ali.munir.dar@gmail.com) wrote:

Find attached an initial patch for ALTER RENAME RULE feature. Please
note that it does not have any documentation yet.

Just took a quick look through this. Seems to be alright, but why do we
allow renaming ON SELECT rules at all, given that they must be named
_RETURN? My thinking would be to check for that case and error out if
someone tries it.

You should try to keep variables lined up:

Relation pg_rewrite_desc;
HeapTuple ruletup;
+ Oid owningRel;

should be:

Relation pg_rewrite_desc;
HeapTuple ruletup;
+ Oid owningRel;

I'd also strongly recommend looking through that entire function very
carefully. Code that's been #ifdef'd out tends to rot.

Thanks,

Stephen

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Stephen Frost (#2)

Stephen Frost <sfrost@snowman.net> writes:

* Ali Dar (ali.munir.dar@gmail.com) wrote:

Find attached an initial patch for ALTER RENAME RULE feature. Please
note that it does not have any documentation yet.

Just took a quick look through this. Seems to be alright, but why do we
allow renaming ON SELECT rules at all, given that they must be named
_RETURN? My thinking would be to check for that case and error out if
someone tries it.

Agreed, we should exclude ON SELECT rules.

You should try to keep variables lined up:

pgindent is probably a better answer than trying to get this right
manually.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#4Dean Rasheed
dean.a.rasheed@gmail.com
In reply to: Ali Dar (#1)

On 3 January 2013 13:49, Ali Dar <ali.munir.dar@gmail.com> wrote:

Find attached an initial patch for ALTER RENAME RULE feature. Please note
that it does not have any documentation yet.

Hi,

I just got round to looking at this. All-in-all it looks OK. I just
have a few more review comments, in addition to Stephen's comment
about renaming SELECT rules...

This compiler warning should be fixed with another #include:
alter.c:107:4: warning: implicit declaration of function ‘RenameRewriteRule’

In gram.y, I think you can just use qualified_name instead of
makeRangeVarFromAnyName().

In RenameRewriteRule(), I think it's worth doing a check to ensure
that the relation actually is a table or a view (you might have some
other relation kind at that point in the code). If the user
accidentally types the name of an index, say, instead of a table, then
it is better to throw an error saying "xxx is not a table or a view"
rather than reporting that the rule doesn't exist.

I think this could probably use some simple regression tests to test
both the success and failure cases.

It would be nice to extend psql tab completion to support this too,
although perhaps that could be done as a separate patch.

Don't forget the docs!

Regards,
Dean

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#5Ali Dar
ali.munir.dar@gmail.com
In reply to: Dean Rasheed (#4)
1 attachment(s)

Please find attached the complete patch for alter rename rule. I have
followed all the suggestions. Followings things are added in this updated
patch:
1) Disallow alter rename of ON SELECT rules.
2) Remove warning.
3) Varibles are lined up.
4) Used qualified_name instead of makeRangeVarFromAnyName.
5) Throw appropriate error if user tries to alter rename rule on irrelavent
object(e.g index).
6) Psql tab support added
7) Regression test cases added.
8) Documentation added.

Regards,
Ali Dar

On Mon, Jan 21, 2013 at 12:34 AM, Dean Rasheed <dean.a.rasheed@gmail.com>wrote:

Show quoted text

On 3 January 2013 13:49, Ali Dar <ali.munir.dar@gmail.com> wrote:

Find attached an initial patch for ALTER RENAME RULE feature. Please note
that it does not have any documentation yet.

Hi,

I just got round to looking at this. All-in-all it looks OK. I just
have a few more review comments, in addition to Stephen's comment
about renaming SELECT rules...

This compiler warning should be fixed with another #include:
alter.c:107:4: warning: implicit declaration of function
‘RenameRewriteRule’

In gram.y, I think you can just use qualified_name instead of
makeRangeVarFromAnyName().

In RenameRewriteRule(), I think it's worth doing a check to ensure
that the relation actually is a table or a view (you might have some
other relation kind at that point in the code). If the user
accidentally types the name of an index, say, instead of a table, then
it is better to throw an error saying "xxx is not a table or a view"
rather than reporting that the rule doesn't exist.

I think this could probably use some simple regression tests to test
both the success and failure cases.

It would be nice to extend psql tab completion to support this too,
although perhaps that could be done as a separate patch.

Don't forget the docs!

Regards,
Dean

Attachments:

alter-rule-rename_complete.patchapplication/octet-stream; name=alter-rule-rename_complete.patchDownload
diff --git a/doc/src/sgml/ref/allfiles.sgml b/doc/src/sgml/ref/allfiles.sgml
index b3fc57d..c61c62f 100644
--- a/doc/src/sgml/ref/allfiles.sgml
+++ b/doc/src/sgml/ref/allfiles.sgml
@@ -25,6 +25,7 @@ Complete list of usable sgml source files in this directory.
 <!ENTITY alterOperatorClass SYSTEM "alter_opclass.sgml">
 <!ENTITY alterOperatorFamily SYSTEM "alter_opfamily.sgml">
 <!ENTITY alterRole          SYSTEM "alter_role.sgml">
+<!ENTITY alterRule          SYSTEM "alter_rule.sgml">
 <!ENTITY alterSchema        SYSTEM "alter_schema.sgml">
 <!ENTITY alterServer        SYSTEM "alter_server.sgml">
 <!ENTITY alterSequence      SYSTEM "alter_sequence.sgml">
diff --git a/doc/src/sgml/ref/create_rule.sgml b/doc/src/sgml/ref/create_rule.sgml
index 381ea3e..7e36aef 100644
--- a/doc/src/sgml/ref/create_rule.sgml
+++ b/doc/src/sgml/ref/create_rule.sgml
@@ -284,4 +284,12 @@ UPDATE mytable SET name = 'foo' WHERE id = 42;
    entire query rewrite system.
   </para>
  </refsect1>
+
+  <refsect1>
+  <title>See Also</title>
+
+  <simplelist type="inline">
+   <member><xref linkend="sql-alterrule"></member>
+  </simplelist>
+ </refsect1>
 </refentry>
diff --git a/doc/src/sgml/reference.sgml b/doc/src/sgml/reference.sgml
index fe90227..5b0c774 100644
--- a/doc/src/sgml/reference.sgml
+++ b/doc/src/sgml/reference.sgml
@@ -53,6 +53,7 @@
    &alterOperatorClass;
    &alterOperatorFamily;
    &alterRole;
+   &alterRule;
    &alterSchema;
    &alterSequence;
    &alterServer;
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index c2d4bb3..3cc6e9a 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -51,6 +51,7 @@
 #include "commands/user.h"
 #include "parser/parse_func.h"
 #include "miscadmin.h"
+#include "rewrite/rewriteDefine.h"
 #include "tcop/utility.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
@@ -307,6 +308,9 @@ ExecRenameStmt(RenameStmt *stmt)
 		case OBJECT_ROLE:
 			return RenameRole(stmt->subname, stmt->newname);
 
+		case OBJECT_RULE:
+			return RenameRewriteRule(stmt->relation, stmt->subname, stmt->newname);
+
 		case OBJECT_SCHEMA:
 			return RenameSchema(stmt->subname, stmt->newname);
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 828e110..33ac554 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -7029,6 +7029,16 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
 					n->missing_ok = false;
 					$$ = (Node *)n;
 				}
+			| ALTER RULE name ON qualified_name RENAME TO name
+				{
+					RenameStmt *n = makeNode(RenameStmt);
+					n->renameType = OBJECT_RULE;
+					n->relation = $5;
+					n->subname = $3;
+					n->newname = $8;
+					n->missing_ok = false;
+					$$ = (Node *)n;
+				}
 			| ALTER USER RoleId RENAME TO RoleId
 				{
 					RenameStmt *n = makeNode(RenameStmt);
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index ac724c3..dbdad19 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -753,35 +753,69 @@ EnableDisableRule(Relation rel, const char *rulename,
 
 /*
  * Rename an existing rewrite rule.
- *
- * This is unused code at the moment.  Note that it lacks a permissions check.
  */
-#ifdef NOT_USED
-void
-RenameRewriteRule(Oid owningRel, const char *oldName,
+Oid
+RenameRewriteRule(RangeVar* relation, const char *oldName,
 				  const char *newName)
 {
 	Relation	pg_rewrite_desc;
 	HeapTuple	ruletup;
+	Oid 		owningRel;
+	char		owningRelKind;
+	Oid 		ruleOid = InvalidOid;
+
+	owningRel = RangeVarGetRelid(relation, AccessExclusiveLock, false);
+
+	owningRelKind = get_rel_relkind(owningRel);
+
+	/*
+	 * verify relation is of a type that rules can be applied to
+	 */
+	if (owningRelKind != RELKIND_RELATION &&
+		owningRelKind != RELKIND_VIEW)
+		ereport(ERROR,
+				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
+				 errmsg("\"%s\" is not a table or view",
+						get_rel_name(owningRel))));
+
+	/*
+	 * check if user has permission to rename rule on this relation
+	 */
+	if (!pg_class_ownercheck(owningRel, GetUserId()))
+		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
+					   get_rel_name(owningRel));
 
 	pg_rewrite_desc = heap_open(RewriteRelationId, RowExclusiveLock);
 
 	ruletup = SearchSysCacheCopy2(RULERELNAME,
 								  ObjectIdGetDatum(owningRel),
 								  PointerGetDatum(oldName));
+
+	/* old rule should already exist */
 	if (!HeapTupleIsValid(ruletup))
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("rule \"%s\" for relation \"%s\" does not exist",
 						oldName, get_rel_name(owningRel))));
 
-	/* should not already exist */
+	ruleOid = HeapTupleGetOid(ruletup);
+
+	/* rule with the new name should not already exist */
 	if (IsDefinedRewriteRule(owningRel, newName))
 		ereport(ERROR,
 				(errcode(ERRCODE_DUPLICATE_OBJECT),
 				 errmsg("rule \"%s\" for relation \"%s\" already exists",
 						newName, get_rel_name(owningRel))));
 
+	/*
+	 * rename is not allowed for ON SELECT rule, because it's always
+	 * named "_RETURN".
+	 */
+	if (((Form_pg_rewrite) GETSTRUCT(ruletup))->ev_type - '0' == CMD_SELECT)
+		ereport(ERROR,
+		(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+			errmsg("rename not allowed for ON SELECT rule")));
+
 	namestrcpy(&(((Form_pg_rewrite) GETSTRUCT(ruletup))->rulename), newName);
 
 	simple_heap_update(pg_rewrite_desc, &ruletup->t_self, ruletup);
@@ -791,6 +825,6 @@ RenameRewriteRule(Oid owningRel, const char *oldName,
 
 	heap_freetuple(ruletup);
 	heap_close(pg_rewrite_desc, RowExclusiveLock);
-}
 
-#endif
+	return ruleOid;
+}
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index f7d8466..0dbb669 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -925,7 +925,7 @@ psql_completion(char *text, int start, int end)
 		{"AGGREGATE", "COLLATION", "CONVERSION", "DATABASE", "DEFAULT PRIVILEGES", "DOMAIN",
 			"EXTENSION", "FOREIGN DATA WRAPPER", "FOREIGN TABLE", "FUNCTION",
 			"GROUP", "INDEX", "LANGUAGE", "LARGE OBJECT", "OPERATOR",
-			"ROLE", "SCHEMA", "SERVER", "SEQUENCE", "TABLE",
+			"ROLE", "RULE", "SCHEMA", "SERVER", "SEQUENCE", "TABLE",
 			"TABLESPACE", "TEXT SEARCH", "TRIGGER", "TYPE",
 		"USER", "USER MAPPING FOR", "VIEW", NULL};
 
@@ -1681,6 +1681,22 @@ psql_completion(char *text, int start, int end)
 			 pg_strcasecmp(prev_wd, "USER") == 0)
 		COMPLETE_WITH_QUERY(Query_for_list_of_roles);
 
+	/* ALTER RULE <name> */
+	else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
+			 pg_strcasecmp(prev2_wd, "RULE") == 0)
+		COMPLETE_WITH_CONST("ON");
+
+	/* ALTER RULE <name> ON <name>*/
+	else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
+			 pg_strcasecmp(prev4_wd, "RULE") == 0)
+		COMPLETE_WITH_CONST("RENAME TO");
+
+	/* If we have ALTER RULE <name> ON, then add the correct viewname */
+	else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
+			 pg_strcasecmp(prev3_wd, "RULE") == 0 &&
+			 pg_strcasecmp(prev_wd, "ON") == 0)
+		COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_views, NULL);
+
 /* BEGIN, END, ABORT */
 	else if (pg_strcasecmp(prev_wd, "BEGIN") == 0 ||
 			 pg_strcasecmp(prev_wd, "END") == 0 ||
diff --git a/src/include/rewrite/rewriteDefine.h b/src/include/rewrite/rewriteDefine.h
index dda267b..72921c3 100644
--- a/src/include/rewrite/rewriteDefine.h
+++ b/src/include/rewrite/rewriteDefine.h
@@ -32,7 +32,7 @@ extern Oid DefineQueryRewrite(char *rulename,
 				   bool replace,
 				   List *action);
 
-extern void RenameRewriteRule(Oid owningRel, const char *oldName,
+extern Oid RenameRewriteRule(RangeVar* relation, const char *oldName,
 				  const char *newName);
 
 extern void setRuleCheckAsUser(Node *node, Oid userid);
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index a235571..7e79815 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1693,3 +1693,42 @@ Rules:
     ON UPDATE TO rules_src DO  VALUES (old.f1,old.f2,'old'::text), (new.f1,new.f2,'new'::text)
 Has OIDs: no
 
+--
+-- check alter rename rule
+--
+CREATE TABLE rule_t1 (a INT);
+CREATE TABLE rule_t2 (a INT);
+CREATE RULE "_RETURN" AS
+    ON SELECT TO rule_t1
+    DO INSTEAD
+        SELECT * FROM rule_t2;
+CREATE RULE InsertRule AS
+    ON INSERT TO rule_t1
+    DO INSTEAD
+        INSERT INTO rule_t2 VALUES(new.a);
+ALTER RULE InsertRule ON rule_t1 RENAME to NewInsertRule;
+INSERT INTO rule_t1 VALUES(1);
+SELECT * FROM rule_t1;
+ a 
+---
+ 1
+(1 row)
+
+--
+-- error conditions for alter rename rule
+--
+ALTER RULE NewInsertRule ON rule_t1 RENAME TO "_RETURN"; -- rule already exists error
+ERROR:  rule "_RETURN" for relation "rule_t1" already exists
+ALTER RULE "_RETURN" ON rule_t1 RENAME TO abc; -- ON SELECT rule can not be renamed error
+ERROR:  rename not allowed for ON SELECT rule
+ALTER RULE InsertRule ON rule_t1 RENAME TO NewInsertRule; -- NO rule exists error
+ERROR:  rule "insertrule" for relation "rule_t1" does not exist
+ALTER RULE NewInsertRule ON notable RENAME TO InsertRule; -- table does not exist error
+ERROR:  relation "notable" does not exist
+CREATE TYPE item1 as();
+ALTER RULE InsertRule ON item1 RENAME to NewInsertRule; -- target item should be view or table
+ERROR:  "item1" is not a table or view
+DROP RULE NewInsertRule ON rule_t1; -- drop altered rule
+DROP TYPE item1;
+DROP VIEW rule_t1;
+DROP TABLE rule_t2;
diff --git a/src/test/regress/sql/rules.sql b/src/test/regress/sql/rules.sql
index 458c2f0..abdd763 100644
--- a/src/test/regress/sql/rules.sql
+++ b/src/test/regress/sql/rules.sql
@@ -968,3 +968,40 @@ update rules_src set f2 = f2 / 10;
 select * from rules_src;
 select * from rules_log;
 \d+ rules_src
+
+
+--
+-- check alter rename rule
+--
+CREATE TABLE rule_t1 (a INT);
+CREATE TABLE rule_t2 (a INT);
+
+CREATE RULE "_RETURN" AS
+    ON SELECT TO rule_t1
+    DO INSTEAD
+        SELECT * FROM rule_t2;
+
+CREATE RULE InsertRule AS
+    ON INSERT TO rule_t1
+    DO INSTEAD
+        INSERT INTO rule_t2 VALUES(new.a);
+
+ALTER RULE InsertRule ON rule_t1 RENAME to NewInsertRule;
+
+INSERT INTO rule_t1 VALUES(1);
+SELECT * FROM rule_t1;
+
+--
+-- error conditions for alter rename rule
+--
+ALTER RULE NewInsertRule ON rule_t1 RENAME TO "_RETURN"; -- rule already exists error
+ALTER RULE "_RETURN" ON rule_t1 RENAME TO abc; -- ON SELECT rule can not be renamed error
+ALTER RULE InsertRule ON rule_t1 RENAME TO NewInsertRule; -- NO rule exists error
+ALTER RULE NewInsertRule ON notable RENAME TO InsertRule; -- table does not exist error
+CREATE TYPE item1 as();
+ALTER RULE InsertRule ON item1 RENAME to NewInsertRule; -- target item should be view or table
+
+DROP RULE NewInsertRule ON rule_t1; -- drop altered rule
+DROP TYPE item1;
+DROP VIEW rule_t1;
+DROP TABLE rule_t2;
\ No newline at end of file
diff --git a/doc/src/sgml/ref/alter_rule.sgml b/doc/src/sgml/ref/alter_rule.sgml
new file mode 100644
index 0000000..3861e4a
--- /dev/null
+++ b/doc/src/sgml/ref/alter_rule.sgml
@@ -0,0 +1,103 @@
+<!--
+doc/src/sgml/ref/alter_rule.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="SQL-ALTERRULE">
+ <refmeta>
+  <refentrytitle>ALTER RULE</refentrytitle>
+  <manvolnum>7</manvolnum>
+  <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+  <refname>ALTER RULE</refname>
+  <refpurpose>change the definition of a rule</refpurpose>
+ </refnamediv>
+
+ <indexterm zone="sql-alterrule">
+  <primary>ALTER RULE</primary>
+ </indexterm>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER RULE <replaceable class="PARAMETER">name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable> RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+  <title>Description</title>
+
+  <para>
+   <command>ALTER RULE</command> changes properties of an existing
+   rule.  The <literal>RENAME</literal> clause changes the name of
+   the given rule without otherwise changing the rule
+   definition.
+  </para>
+
+  <para>
+   You must own the table on which the rule acts to be allowed to change its properties.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>Parameters</title>
+
+  <variablelist>
+   <varlistentry>
+    <term><replaceable class="PARAMETER">name</replaceable></term>
+    <listitem>
+     <para>
+      The name of an existing rule to alter.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term><replaceable class="PARAMETER">table_name</replaceable></term>
+    <listitem>
+     <para>
+      The name of the table on which this rule acts.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term><replaceable class="PARAMETER">new_name</replaceable></term>
+    <listitem>
+     <para>
+      The new name for the rule.
+     </para>
+    </listitem>
+   </varlistentry>
+  </variablelist>
+ </refsect1>
+
+ <refsect1>
+  <title>Examples</title>
+
+  <para>
+   To rename an existing rule:
+<programlisting>
+ALTER RULE notify_all ON emp RENAME TO notify_me;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+  <title>Compatibility</title>
+
+  <para>
+   <command>ALTER RULE</command> is a
+   <productname>PostgreSQL</productname> language extension, as is the
+   entire query rewrite system.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>See Also</title>
+
+  <simplelist type="inline">
+   <member><xref linkend="sql-createrule"></member>
+  </simplelist>
+ </refsect1>
+</refentry>
#6Dean Rasheed
dean.a.rasheed@gmail.com
In reply to: Ali Dar (#5)
1 attachment(s)

On 29 January 2013 15:34, Ali Dar <ali.munir.dar@gmail.com> wrote:

Please find attached the complete patch for alter rename rule. I have
followed all the suggestions.

This looks good. I've tested it, and it appears to work as intended.
I'm happy with the code, and the new docs and regression tests look
OK.

I have a couple of minor tweaks (see attached):

* On the new manual page, I replaced "table" with "table or view".

* In the new tab-completion code, I modified the query so that it
completes with tables as well as views, and limited the results to
just those relations that have a rule with the name specified,
otherwise the list of completions could be very long.

If you're happy with these changes, I think this is ready for committer review.

Regards,
Dean

Attachments:

alter-rule-rename_complete.v2.patchapplication/octet-stream; name=alter-rule-rename_complete.v2.patchDownload
diff --git a/doc/src/sgml/ref/allfiles.sgml b/doc/src/sgml/ref/allfiles.sgml
new file mode 100644
index b3fc57d..c61c62f
--- a/doc/src/sgml/ref/allfiles.sgml
+++ b/doc/src/sgml/ref/allfiles.sgml
@@ -25,6 +25,7 @@ Complete list of usable sgml source file
 <!ENTITY alterOperatorClass SYSTEM "alter_opclass.sgml">
 <!ENTITY alterOperatorFamily SYSTEM "alter_opfamily.sgml">
 <!ENTITY alterRole          SYSTEM "alter_role.sgml">
+<!ENTITY alterRule          SYSTEM "alter_rule.sgml">
 <!ENTITY alterSchema        SYSTEM "alter_schema.sgml">
 <!ENTITY alterServer        SYSTEM "alter_server.sgml">
 <!ENTITY alterSequence      SYSTEM "alter_sequence.sgml">
diff --git a/doc/src/sgml/ref/create_rule.sgml b/doc/src/sgml/ref/create_rule.sgml
new file mode 100644
index 381ea3e..7e36aef
--- a/doc/src/sgml/ref/create_rule.sgml
+++ b/doc/src/sgml/ref/create_rule.sgml
@@ -284,4 +284,12 @@ UPDATE mytable SET name = 'foo' WHERE id
    entire query rewrite system.
   </para>
  </refsect1>
+
+  <refsect1>
+  <title>See Also</title>
+
+  <simplelist type="inline">
+   <member><xref linkend="sql-alterrule"></member>
+  </simplelist>
+ </refsect1>
 </refentry>
diff --git a/doc/src/sgml/reference.sgml b/doc/src/sgml/reference.sgml
new file mode 100644
index fe90227..5b0c774
--- a/doc/src/sgml/reference.sgml
+++ b/doc/src/sgml/reference.sgml
@@ -53,6 +53,7 @@
    &alterOperatorClass;
    &alterOperatorFamily;
    &alterRole;
+   &alterRule;
    &alterSchema;
    &alterSequence;
    &alterServer;
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
new file mode 100644
index c2d4bb3..3cc6e9a
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -51,6 +51,7 @@
 #include "commands/user.h"
 #include "parser/parse_func.h"
 #include "miscadmin.h"
+#include "rewrite/rewriteDefine.h"
 #include "tcop/utility.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
@@ -307,6 +308,9 @@ ExecRenameStmt(RenameStmt *stmt)
 		case OBJECT_ROLE:
 			return RenameRole(stmt->subname, stmt->newname);
 
+		case OBJECT_RULE:
+			return RenameRewriteRule(stmt->relation, stmt->subname, stmt->newname);
+
 		case OBJECT_SCHEMA:
 			return RenameSchema(stmt->subname, stmt->newname);
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
new file mode 100644
index 342b796..73cb49d
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -7030,6 +7030,16 @@ RenameStmt: ALTER AGGREGATE func_name ag
 					n->missing_ok = false;
 					$$ = (Node *)n;
 				}
+			| ALTER RULE name ON qualified_name RENAME TO name
+				{
+					RenameStmt *n = makeNode(RenameStmt);
+					n->renameType = OBJECT_RULE;
+					n->relation = $5;
+					n->subname = $3;
+					n->newname = $8;
+					n->missing_ok = false;
+					$$ = (Node *)n;
+				}
 			| ALTER USER RoleId RENAME TO RoleId
 				{
 					RenameStmt *n = makeNode(RenameStmt);
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
new file mode 100644
index ac724c3..dbdad19
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -753,35 +753,69 @@ EnableDisableRule(Relation rel, const ch
 
 /*
  * Rename an existing rewrite rule.
- *
- * This is unused code at the moment.  Note that it lacks a permissions check.
  */
-#ifdef NOT_USED
-void
-RenameRewriteRule(Oid owningRel, const char *oldName,
+Oid
+RenameRewriteRule(RangeVar* relation, const char *oldName,
 				  const char *newName)
 {
 	Relation	pg_rewrite_desc;
 	HeapTuple	ruletup;
+	Oid 		owningRel;
+	char		owningRelKind;
+	Oid 		ruleOid = InvalidOid;
+
+	owningRel = RangeVarGetRelid(relation, AccessExclusiveLock, false);
+
+	owningRelKind = get_rel_relkind(owningRel);
+
+	/*
+	 * verify relation is of a type that rules can be applied to
+	 */
+	if (owningRelKind != RELKIND_RELATION &&
+		owningRelKind != RELKIND_VIEW)
+		ereport(ERROR,
+				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
+				 errmsg("\"%s\" is not a table or view",
+						get_rel_name(owningRel))));
+
+	/*
+	 * check if user has permission to rename rule on this relation
+	 */
+	if (!pg_class_ownercheck(owningRel, GetUserId()))
+		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
+					   get_rel_name(owningRel));
 
 	pg_rewrite_desc = heap_open(RewriteRelationId, RowExclusiveLock);
 
 	ruletup = SearchSysCacheCopy2(RULERELNAME,
 								  ObjectIdGetDatum(owningRel),
 								  PointerGetDatum(oldName));
+
+	/* old rule should already exist */
 	if (!HeapTupleIsValid(ruletup))
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("rule \"%s\" for relation \"%s\" does not exist",
 						oldName, get_rel_name(owningRel))));
 
-	/* should not already exist */
+	ruleOid = HeapTupleGetOid(ruletup);
+
+	/* rule with the new name should not already exist */
 	if (IsDefinedRewriteRule(owningRel, newName))
 		ereport(ERROR,
 				(errcode(ERRCODE_DUPLICATE_OBJECT),
 				 errmsg("rule \"%s\" for relation \"%s\" already exists",
 						newName, get_rel_name(owningRel))));
 
+	/*
+	 * rename is not allowed for ON SELECT rule, because it's always
+	 * named "_RETURN".
+	 */
+	if (((Form_pg_rewrite) GETSTRUCT(ruletup))->ev_type - '0' == CMD_SELECT)
+		ereport(ERROR,
+		(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+			errmsg("rename not allowed for ON SELECT rule")));
+
 	namestrcpy(&(((Form_pg_rewrite) GETSTRUCT(ruletup))->rulename), newName);
 
 	simple_heap_update(pg_rewrite_desc, &ruletup->t_self, ruletup);
@@ -791,6 +825,6 @@ RenameRewriteRule(Oid owningRel, const c
 
 	heap_freetuple(ruletup);
 	heap_close(pg_rewrite_desc, RowExclusiveLock);
-}
 
-#endif
+	return ruleOid;
+}
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
new file mode 100644
index 09396ca..8c4d32f
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -633,6 +633,15 @@ static const SchemaQuery Query_for_list_
 "       (SELECT tgrelid FROM pg_catalog.pg_trigger "\
 "         WHERE pg_catalog.quote_ident(tgname)='%s')"
 
+/* the silly-looking length condition is just to eat up the current word */
+#define Query_for_list_of_relations_for_rule \
+"SELECT pg_catalog.quote_ident(relname) "\
+"  FROM pg_catalog.pg_class"\
+" WHERE (%d = pg_catalog.length('%s'))"\
+"   AND oid IN "\
+"       (SELECT ev_class FROM pg_catalog.pg_rewrite "\
+"         WHERE pg_catalog.quote_ident(rulename)='%s')"
+
 #define Query_for_list_of_ts_configurations \
 "SELECT pg_catalog.quote_ident(cfgname) FROM pg_catalog.pg_ts_config "\
 " WHERE substring(pg_catalog.quote_ident(cfgname),1,%d)='%s'"
@@ -925,7 +934,7 @@ psql_completion(char *text, int start, i
 		{"AGGREGATE", "COLLATION", "CONVERSION", "DATABASE", "DEFAULT PRIVILEGES", "DOMAIN",
 			"EXTENSION", "FOREIGN DATA WRAPPER", "FOREIGN TABLE", "FUNCTION",
 			"GROUP", "INDEX", "LANGUAGE", "LARGE OBJECT", "OPERATOR",
-			"ROLE", "SCHEMA", "SERVER", "SEQUENCE", "TABLE",
+			"ROLE", "RULE", "SCHEMA", "SERVER", "SEQUENCE", "TABLE",
 			"TABLESPACE", "TEXT SEARCH", "TRIGGER", "TYPE",
 		"USER", "USER MAPPING FOR", "VIEW", NULL};
 
@@ -1681,6 +1690,25 @@ psql_completion(char *text, int start, i
 			 pg_strcasecmp(prev_wd, "USER") == 0)
 		COMPLETE_WITH_QUERY(Query_for_list_of_roles);
 
+	/* ALTER RULE <name> */
+	else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
+			 pg_strcasecmp(prev2_wd, "RULE") == 0)
+		COMPLETE_WITH_CONST("ON");
+
+	/* ALTER RULE <name> ON <name>*/
+	else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
+			 pg_strcasecmp(prev4_wd, "RULE") == 0)
+		COMPLETE_WITH_CONST("RENAME TO");
+
+	/* If we have ALTER RULE <name> ON, then add the correct viewname */
+	else if (pg_strcasecmp(prev4_wd, "ALTER") == 0 &&
+			 pg_strcasecmp(prev3_wd, "RULE") == 0 &&
+			 pg_strcasecmp(prev_wd, "ON") == 0)
+	{
+		completion_info_charp = prev2_wd;
+		COMPLETE_WITH_QUERY(Query_for_list_of_relations_for_rule);
+	}
+
 /* BEGIN, END, ABORT */
 	else if (pg_strcasecmp(prev_wd, "BEGIN") == 0 ||
 			 pg_strcasecmp(prev_wd, "END") == 0 ||
diff --git a/src/include/rewrite/rewriteDefine.h b/src/include/rewrite/rewriteDefine.h
new file mode 100644
index dda267b..72921c3
--- a/src/include/rewrite/rewriteDefine.h
+++ b/src/include/rewrite/rewriteDefine.h
@@ -32,7 +32,7 @@ extern Oid DefineQueryRewrite(char *rule
 				   bool replace,
 				   List *action);
 
-extern void RenameRewriteRule(Oid owningRel, const char *oldName,
+extern Oid RenameRewriteRule(RangeVar* relation, const char *oldName,
 				  const char *newName);
 
 extern void setRuleCheckAsUser(Node *node, Oid userid);
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
new file mode 100644
index a235571..7e79815
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1693,3 +1693,42 @@ Rules:
     ON UPDATE TO rules_src DO  VALUES (old.f1,old.f2,'old'::text), (new.f1,new.f2,'new'::text)
 Has OIDs: no
 
+--
+-- check alter rename rule
+--
+CREATE TABLE rule_t1 (a INT);
+CREATE TABLE rule_t2 (a INT);
+CREATE RULE "_RETURN" AS
+    ON SELECT TO rule_t1
+    DO INSTEAD
+        SELECT * FROM rule_t2;
+CREATE RULE InsertRule AS
+    ON INSERT TO rule_t1
+    DO INSTEAD
+        INSERT INTO rule_t2 VALUES(new.a);
+ALTER RULE InsertRule ON rule_t1 RENAME to NewInsertRule;
+INSERT INTO rule_t1 VALUES(1);
+SELECT * FROM rule_t1;
+ a 
+---
+ 1
+(1 row)
+
+--
+-- error conditions for alter rename rule
+--
+ALTER RULE NewInsertRule ON rule_t1 RENAME TO "_RETURN"; -- rule already exists error
+ERROR:  rule "_RETURN" for relation "rule_t1" already exists
+ALTER RULE "_RETURN" ON rule_t1 RENAME TO abc; -- ON SELECT rule can not be renamed error
+ERROR:  rename not allowed for ON SELECT rule
+ALTER RULE InsertRule ON rule_t1 RENAME TO NewInsertRule; -- NO rule exists error
+ERROR:  rule "insertrule" for relation "rule_t1" does not exist
+ALTER RULE NewInsertRule ON notable RENAME TO InsertRule; -- table does not exist error
+ERROR:  relation "notable" does not exist
+CREATE TYPE item1 as();
+ALTER RULE InsertRule ON item1 RENAME to NewInsertRule; -- target item should be view or table
+ERROR:  "item1" is not a table or view
+DROP RULE NewInsertRule ON rule_t1; -- drop altered rule
+DROP TYPE item1;
+DROP VIEW rule_t1;
+DROP TABLE rule_t2;
diff --git a/src/test/regress/sql/rules.sql b/src/test/regress/sql/rules.sql
new file mode 100644
index 458c2f0..abdd763
--- a/src/test/regress/sql/rules.sql
+++ b/src/test/regress/sql/rules.sql
@@ -968,3 +968,40 @@ update rules_src set f2 = f2 / 10;
 select * from rules_src;
 select * from rules_log;
 \d+ rules_src
+
+
+--
+-- check alter rename rule
+--
+CREATE TABLE rule_t1 (a INT);
+CREATE TABLE rule_t2 (a INT);
+
+CREATE RULE "_RETURN" AS
+    ON SELECT TO rule_t1
+    DO INSTEAD
+        SELECT * FROM rule_t2;
+
+CREATE RULE InsertRule AS
+    ON INSERT TO rule_t1
+    DO INSTEAD
+        INSERT INTO rule_t2 VALUES(new.a);
+
+ALTER RULE InsertRule ON rule_t1 RENAME to NewInsertRule;
+
+INSERT INTO rule_t1 VALUES(1);
+SELECT * FROM rule_t1;
+
+--
+-- error conditions for alter rename rule
+--
+ALTER RULE NewInsertRule ON rule_t1 RENAME TO "_RETURN"; -- rule already exists error
+ALTER RULE "_RETURN" ON rule_t1 RENAME TO abc; -- ON SELECT rule can not be renamed error
+ALTER RULE InsertRule ON rule_t1 RENAME TO NewInsertRule; -- NO rule exists error
+ALTER RULE NewInsertRule ON notable RENAME TO InsertRule; -- table does not exist error
+CREATE TYPE item1 as();
+ALTER RULE InsertRule ON item1 RENAME to NewInsertRule; -- target item should be view or table
+
+DROP RULE NewInsertRule ON rule_t1; -- drop altered rule
+DROP TYPE item1;
+DROP VIEW rule_t1;
+DROP TABLE rule_t2;
\ No newline at end of file
diff --git a/doc/src/sgml/ref/alter_rule.sgml b/doc/src/sgml/ref/alter_rule.sgml
new file mode 100644
index ...c98c35b
--- a/doc/src/sgml/ref/alter_rule.sgml
+++ b/doc/src/sgml/ref/alter_rule.sgml
@@ -0,0 +1,104 @@
+<!--
+doc/src/sgml/ref/alter_rule.sgml
+PostgreSQL documentation
+-->
+
+<refentry id="SQL-ALTERRULE">
+ <refmeta>
+  <refentrytitle>ALTER RULE</refentrytitle>
+  <manvolnum>7</manvolnum>
+  <refmiscinfo>SQL - Language Statements</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+  <refname>ALTER RULE</refname>
+  <refpurpose>change the definition of a rule</refpurpose>
+ </refnamediv>
+
+ <indexterm zone="sql-alterrule">
+  <primary>ALTER RULE</primary>
+ </indexterm>
+
+ <refsynopsisdiv>
+<synopsis>
+ALTER RULE <replaceable class="PARAMETER">name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable> RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
+</synopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+  <title>Description</title>
+
+  <para>
+   <command>ALTER RULE</command> changes properties of an existing
+   rule.  The <literal>RENAME</literal> clause changes the name of
+   the given rule without otherwise changing the rule
+   definition.
+  </para>
+
+  <para>
+   You must own the table or view on which the rule acts to be allowed to
+   change its properties.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>Parameters</title>
+
+  <variablelist>
+   <varlistentry>
+    <term><replaceable class="PARAMETER">name</replaceable></term>
+    <listitem>
+     <para>
+      The name of an existing rule to alter.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term><replaceable class="PARAMETER">table_name</replaceable></term>
+    <listitem>
+     <para>
+      The name of the table or view on which this rule acts.
+     </para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term><replaceable class="PARAMETER">new_name</replaceable></term>
+    <listitem>
+     <para>
+      The new name for the rule.
+     </para>
+    </listitem>
+   </varlistentry>
+  </variablelist>
+ </refsect1>
+
+ <refsect1>
+  <title>Examples</title>
+
+  <para>
+   To rename an existing rule:
+<programlisting>
+ALTER RULE notify_all ON emp RENAME TO notify_me;
+</programlisting></para>
+ </refsect1>
+
+ <refsect1>
+  <title>Compatibility</title>
+
+  <para>
+   <command>ALTER RULE</command> is a
+   <productname>PostgreSQL</productname> language extension, as is the
+   entire query rewrite system.
+  </para>
+ </refsect1>
+
+ <refsect1>
+  <title>See Also</title>
+
+  <simplelist type="inline">
+   <member><xref linkend="sql-createrule"></member>
+  </simplelist>
+ </refsect1>
+</refentry>
#7Ali Dar
ali.munir.dar@gmail.com
In reply to: Dean Rasheed (#6)

The tweaks made by you seems fine. I'm good with it.

Regards,
Ali Dar

On Sun, Feb 3, 2013 at 8:04 PM, Dean Rasheed <dean.a.rasheed@gmail.com>wrote:

Show quoted text

On 29 January 2013 15:34, Ali Dar <ali.munir.dar@gmail.com> wrote:

Please find attached the complete patch for alter rename rule. I have
followed all the suggestions.

This looks good. I've tested it, and it appears to work as intended.
I'm happy with the code, and the new docs and regression tests look
OK.

I have a couple of minor tweaks (see attached):

* On the new manual page, I replaced "table" with "table or view".

* In the new tab-completion code, I modified the query so that it
completes with tables as well as views, and limited the results to
just those relations that have a rule with the name specified,
otherwise the list of completions could be very long.

If you're happy with these changes, I think this is ready for committer
review.

Regards,
Dean

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Dean Rasheed (#6)

Dean Rasheed <dean.a.rasheed@gmail.com> writes:

[ alter-rule-rename_complete.v2.patch ]

Committed with assorted editorialization. Aside from cosmetic issues,
the main changes were:

* use RangeVarGetRelidExtended with a callback to perform the lookup
and locking of the target relation. This is a new API that the original
version of RenameRewriteRule couldn't have known about. I borrowed the
code pretty much verbatim from renametrig(), and am now wondering
whether there shouldn't be some attempt to unify the callbacks for this.

* call CacheInvalidateRelcache to ensure that other sessions notice the
rule tuple update. It may be that this isn't necessary because nothing
looks at the rule name fields in relcache entries ... but I wouldn't bet
on that, and in any case it seems like bad practice to let stale cache
entries hang around.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers