Rule names are now unique per-relation, rather than unique globally.

DROP RULE and COMMENT ON RULE syntax adds an 'ON tablename' clause,
similar to TRIGGER syntaxes.  To allow loading of existing pg_dump
files containing COMMENT ON RULE, the COMMENT code will still accept
the old syntax --- but only if the target rulename is unique across
the whole database.
This commit is contained in:
Tom Lane 2002-04-18 20:01:11 +00:00
parent 4e08a625b0
commit b3120804ad
35 changed files with 489 additions and 300 deletions

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.94 2002/03/22 19:20:09 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/func.sgml,v 1.95 2002/04/18 20:01:08 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
@ -4344,7 +4344,12 @@ SELECT NULLIF(value, '(none)') ...
<entry>Get CREATE VIEW command for view</> <entry>Get CREATE VIEW command for view</>
</row> </row>
<row> <row>
<entry><function>pg_get_ruledef</>(<parameter>rulename</parameter>)</entry> <entry><function>pg_get_viewdef</>(<parameter>viewOID</parameter>)</entry>
<entry><type>text</></entry>
<entry>Get CREATE VIEW command for view</>
</row>
<row>
<entry><function>pg_get_ruledef</>(<parameter>ruleOID</parameter>)</entry>
<entry><type>text</></entry> <entry><type>text</></entry>
<entry>Get CREATE RULE command for rule</> <entry>Get CREATE RULE command for rule</>
</row> </row>

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/comment.sgml,v 1.15 2002/03/19 02:18:12 momjian Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/comment.sgml,v 1.16 2002/04/18 20:01:09 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
@ -25,11 +25,12 @@ PostgreSQL documentation
<synopsis> <synopsis>
COMMENT ON COMMENT ON
[ [
[ DATABASE | DOMAIN | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ] <replaceable class="PARAMETER">object_name</replaceable> | [ DATABASE | DOMAIN | INDEX | SEQUENCE | TABLE | TYPE | VIEW ] <replaceable class="PARAMETER">object_name</replaceable> |
COLUMN <replaceable class="PARAMETER">table_name</replaceable>.<replaceable class="PARAMETER">column_name</replaceable> | COLUMN <replaceable class="PARAMETER">table_name</replaceable>.<replaceable class="PARAMETER">column_name</replaceable> |
AGGREGATE <replaceable class="PARAMETER">agg_name</replaceable> (<replaceable class="PARAMETER">agg_type</replaceable>) | AGGREGATE <replaceable class="PARAMETER">agg_name</replaceable> (<replaceable class="PARAMETER">agg_type</replaceable>) |
FUNCTION <replaceable class="PARAMETER">func_name</replaceable> (<replaceable class="PARAMETER">arg1</replaceable>, <replaceable class="PARAMETER">arg2</replaceable>, ...) | FUNCTION <replaceable class="PARAMETER">func_name</replaceable> (<replaceable class="PARAMETER">arg1</replaceable>, <replaceable class="PARAMETER">arg2</replaceable>, ...) |
OPERATOR <replaceable class="PARAMETER">op</replaceable> (<replaceable class="PARAMETER">leftoperand_type</replaceable> <replaceable class="PARAMETER">rightoperand_type</replaceable>) | OPERATOR <replaceable class="PARAMETER">op</replaceable> (<replaceable class="PARAMETER">leftoperand_type</replaceable> <replaceable class="PARAMETER">rightoperand_type</replaceable>) |
RULE <replaceable class="PARAMETER">rule_name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable> |
TRIGGER <replaceable class="PARAMETER">trigger_name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable> TRIGGER <replaceable class="PARAMETER">trigger_name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable>
] IS <replaceable class="PARAMETER">'text'</replaceable> ] IS <replaceable class="PARAMETER">'text'</replaceable>
</synopsis> </synopsis>
@ -46,7 +47,7 @@ COMMENT ON
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term><replaceable class="PARAMETER">object_name, table_name, <term><replaceable class="PARAMETER">object_name, table_name,
column_name, agg_name, func_name, op, trigger_name</replaceable></term> column_name, agg_name, func_name, op, rule_name, trigger_name</replaceable></term>
<listitem> <listitem>
<para> <para>
The name of the object to be be commented. The name of the object to be be commented.
@ -143,7 +144,6 @@ COMMENT ON mytable IS 'This is my table.';
COMMENT ON DATABASE my_database IS 'Development Database'; COMMENT ON DATABASE my_database IS 'Development Database';
COMMENT ON DOMAIN my_domain IS 'Email Address Domain'; COMMENT ON DOMAIN my_domain IS 'Email Address Domain';
COMMENT ON INDEX my_index IS 'Enforces uniqueness on employee id'; COMMENT ON INDEX my_index IS 'Enforces uniqueness on employee id';
COMMENT ON RULE my_rule IS 'Logs UPDATES of employee records';
COMMENT ON SEQUENCE my_sequence IS 'Used to generate primary keys'; COMMENT ON SEQUENCE my_sequence IS 'Used to generate primary keys';
COMMENT ON TABLE my_table IS 'Employee Information'; COMMENT ON TABLE my_table IS 'Employee Information';
COMMENT ON TYPE my_type IS 'Complex Number support'; COMMENT ON TYPE my_type IS 'Complex Number support';
@ -152,6 +152,7 @@ COMMENT ON COLUMN my_table.my_field IS 'Employee ID number';
COMMENT ON AGGREGATE my_aggregate (double precision) IS 'Computes sample variance'; COMMENT ON AGGREGATE my_aggregate (double precision) IS 'Computes sample variance';
COMMENT ON FUNCTION my_function (timestamp) IS 'Returns Roman Numeral'; COMMENT ON FUNCTION my_function (timestamp) IS 'Returns Roman Numeral';
COMMENT ON OPERATOR ^ (text, text) IS 'Performs intersection of two text'; COMMENT ON OPERATOR ^ (text, text) IS 'Performs intersection of two text';
COMMENT ON RULE my_rule ON my_table IS 'Logs UPDATES of employee records';
COMMENT ON TRIGGER my_trigger ON my_table IS 'Used for R.I.'; COMMENT ON TRIGGER my_trigger ON my_table IS 'Used for R.I.';
</programlisting> </programlisting>
</para> </para>

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_rule.sgml,v 1.11 2001/12/08 03:24:36 thomas Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_rule.sgml,v 1.12 2002/04/18 20:01:09 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
@ -23,7 +23,7 @@ PostgreSQL documentation
<date>1998-09-22</date> <date>1998-09-22</date>
</refsynopsisdivinfo> </refsynopsisdivinfo>
<synopsis> <synopsis>
DROP RULE <replaceable class="PARAMETER">name</replaceable> [, ...] DROP RULE <replaceable class="PARAMETER">name</replaceable> ON <replaceable class="PARAMETER">relation</replaceable>
</synopsis> </synopsis>
<refsect2 id="R2-SQL-DROPRULE-1"> <refsect2 id="R2-SQL-DROPRULE-1">
@ -43,6 +43,14 @@ DROP RULE <replaceable class="PARAMETER">name</replaceable> [, ...]
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><replaceable class="parameter">relation</replaceable></term>
<listitem>
<para>
The name of the relation the rule applies to.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</para> </para>
</refsect2> </refsect2>
@ -68,7 +76,7 @@ DROP
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><computeroutput> <term><computeroutput>
ERROR: Rule or view "<replaceable class="parameter">name</replaceable>" not found ERROR: Rule "<replaceable class="parameter">name</replaceable>" not found
</computeroutput></term> </computeroutput></term>
<listitem> <listitem>
<para> <para>
@ -113,11 +121,6 @@ ERROR: Rule or view "<replaceable class="parameter">name</replaceable>" not fou
Refer to <command>CREATE RULE</command> for Refer to <command>CREATE RULE</command> for
information on how to create rules. information on how to create rules.
</para> </para>
<para>
Once a rule is dropped, access to historical information
the rule has written may disappear.
</para>
</refsect2> </refsect2>
</refsect1> </refsect1>
@ -129,7 +132,7 @@ ERROR: Rule or view "<replaceable class="parameter">name</replaceable>" not fou
To drop the rewrite rule <literal>newrule</literal>: To drop the rewrite rule <literal>newrule</literal>:
<programlisting> <programlisting>
DROP RULE newrule; DROP RULE newrule ON mytable;
</programlisting> </programlisting>
</para> </para>
</refsect1> </refsect1>

View File

@ -1,5 +1,5 @@
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.132 2002/04/10 22:46:48 petere Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/release.sgml,v 1.133 2002/04/18 20:01:08 tgl Exp $
--> -->
<appendix id="release"> <appendix id="release">
@ -24,6 +24,7 @@ CDATA means the content is "SGML-free", so you can write without
worries about funny characters. worries about funny characters.
--> -->
<literallayout><![CDATA[ <literallayout><![CDATA[
Rule names are now per-relation, not global; DROP RULE and COMMENT ON RULE syntax changes accordingly
Readline and Zlib are now required by default and must be turned off explicitly if their use is not desired Readline and Zlib are now required by default and must be turned off explicitly if their use is not desired
Define a third class of function volatility to allow indexscans in more cases Define a third class of function volatility to allow indexscans in more cases
Locale support is now built by default; choice of locale is set by initdb and/or at run-time Locale support is now built by default; choice of locale is set by initdb and/or at run-time

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.90 2002/04/17 20:57:56 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.91 2002/04/18 20:01:09 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -68,7 +68,7 @@ char *Name_pg_proc_indices[Num_pg_proc_indices] =
char *Name_pg_relcheck_indices[Num_pg_relcheck_indices] = char *Name_pg_relcheck_indices[Num_pg_relcheck_indices] =
{RelCheckIndex}; {RelCheckIndex};
char *Name_pg_rewrite_indices[Num_pg_rewrite_indices] = char *Name_pg_rewrite_indices[Num_pg_rewrite_indices] =
{RewriteOidIndex, RewriteRulenameIndex}; {RewriteOidIndex, RewriteRelRulenameIndex};
char *Name_pg_shadow_indices[Num_pg_shadow_indices] = char *Name_pg_shadow_indices[Num_pg_shadow_indices] =
{ShadowNameIndex, ShadowSysidIndex}; {ShadowNameIndex, ShadowSysidIndex};
char *Name_pg_statistic_indices[Num_pg_statistic_indices] = char *Name_pg_statistic_indices[Num_pg_statistic_indices] =

View File

@ -7,7 +7,7 @@
* Copyright (c) 1999-2001, PostgreSQL Global Development Group * Copyright (c) 1999-2001, PostgreSQL Global Development Group
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.41 2002/04/16 23:08:10 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.42 2002/04/18 20:01:09 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -472,44 +472,105 @@ CommentDatabase(List *qualname, char *comment)
* CommentRule -- * CommentRule --
* *
* This routine is used to add/drop any user-comments a user might * This routine is used to add/drop any user-comments a user might
* have regarding a specified RULE. The rule is specified by name * have regarding a specified RULE. The rule for commenting is determined by
* and, if found, and the user has appropriate permissions, a * both its name and the relation to which it refers. The arguments to this
* comment will be added/dropped using the CreateComments() routine. * function are the rule name and relation name (merged into a qualified
* name), and the comment to add/drop.
*
* Before PG 7.3, rules had unique names across the whole database, and so
* the syntax was just COMMENT ON RULE rulename, with no relation name.
* For purposes of backwards compatibility, we support that as long as there
* is only one rule by the specified name in the database.
*/ */
static void static void
CommentRule(List *qualname, char *comment) CommentRule(List *qualname, char *comment)
{ {
char *rule; int nnames;
List *relname;
char *rulename;
RangeVar *rel;
Relation relation;
HeapTuple tuple; HeapTuple tuple;
Oid reloid; Oid reloid;
Oid ruleoid; Oid ruleoid;
Oid classoid; Oid classoid;
int32 aclcheck; int32 aclcheck;
/* XXX this is gonna change soon */ /* Separate relname and trig name */
if (length(qualname) != 1) nnames = length(qualname);
elog(ERROR, "CommentRule: rule name may not be qualified"); if (nnames == 1)
rule = strVal(lfirst(qualname)); {
/* Old-style: only a rule name is given */
Relation RewriteRelation;
HeapScanDesc scanDesc;
ScanKeyData scanKeyData;
/* Find the rule's pg_rewrite tuple, get its OID and its table's OID */ rulename = strVal(lfirst(qualname));
tuple = SearchSysCache(RULENAME, /* Search pg_rewrite for such a rule */
PointerGetDatum(rule), ScanKeyEntryInitialize(&scanKeyData,
0, 0, 0); 0,
if (!HeapTupleIsValid(tuple)) Anum_pg_rewrite_rulename,
elog(ERROR, "rule '%s' does not exist", rule); F_NAMEEQ,
PointerGetDatum(rulename));
reloid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class; RewriteRelation = heap_openr(RewriteRelationName, AccessShareLock);
ruleoid = tuple->t_data->t_oid; scanDesc = heap_beginscan(RewriteRelation,
0, SnapshotNow, 1, &scanKeyData);
ReleaseSysCache(tuple); tuple = heap_getnext(scanDesc, 0);
if (HeapTupleIsValid(tuple))
{
reloid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
ruleoid = tuple->t_data->t_oid;
}
else
{
elog(ERROR, "rule '%s' does not exist", rulename);
reloid = ruleoid = 0; /* keep compiler quiet */
}
if (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0)))
elog(ERROR, "There are multiple rules '%s'"
"\n\tPlease specify a relation name as well as a rule name",
rulename);
heap_endscan(scanDesc);
heap_close(RewriteRelation, AccessShareLock);
/* Open the owning relation to ensure it won't go away meanwhile */
relation = heap_open(reloid, AccessShareLock);
}
else
{
/* New-style: rule and relname both provided */
Assert(nnames >= 2);
relname = ltruncate(nnames-1, listCopy(qualname));
rulename = strVal(nth(nnames-1, qualname));
/* Open the owning relation to ensure it won't go away meanwhile */
rel = makeRangeVarFromNameList(relname);
relation = heap_openrv(rel, AccessShareLock);
reloid = RelationGetRelid(relation);
/* Find the rule's pg_rewrite tuple, get its OID */
tuple = SearchSysCache(RULERELNAME,
ObjectIdGetDatum(reloid),
PointerGetDatum(rulename),
0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "rule '%s' does not exist", rulename);
Assert(reloid == ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class);
ruleoid = tuple->t_data->t_oid;
ReleaseSysCache(tuple);
}
/* Check object security */ /* Check object security */
aclcheck = pg_class_aclcheck(reloid, GetUserId(), ACL_RULE); aclcheck = pg_class_aclcheck(reloid, GetUserId(), ACL_RULE);
if (aclcheck != ACLCHECK_OK) if (aclcheck != ACLCHECK_OK)
elog(ERROR, "you are not permitted to comment on rule '%s'", elog(ERROR, "you are not permitted to comment on rule '%s'",
rule); rulename);
/* pg_rewrite doesn't have a hard-coded OID, so must look it up */ /* pg_rewrite doesn't have a hard-coded OID, so must look it up */

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.2 2002/04/15 23:45:07 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.3 2002/04/18 20:01:09 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1423,8 +1423,8 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
Relation ridescs[Num_pg_class_indices]; Relation ridescs[Num_pg_class_indices];
Oid toast_relid; Oid toast_relid;
Oid toast_idxid; Oid toast_idxid;
char toast_relname[NAMEDATALEN + 1]; char toast_relname[NAMEDATALEN];
char toast_idxname[NAMEDATALEN + 1]; char toast_idxname[NAMEDATALEN];
IndexInfo *indexInfo; IndexInfo *indexInfo;
Oid classObjectId[2]; Oid classObjectId[2];
@ -1667,7 +1667,7 @@ needs_toast_table(Relation rel)
Oid Oid
DefineRelation(CreateStmt *stmt, char relkind) DefineRelation(CreateStmt *stmt, char relkind)
{ {
char *relname = palloc(NAMEDATALEN); char relname[NAMEDATALEN];
Oid namespaceId; Oid namespaceId;
List *schema = stmt->tableElts; List *schema = stmt->tableElts;
int numberOfAttributes; int numberOfAttributes;
@ -1686,7 +1686,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
* Truncate relname to appropriate length (probably a waste of time, * Truncate relname to appropriate length (probably a waste of time,
* as parser should have done this already). * as parser should have done this already).
*/ */
StrNCpy(relname, (stmt->relation)->relname, NAMEDATALEN); StrNCpy(relname, stmt->relation->relname, NAMEDATALEN);
/* /*
* Look up the namespace in which we are supposed to create the * Look up the namespace in which we are supposed to create the
@ -2642,8 +2642,8 @@ renameatt(Oid relid,
0, 0)) 0, 0))
elog(ERROR, "renameatt: attribute \"%s\" exists", newattname); elog(ERROR, "renameatt: attribute \"%s\" exists", newattname);
StrNCpy(NameStr(((Form_pg_attribute) GETSTRUCT(atttup))->attname), namestrcpy(&(((Form_pg_attribute) GETSTRUCT(atttup))->attname),
newattname, NAMEDATALEN); newattname);
simple_heap_update(attrelation, &atttup->t_self, atttup); simple_heap_update(attrelation, &atttup->t_self, atttup);
@ -2699,8 +2699,8 @@ renameatt(Oid relid,
/* /*
* Update the (copied) attribute tuple. * Update the (copied) attribute tuple.
*/ */
StrNCpy(NameStr(((Form_pg_attribute) GETSTRUCT(atttup))->attname), namestrcpy(&(((Form_pg_attribute) GETSTRUCT(atttup))->attname),
newattname, NAMEDATALEN); newattname);
simple_heap_update(attrelation, &atttup->t_self, atttup); simple_heap_update(attrelation, &atttup->t_self, atttup);
@ -2753,6 +2753,7 @@ renamerel(Oid relid, const char *newrelname)
Relation relrelation; /* for RELATION relation */ Relation relrelation; /* for RELATION relation */
HeapTuple reltup; HeapTuple reltup;
Oid namespaceId; Oid namespaceId;
char *oldrelname;
char relkind; char relkind;
bool relhastriggers; bool relhastriggers;
Relation irelations[Num_pg_class_indices]; Relation irelations[Num_pg_class_indices];
@ -2763,13 +2764,14 @@ renamerel(Oid relid, const char *newrelname)
*/ */
targetrelation = relation_open(relid, AccessExclusiveLock); targetrelation = relation_open(relid, AccessExclusiveLock);
oldrelname = pstrdup(RelationGetRelationName(targetrelation));
namespaceId = RelationGetNamespace(targetrelation); namespaceId = RelationGetNamespace(targetrelation);
/* Validity checks */ /* Validity checks */
if (!allowSystemTableMods && if (!allowSystemTableMods &&
IsSystemRelation(targetrelation)) IsSystemRelation(targetrelation))
elog(ERROR, "renamerel: system relation \"%s\" may not be renamed", elog(ERROR, "renamerel: system relation \"%s\" may not be renamed",
RelationGetRelationName(targetrelation)); oldrelname);
relkind = targetrelation->rd_rel->relkind; relkind = targetrelation->rd_rel->relkind;
relhastriggers = (targetrelation->rd_rel->reltriggers > 0); relhastriggers = (targetrelation->rd_rel->reltriggers > 0);
@ -2785,7 +2787,7 @@ renamerel(Oid relid, const char *newrelname)
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(reltup)) if (!HeapTupleIsValid(reltup))
elog(ERROR, "renamerel: relation \"%s\" does not exist", elog(ERROR, "renamerel: relation \"%s\" does not exist",
RelationGetRelationName(targetrelation)); oldrelname);
if (get_relname_relid(newrelname, namespaceId) != InvalidOid) if (get_relname_relid(newrelname, namespaceId) != InvalidOid)
elog(ERROR, "renamerel: relation \"%s\" exists", newrelname); elog(ERROR, "renamerel: relation \"%s\" exists", newrelname);
@ -2794,8 +2796,7 @@ renamerel(Oid relid, const char *newrelname)
* Update pg_class tuple with new relname. (Scribbling on reltup is * Update pg_class tuple with new relname. (Scribbling on reltup is
* OK because it's a copy...) * OK because it's a copy...)
*/ */
StrNCpy(NameStr(((Form_pg_class) GETSTRUCT(reltup))->relname), namestrcpy(&(((Form_pg_class) GETSTRUCT(reltup))->relname), newrelname);
newrelname, NAMEDATALEN);
simple_heap_update(relrelation, &reltup->t_self, reltup); simple_heap_update(relrelation, &reltup->t_self, reltup);
@ -2811,8 +2812,7 @@ renamerel(Oid relid, const char *newrelname)
* Also rename the associated type, if any. * Also rename the associated type, if any.
*/ */
if (relkind != RELKIND_INDEX) if (relkind != RELKIND_INDEX)
TypeRename(RelationGetRelationName(targetrelation), namespaceId, TypeRename(oldrelname, namespaceId, newrelname);
newrelname);
/* /*
* If it's a view, must also rename the associated ON SELECT rule. * If it's a view, must also rename the associated ON SELECT rule.
@ -2822,9 +2822,9 @@ renamerel(Oid relid, const char *newrelname)
char *oldrulename, char *oldrulename,
*newrulename; *newrulename;
oldrulename = MakeRetrieveViewRuleName(RelationGetRelationName(targetrelation)); oldrulename = MakeRetrieveViewRuleName(oldrelname);
newrulename = MakeRetrieveViewRuleName(newrelname); newrulename = MakeRetrieveViewRuleName(newrelname);
RenameRewriteRule(oldrulename, newrulename); RenameRewriteRule(relid, oldrulename, newrulename);
} }
/* /*
@ -2834,12 +2834,12 @@ renamerel(Oid relid, const char *newrelname)
{ {
/* update tgargs where relname is primary key */ /* update tgargs where relname is primary key */
update_ri_trigger_args(relid, update_ri_trigger_args(relid,
RelationGetRelationName(targetrelation), oldrelname,
newrelname, newrelname,
false, true); false, true);
/* update tgargs where relname is foreign key */ /* update tgargs where relname is foreign key */
update_ri_trigger_args(relid, update_ri_trigger_args(relid,
RelationGetRelationName(targetrelation), oldrelname,
newrelname, newrelname,
true, true); true, true);
} }

View File

@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.179 2002/04/17 20:57:56 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.180 2002/04/18 20:01:09 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -2380,14 +2380,15 @@ _copyCreateTrigStmt(CreateTrigStmt *from)
return newnode; return newnode;
} }
static DropTrigStmt * static DropPropertyStmt *
_copyDropTrigStmt(DropTrigStmt *from) _copyDropPropertyStmt(DropPropertyStmt *from)
{ {
DropTrigStmt *newnode = makeNode(DropTrigStmt); DropPropertyStmt *newnode = makeNode(DropPropertyStmt);
if (from->trigname)
newnode->trigname = pstrdup(from->trigname);
Node_Copy(from, newnode, relation); Node_Copy(from, newnode, relation);
if (from->property)
newnode->property = pstrdup(from->property);
newnode->removeType = from->removeType;
return newnode; return newnode;
} }
@ -2915,8 +2916,8 @@ copyObject(void *from)
case T_CreateTrigStmt: case T_CreateTrigStmt:
retval = _copyCreateTrigStmt(from); retval = _copyCreateTrigStmt(from);
break; break;
case T_DropTrigStmt: case T_DropPropertyStmt:
retval = _copyDropTrigStmt(from); retval = _copyDropPropertyStmt(from);
break; break;
case T_CreatePLangStmt: case T_CreatePLangStmt:
retval = _copyCreatePLangStmt(from); retval = _copyCreatePLangStmt(from);

View File

@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.127 2002/04/17 20:57:56 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.128 2002/04/18 20:01:09 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -1232,12 +1232,14 @@ _equalCreateTrigStmt(CreateTrigStmt *a, CreateTrigStmt *b)
} }
static bool static bool
_equalDropTrigStmt(DropTrigStmt *a, DropTrigStmt *b) _equalDropPropertyStmt(DropPropertyStmt *a, DropPropertyStmt *b)
{ {
if (!equalstr(a->trigname, b->trigname))
return false;
if (!equal(a->relation, b->relation)) if (!equal(a->relation, b->relation))
return false; return false;
if (!equalstr(a->property, b->property))
return false;
if (a->removeType != b->removeType)
return false;
return true; return true;
} }
@ -2080,8 +2082,8 @@ equal(void *a, void *b)
case T_CreateTrigStmt: case T_CreateTrigStmt:
retval = _equalCreateTrigStmt(a, b); retval = _equalCreateTrigStmt(a, b);
break; break;
case T_DropTrigStmt: case T_DropPropertyStmt:
retval = _equalDropTrigStmt(a, b); retval = _equalDropPropertyStmt(a, b);
break; break;
case T_CreatePLangStmt: case T_CreatePLangStmt:
retval = _equalCreatePLangStmt(a, b); retval = _equalCreatePLangStmt(a, b);

View File

@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.303 2002/04/17 20:57:56 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.304 2002/04/18 20:01:09 tgl Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
@ -134,7 +134,7 @@ static bool set_name_needs_quotes(const char *name);
CreateSchemaStmt, CreateSeqStmt, CreateStmt, CreateTrigStmt, CreateSchemaStmt, CreateSeqStmt, CreateStmt, CreateTrigStmt,
CreateUserStmt, CreatedbStmt, CursorStmt, DefineStmt, DeleteStmt, CreateUserStmt, CreatedbStmt, CursorStmt, DefineStmt, DeleteStmt,
DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropTrigStmt, DropGroupStmt, DropPLangStmt, DropSchemaStmt, DropStmt, DropTrigStmt,
DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt, DropRuleStmt, DropUserStmt, DropdbStmt, ExplainStmt, FetchStmt,
GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt, LockStmt, GrantStmt, IndexStmt, InsertStmt, ListenStmt, LoadStmt, LockStmt,
NotifyStmt, OptimizableStmt, ProcedureStmt, ReindexStmt, NotifyStmt, OptimizableStmt, ProcedureStmt, ReindexStmt,
RemoveAggrStmt, RemoveFuncStmt, RemoveOperStmt, RemoveAggrStmt, RemoveFuncStmt, RemoveOperStmt,
@ -469,6 +469,7 @@ stmt : AlterDatabaseSetStmt
| DropGroupStmt | DropGroupStmt
| DropPLangStmt | DropPLangStmt
| DropTrigStmt | DropTrigStmt
| DropRuleStmt
| DropUserStmt | DropUserStmt
| ExplainStmt | ExplainStmt
| FetchStmt | FetchStmt
@ -2062,9 +2063,10 @@ ConstraintTimeSpec: INITIALLY IMMEDIATE
DropTrigStmt: DROP TRIGGER name ON qualified_name DropTrigStmt: DROP TRIGGER name ON qualified_name
{ {
DropTrigStmt *n = makeNode(DropTrigStmt); DropPropertyStmt *n = makeNode(DropPropertyStmt);
n->trigname = $3;
n->relation = $5; n->relation = $5;
n->property = $3;
n->removeType = DROP_TRIGGER;
$$ = (Node *) n; $$ = (Node *) n;
} }
; ;
@ -2154,7 +2156,6 @@ drop_type: TABLE { $$ = DROP_TABLE; }
| SEQUENCE { $$ = DROP_SEQUENCE; } | SEQUENCE { $$ = DROP_SEQUENCE; }
| VIEW { $$ = DROP_VIEW; } | VIEW { $$ = DROP_VIEW; }
| INDEX { $$ = DROP_INDEX; } | INDEX { $$ = DROP_INDEX; }
| RULE { $$ = DROP_RULE; }
| TYPE_P { $$ = DROP_TYPE; } | TYPE_P { $$ = DROP_TYPE; }
| DOMAIN_P { $$ = DROP_DOMAIN; } | DOMAIN_P { $$ = DROP_DOMAIN; }
; ;
@ -2191,11 +2192,11 @@ TruncateStmt: TRUNCATE opt_table qualified_name
* The COMMENT ON statement can take different forms based upon the type of * The COMMENT ON statement can take different forms based upon the type of
* the object associated with the comment. The form of the statement is: * the object associated with the comment. The form of the statement is:
* *
* COMMENT ON [ [ DATABASE | DOMAIN | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ] * COMMENT ON [ [ DATABASE | DOMAIN | INDEX | SEQUENCE | TABLE | TYPE | VIEW ]
* <objname> | AGGREGATE <aggname> (<aggtype>) | FUNCTION * <objname> | AGGREGATE <aggname> (<aggtype>) | FUNCTION
* <funcname> (arg1, arg2, ...) | OPERATOR <op> * <funcname> (arg1, arg2, ...) | OPERATOR <op>
* (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON * (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON
* <relname> ] IS 'text' * <relname> | RULE <rulename> ON <relname> ] IS 'text'
* *
*****************************************************************************/ *****************************************************************************/
@ -2244,12 +2245,30 @@ CommentStmt: COMMENT ON comment_type any_name IS comment_text
n->comment = $8; n->comment = $8;
$$ = (Node *) n; $$ = (Node *) n;
} }
| COMMENT ON RULE name ON any_name IS comment_text
{
CommentStmt *n = makeNode(CommentStmt);
n->objtype = RULE;
n->objname = lappend($6, makeString($4));
n->objargs = NIL;
n->comment = $8;
$$ = (Node *) n;
}
| COMMENT ON RULE name IS comment_text
{
/* Obsolete syntax supported for awhile for compatibility */
CommentStmt *n = makeNode(CommentStmt);
n->objtype = RULE;
n->objname = makeList1(makeString($4));
n->objargs = NIL;
n->comment = $6;
$$ = (Node *) n;
}
; ;
comment_type: COLUMN { $$ = COLUMN; } comment_type: COLUMN { $$ = COLUMN; }
| DATABASE { $$ = DATABASE; } | DATABASE { $$ = DATABASE; }
| INDEX { $$ = INDEX; } | INDEX { $$ = INDEX; }
| RULE { $$ = RULE; }
| SEQUENCE { $$ = SEQUENCE; } | SEQUENCE { $$ = SEQUENCE; }
| TABLE { $$ = TABLE; } | TABLE { $$ = TABLE; }
| DOMAIN_P { $$ = TYPE_P; } | DOMAIN_P { $$ = TYPE_P; }
@ -2977,6 +2996,17 @@ opt_instead: INSTEAD { $$ = TRUE; }
; ;
DropRuleStmt: DROP RULE name ON qualified_name
{
DropPropertyStmt *n = makeNode(DropPropertyStmt);
n->relation = $5;
n->property = $3;
n->removeType = DROP_RULE;
$$ = (Node *) n;
}
;
/***************************************************************************** /*****************************************************************************
* *
* QUERY: * QUERY:

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.66 2002/03/26 19:16:02 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteDefine.c,v 1.67 2002/04/18 20:01:09 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -37,7 +37,7 @@ static bool setRuleCheckAsUser_walker(Node *node, Oid *context);
/* /*
* InsertRule - * InsertRule -
* takes the arguments and inserts them as attributes into the system * takes the arguments and inserts them as a row into the system
* relation "pg_rewrite" * relation "pg_rewrite"
*/ */
static Oid static Oid
@ -58,7 +58,7 @@ InsertRule(char *rulname,
HeapTuple tup; HeapTuple tup;
Oid rewriteObjectId; Oid rewriteObjectId;
if (IsDefinedRewriteRule(rulname)) if (IsDefinedRewriteRule(eventrel_oid, rulname))
elog(ERROR, "Attempt to insert rule \"%s\" failed: already exists", elog(ERROR, "Attempt to insert rule \"%s\" failed: already exists",
rulname); rulname);
@ -69,13 +69,13 @@ InsertRule(char *rulname,
i = 0; i = 0;
namestrcpy(&rname, rulname); namestrcpy(&rname, rulname);
values[i++] = NameGetDatum(&rname); values[i++] = NameGetDatum(&rname); /* rulename */
values[i++] = CharGetDatum(evtype + '0'); values[i++] = ObjectIdGetDatum(eventrel_oid); /* ev_class */
values[i++] = ObjectIdGetDatum(eventrel_oid); values[i++] = Int16GetDatum(evslot_index); /* ev_attr */
values[i++] = Int16GetDatum(evslot_index); values[i++] = CharGetDatum(evtype + '0'); /* ev_type */
values[i++] = BoolGetDatum(evinstead); values[i++] = BoolGetDatum(evinstead); /* is_instead */
values[i++] = DirectFunctionCall1(textin, CStringGetDatum(evqual)); values[i++] = DirectFunctionCall1(textin, CStringGetDatum(evqual)); /* ev_qual */
values[i++] = DirectFunctionCall1(textin, CStringGetDatum(actiontree)); values[i++] = DirectFunctionCall1(textin, CStringGetDatum(actiontree)); /* ev_action */
/* /*
* create a new pg_rewrite tuple * create a new pg_rewrite tuple
@ -423,26 +423,27 @@ setRuleCheckAsUser_walker(Node *node, Oid *context)
* ON SELECT rule associated with a view, when the view is renamed. * ON SELECT rule associated with a view, when the view is renamed.
*/ */
void void
RenameRewriteRule(char *oldname, char *newname) RenameRewriteRule(Oid owningRel, const char *oldName,
const char *newName)
{ {
Relation pg_rewrite_desc; Relation pg_rewrite_desc;
HeapTuple ruletup; HeapTuple ruletup;
pg_rewrite_desc = heap_openr(RewriteRelationName, RowExclusiveLock); pg_rewrite_desc = heap_openr(RewriteRelationName, RowExclusiveLock);
ruletup = SearchSysCacheCopy(RULENAME, ruletup = SearchSysCacheCopy(RULERELNAME,
PointerGetDatum(oldname), ObjectIdGetDatum(owningRel),
0, 0, 0); PointerGetDatum(oldName),
0, 0);
if (!HeapTupleIsValid(ruletup)) if (!HeapTupleIsValid(ruletup))
elog(ERROR, "RenameRewriteRule: rule \"%s\" does not exist", oldname); elog(ERROR, "RenameRewriteRule: rule \"%s\" does not exist", oldName);
/* should not already exist */ /* should not already exist */
if (IsDefinedRewriteRule(newname)) if (IsDefinedRewriteRule(owningRel, newName))
elog(ERROR, "Attempt to rename rule \"%s\" failed: \"%s\" already exists", elog(ERROR, "Attempt to rename rule \"%s\" failed: \"%s\" already exists",
oldname, newname); oldName, newName);
StrNCpy(NameStr(((Form_pg_rewrite) GETSTRUCT(ruletup))->rulename), namestrcpy(&(((Form_pg_rewrite) GETSTRUCT(ruletup))->rulename), newName);
newname, NAMEDATALEN);
simple_heap_update(pg_rewrite_desc, &ruletup->t_self, ruletup); simple_heap_update(pg_rewrite_desc, &ruletup->t_self, ruletup);

View File

@ -8,15 +8,16 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.47 2002/03/29 19:06:13 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.48 2002/04/18 20:01:09 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include "utils/builtins.h" #include "access/genam.h"
#include "access/heapam.h" #include "access/heapam.h"
#include "catalog/catname.h" #include "catalog/catname.h"
#include "catalog/indexing.h"
#include "catalog/pg_rewrite.h" #include "catalog/pg_rewrite.h"
#include "commands/comment.h" #include "commands/comment.h"
#include "miscadmin.h" #include "miscadmin.h"
@ -30,12 +31,11 @@
/* /*
* RemoveRewriteRule * RemoveRewriteRule
* *
* Delete a rule given its (possibly qualified) rulename. * Delete a rule given its name.
*/ */
void void
RemoveRewriteRule(List *names) RemoveRewriteRule(Oid owningRel, const char *ruleName)
{ {
char *ruleName;
Relation RewriteRelation; Relation RewriteRelation;
Relation event_relation; Relation event_relation;
HeapTuple tuple; HeapTuple tuple;
@ -44,13 +44,6 @@ RemoveRewriteRule(List *names)
bool hasMoreRules; bool hasMoreRules;
int32 aclcheck_result; int32 aclcheck_result;
/*
* XXX temporary until rules become schema-tized
*/
if (length(names) != 1)
elog(ERROR, "Qualified rule names not supported yet");
ruleName = strVal(lfirst(names));
/* /*
* Open the pg_rewrite relation. * Open the pg_rewrite relation.
*/ */
@ -59,9 +52,10 @@ RemoveRewriteRule(List *names)
/* /*
* Find the tuple for the target rule. * Find the tuple for the target rule.
*/ */
tuple = SearchSysCacheCopy(RULENAME, tuple = SearchSysCacheCopy(RULERELNAME,
ObjectIdGetDatum(owningRel),
PointerGetDatum(ruleName), PointerGetDatum(ruleName),
0, 0, 0); 0, 0);
/* /*
* complain if no rule with such name existed * complain if no rule with such name existed
@ -75,6 +69,7 @@ RemoveRewriteRule(List *names)
*/ */
ruleId = tuple->t_data->t_oid; ruleId = tuple->t_data->t_oid;
eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class; eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
Assert(eventRelationOid == owningRel);
/* /*
* We had better grab AccessExclusiveLock so that we know no other * We had better grab AccessExclusiveLock so that we know no other
@ -137,10 +132,10 @@ RemoveRewriteRule(List *names)
void void
RelationRemoveRules(Oid relid) RelationRemoveRules(Oid relid)
{ {
Relation RewriteRelation = NULL; Relation RewriteRelation;
HeapScanDesc scanDesc = NULL; SysScanDesc scanDesc;
ScanKeyData scanKeyData; ScanKeyData scanKeyData;
HeapTuple tuple = NULL; HeapTuple tuple;
/* /*
* Open the pg_rewrite relation. * Open the pg_rewrite relation.
@ -148,18 +143,21 @@ RelationRemoveRules(Oid relid)
RewriteRelation = heap_openr(RewriteRelationName, RowExclusiveLock); RewriteRelation = heap_openr(RewriteRelationName, RowExclusiveLock);
/* /*
* Scan the RuleRelation ('pg_rewrite') for all the tuples that has * Scan pg_rewrite for all the tuples that have the same ev_class
* the same ev_class as relid (the relation to be removed). * as relid (the relation to be removed).
*/ */
ScanKeyEntryInitialize(&scanKeyData, ScanKeyEntryInitialize(&scanKeyData,
0, 0,
Anum_pg_rewrite_ev_class, Anum_pg_rewrite_ev_class,
F_OIDEQ, F_OIDEQ,
ObjectIdGetDatum(relid)); ObjectIdGetDatum(relid));
scanDesc = heap_beginscan(RewriteRelation,
0, SnapshotNow, 1, &scanKeyData);
while (HeapTupleIsValid(tuple = heap_getnext(scanDesc, 0))) scanDesc = systable_beginscan(RewriteRelation,
RewriteRelRulenameIndex,
true, SnapshotNow,
1, &scanKeyData);
while (HeapTupleIsValid(tuple = systable_getnext(scanDesc)))
{ {
/* Delete any comments associated with this rule */ /* Delete any comments associated with this rule */
DeleteComments(tuple->t_data->t_oid, RelationGetRelid(RewriteRelation)); DeleteComments(tuple->t_data->t_oid, RelationGetRelid(RewriteRelation));
@ -167,6 +165,7 @@ RelationRemoveRules(Oid relid)
simple_heap_delete(RewriteRelation, &tuple->t_self); simple_heap_delete(RewriteRelation, &tuple->t_self);
} }
heap_endscan(scanDesc); systable_endscan(scanDesc);
heap_close(RewriteRelation, RowExclusiveLock); heap_close(RewriteRelation, RowExclusiveLock);
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.49 2001/08/12 21:35:19 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.50 2002/04/18 20:01:09 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -29,11 +29,12 @@
* Is there a rule by the given name? * Is there a rule by the given name?
*/ */
bool bool
IsDefinedRewriteRule(const char *ruleName) IsDefinedRewriteRule(Oid owningRel, const char *ruleName)
{ {
return SearchSysCacheExists(RULENAME, return SearchSysCacheExists(RULERELNAME,
ObjectIdGetDatum(owningRel),
PointerGetDatum(ruleName), PointerGetDatum(ruleName),
0, 0, 0); 0, 0);
} }
/* /*

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.260 2002/03/24 04:31:07 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.261 2002/04/18 20:01:09 tgl Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
@ -1688,7 +1688,7 @@ PostgresMain(int argc, char *argv[], const char *username)
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
puts("\nPOSTGRES backend interactive interface "); puts("\nPOSTGRES backend interactive interface ");
puts("$Revision: 1.260 $ $Date: 2002/03/24 04:31:07 $\n"); puts("$Revision: 1.261 $ $Date: 2002/04/18 20:01:09 $\n");
} }
/* /*
@ -2322,7 +2322,7 @@ CreateCommandTag(Node *parsetree)
tag = "CREATE"; tag = "CREATE";
break; break;
case T_DropTrigStmt: case T_DropPropertyStmt:
tag = "DROP"; tag = "DROP";
break; break;

View File

@ -10,7 +10,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.149 2002/04/15 05:22:04 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.150 2002/04/18 20:01:09 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -312,11 +312,6 @@ ProcessUtility(Node *parsetree,
RemoveIndex(rel); RemoveIndex(rel);
break; break;
case DROP_RULE:
/* RemoveRewriteRule checks permissions */
RemoveRewriteRule(names);
break;
case DROP_TYPE: case DROP_TYPE:
/* RemoveType does its own permissions checks */ /* RemoveType does its own permissions checks */
RemoveType(names); RemoveType(names);
@ -714,12 +709,24 @@ ProcessUtility(Node *parsetree,
CreateTrigger((CreateTrigStmt *) parsetree); CreateTrigger((CreateTrigStmt *) parsetree);
break; break;
case T_DropTrigStmt: case T_DropPropertyStmt:
{ {
DropTrigStmt *stmt = (DropTrigStmt *) parsetree; DropPropertyStmt *stmt = (DropPropertyStmt *) parsetree;
Oid relId;
DropTrigger(RangeVarGetRelid(stmt->relation, false), relId = RangeVarGetRelid(stmt->relation, false);
stmt->trigname);
switch (stmt->removeType)
{
case DROP_RULE:
/* RemoveRewriteRule checks permissions */
RemoveRewriteRule(relId, stmt->property);
break;
case DROP_TRIGGER:
/* DropTrigger checks permissions */
DropTrigger(relId, stmt->property);
break;
}
} }
break; break;

View File

@ -3,7 +3,7 @@
* back to source text * back to source text
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.96 2002/04/11 20:00:04 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.97 2002/04/18 20:01:09 tgl Exp $
* *
* This software is copyrighted by Jan Wieck - Hamburg. * This software is copyrighted by Jan Wieck - Hamburg.
* *
@ -42,6 +42,7 @@
#include "catalog/heap.h" #include "catalog/heap.h"
#include "catalog/index.h" #include "catalog/index.h"
#include "catalog/namespace.h"
#include "catalog/pg_index.h" #include "catalog/pg_index.h"
#include "catalog/pg_opclass.h" #include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h" #include "catalog/pg_operator.h"
@ -97,11 +98,10 @@ typedef struct
* Global data * Global data
* ---------- * ----------
*/ */
static char *rulename = NULL; static void *plan_getrulebyoid = NULL;
static void *plan_getrule = NULL; static char *query_getrulebyoid = "SELECT * FROM pg_rewrite WHERE oid = $1";
static char *query_getrule = "SELECT * FROM pg_rewrite WHERE rulename = $1"; static void *plan_getviewrule = NULL;
static void *plan_getview = NULL; static char *query_getviewrule = "SELECT * FROM pg_rewrite WHERE ev_class = $1 AND rulename = $2";
static char *query_getview = "SELECT * FROM pg_rewrite WHERE rulename = $1";
/* ---------- /* ----------
@ -112,6 +112,7 @@ static char *query_getview = "SELECT * FROM pg_rewrite WHERE rulename = $1";
* as a parameter, and append their text output to its contents. * as a parameter, and append their text output to its contents.
* ---------- * ----------
*/ */
static text *pg_do_getviewdef(Oid viewoid);
static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc); static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc);
static void make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc); static void make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc);
static void get_query_def(Query *query, StringInfo buf, List *parentnamespace); static void get_query_def(Query *query, StringInfo buf, List *parentnamespace);
@ -156,21 +157,16 @@ static char *get_relid_attribute_name(Oid relid, AttrNumber attnum);
Datum Datum
pg_get_ruledef(PG_FUNCTION_ARGS) pg_get_ruledef(PG_FUNCTION_ARGS)
{ {
Name rname = PG_GETARG_NAME(0); Oid ruleoid = PG_GETARG_OID(0);
text *ruledef; text *ruledef;
Datum args[1]; Datum args[1];
char nulls[2]; char nulls[1];
int spirc; int spirc;
HeapTuple ruletup; HeapTuple ruletup;
TupleDesc rulettc; TupleDesc rulettc;
StringInfoData buf; StringInfoData buf;
int len; int len;
/*
* We need the rules name somewhere deep down: rulename is global
*/
rulename = pstrdup(NameStr(*rname));
/* /*
* Connect to SPI manager * Connect to SPI manager
*/ */
@ -182,27 +178,26 @@ pg_get_ruledef(PG_FUNCTION_ARGS)
* pg_rewrite over the SPI manager instead of using the syscache to be * pg_rewrite over the SPI manager instead of using the syscache to be
* checked for read access on pg_rewrite. * checked for read access on pg_rewrite.
*/ */
if (plan_getrule == NULL) if (plan_getrulebyoid == NULL)
{ {
Oid argtypes[1]; Oid argtypes[1];
void *plan; void *plan;
argtypes[0] = NAMEOID; argtypes[0] = OIDOID;
plan = SPI_prepare(query_getrule, 1, argtypes); plan = SPI_prepare(query_getrulebyoid, 1, argtypes);
if (plan == NULL) if (plan == NULL)
elog(ERROR, "SPI_prepare() failed for \"%s\"", query_getrule); elog(ERROR, "SPI_prepare() failed for \"%s\"", query_getrulebyoid);
plan_getrule = SPI_saveplan(plan); plan_getrulebyoid = SPI_saveplan(plan);
} }
/* /*
* Get the pg_rewrite tuple for this rule * Get the pg_rewrite tuple for this rule
*/ */
args[0] = PointerGetDatum(rulename); args[0] = ObjectIdGetDatum(ruleoid);
nulls[0] = (rulename == NULL) ? 'n' : ' '; nulls[0] = ' ';
nulls[1] = '\0'; spirc = SPI_execp(plan_getrulebyoid, args, nulls, 1);
spirc = SPI_execp(plan_getrule, args, nulls, 1);
if (spirc != SPI_OK_SELECT) if (spirc != SPI_OK_SELECT)
elog(ERROR, "failed to get pg_rewrite tuple for %s", rulename); elog(ERROR, "failed to get pg_rewrite tuple for %u", ruleoid);
if (SPI_processed != 1) if (SPI_processed != 1)
{ {
if (SPI_finish() != SPI_OK_FINISH) if (SPI_finish() != SPI_OK_FINISH)
@ -248,22 +243,48 @@ pg_get_ruledef(PG_FUNCTION_ARGS)
Datum Datum
pg_get_viewdef(PG_FUNCTION_ARGS) pg_get_viewdef(PG_FUNCTION_ARGS)
{ {
Name vname = PG_GETARG_NAME(0); /* By OID */
Oid viewoid = PG_GETARG_OID(0);
text *ruledef; text *ruledef;
Datum args[1];
char nulls[1]; ruledef = pg_do_getviewdef(viewoid);
PG_RETURN_TEXT_P(ruledef);
}
Datum
pg_get_viewdef_name(PG_FUNCTION_ARGS)
{
/* By qualified name */
text *viewname = PG_GETARG_TEXT_P(0);
RangeVar *viewrel;
Oid viewoid;
text *ruledef;
viewrel = makeRangeVarFromNameList(textToQualifiedNameList(viewname,
"get_viewdef"));
viewoid = RangeVarGetRelid(viewrel, false);
ruledef = pg_do_getviewdef(viewoid);
PG_RETURN_TEXT_P(ruledef);
}
/*
* Common code for by-OID and by-name variants of pg_get_viewdef
*/
static text *
pg_do_getviewdef(Oid viewoid)
{
text *ruledef;
Datum args[2];
char nulls[2];
int spirc; int spirc;
HeapTuple ruletup; HeapTuple ruletup;
TupleDesc rulettc; TupleDesc rulettc;
StringInfoData buf; StringInfoData buf;
int len; int len;
char *viewname;
char *name; char *name;
/*
* We need the view name somewhere deep down
*/
rulename = pstrdup(NameStr(*vname));
/* /*
* Connect to SPI manager * Connect to SPI manager
*/ */
@ -275,28 +296,31 @@ pg_get_viewdef(PG_FUNCTION_ARGS)
* pg_rewrite over the SPI manager instead of using the syscache to be * pg_rewrite over the SPI manager instead of using the syscache to be
* checked for read access on pg_rewrite. * checked for read access on pg_rewrite.
*/ */
if (plan_getview == NULL) if (plan_getviewrule == NULL)
{ {
Oid argtypes[1]; Oid argtypes[2];
void *plan; void *plan;
argtypes[0] = NAMEOID; argtypes[0] = OIDOID;
plan = SPI_prepare(query_getview, 1, argtypes); argtypes[1] = NAMEOID;
plan = SPI_prepare(query_getviewrule, 2, argtypes);
if (plan == NULL) if (plan == NULL)
elog(ERROR, "SPI_prepare() failed for \"%s\"", query_getview); elog(ERROR, "SPI_prepare() failed for \"%s\"", query_getviewrule);
plan_getview = SPI_saveplan(plan); plan_getviewrule = SPI_saveplan(plan);
} }
/* /*
* Get the pg_rewrite tuple for this rule: rulename is actually * Get the pg_rewrite tuple for the view's SELECT rule
* viewname here
*/ */
name = MakeRetrieveViewRuleName(rulename); viewname = get_rel_name(viewoid);
args[0] = PointerGetDatum(name); name = MakeRetrieveViewRuleName(viewname);
args[0] = ObjectIdGetDatum(viewoid);
args[1] = PointerGetDatum(name);
nulls[0] = ' '; nulls[0] = ' ';
spirc = SPI_execp(plan_getview, args, nulls, 1); nulls[1] = ' ';
spirc = SPI_execp(plan_getviewrule, args, nulls, 2);
if (spirc != SPI_OK_SELECT) if (spirc != SPI_OK_SELECT)
elog(ERROR, "failed to get pg_rewrite tuple for view %s", rulename); elog(ERROR, "failed to get pg_rewrite tuple for view %s", viewname);
initStringInfo(&buf); initStringInfo(&buf);
if (SPI_processed != 1) if (SPI_processed != 1)
appendStringInfo(&buf, "Not a view"); appendStringInfo(&buf, "Not a view");
@ -322,10 +346,7 @@ pg_get_viewdef(PG_FUNCTION_ARGS)
if (SPI_finish() != SPI_OK_FINISH) if (SPI_finish() != SPI_OK_FINISH)
elog(ERROR, "get_viewdef: SPI_finish() failed"); elog(ERROR, "get_viewdef: SPI_finish() failed");
/* return ruledef;
* Easy - isn't it?
*/
PG_RETURN_TEXT_P(ruledef);
} }
@ -633,8 +654,6 @@ deparse_expression(Node *expr, List *dpcontext, bool forceprefix)
context.namespaces = dpcontext; context.namespaces = dpcontext;
context.varprefix = forceprefix; context.varprefix = forceprefix;
rulename = ""; /* in case of errors */
get_rule_expr(expr, &context); get_rule_expr(expr, &context);
return buf.data; return buf.data;
@ -792,6 +811,7 @@ deparse_context_for_subplan(const char *name, List *tlist,
static void static void
make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc) make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc)
{ {
char *rulename;
char ev_type; char ev_type;
Oid ev_class; Oid ev_class;
int2 ev_attr; int2 ev_attr;
@ -800,23 +820,38 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc)
char *ev_action; char *ev_action;
List *actions = NIL; List *actions = NIL;
int fno; int fno;
Datum dat;
bool isnull; bool isnull;
/* /*
* Get the attribute values from the rules tuple * Get the attribute values from the rules tuple
*/ */
fno = SPI_fnumber(rulettc, "rulename");
dat = SPI_getbinval(ruletup, rulettc, fno, &isnull);
Assert(!isnull);
rulename = NameStr(*(DatumGetName(dat)));
fno = SPI_fnumber(rulettc, "ev_type"); fno = SPI_fnumber(rulettc, "ev_type");
ev_type = (char) SPI_getbinval(ruletup, rulettc, fno, &isnull); dat = SPI_getbinval(ruletup, rulettc, fno, &isnull);
Assert(!isnull);
ev_type = DatumGetChar(dat);
fno = SPI_fnumber(rulettc, "ev_class"); fno = SPI_fnumber(rulettc, "ev_class");
ev_class = (Oid) SPI_getbinval(ruletup, rulettc, fno, &isnull); dat = SPI_getbinval(ruletup, rulettc, fno, &isnull);
Assert(!isnull);
ev_class = DatumGetObjectId(dat);
fno = SPI_fnumber(rulettc, "ev_attr"); fno = SPI_fnumber(rulettc, "ev_attr");
ev_attr = (int2) SPI_getbinval(ruletup, rulettc, fno, &isnull); dat = SPI_getbinval(ruletup, rulettc, fno, &isnull);
Assert(!isnull);
ev_attr = DatumGetInt16(dat);
fno = SPI_fnumber(rulettc, "is_instead"); fno = SPI_fnumber(rulettc, "is_instead");
is_instead = (bool) SPI_getbinval(ruletup, rulettc, fno, &isnull); dat = SPI_getbinval(ruletup, rulettc, fno, &isnull);
Assert(!isnull);
is_instead = DatumGetBool(dat);
/* these could be nulls */
fno = SPI_fnumber(rulettc, "ev_qual"); fno = SPI_fnumber(rulettc, "ev_qual");
ev_qual = SPI_getvalue(ruletup, rulettc, fno); ev_qual = SPI_getvalue(ruletup, rulettc, fno);
@ -1051,8 +1086,8 @@ get_query_def(Query *query, StringInfo buf, List *parentnamespace)
break; break;
default: default:
elog(ERROR, "get_ruledef of %s: query command type %d not implemented yet", elog(ERROR, "get_query_def: unknown query command type %d",
rulename, query->commandType); query->commandType);
break; break;
} }
} }
@ -1901,9 +1936,7 @@ get_rule_expr(Node *node, deparse_context *context)
break; break;
default: default:
printf("\n%s\n", nodeToString(node)); elog(ERROR, "get_rule_expr: unknown node type %d", nodeTag(node));
elog(ERROR, "get_ruledef of %s: unknown node type %d in get_rule_expr()",
rulename, nodeTag(node));
break; break;
} }
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.160 2002/04/12 20:38:29 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.161 2002/04/18 20:01:09 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -675,17 +675,18 @@ RelationBuildRuleLock(Relation relation)
/* /*
* open pg_rewrite and begin a scan * open pg_rewrite and begin a scan
*
* XXX: there is no suitable index for this scan. FIXME.
*/ */
pg_rewrite_desc = heap_openr(RewriteRelationName, AccessShareLock); pg_rewrite_desc = heap_openr(RewriteRelationName, AccessShareLock);
pg_rewrite_tupdesc = RelationGetDescr(pg_rewrite_desc); pg_rewrite_tupdesc = RelationGetDescr(pg_rewrite_desc);
pg_rewrite_scan = systable_beginscan(pg_rewrite_desc, NULL, false, pg_rewrite_scan = systable_beginscan(pg_rewrite_desc,
RewriteRelRulenameIndex,
criticalRelcachesBuilt,
SnapshotNow, SnapshotNow,
1, &key); 1, &key);
while (HeapTupleIsValid(pg_rewrite_tuple = systable_getnext(pg_rewrite_scan))) while (HeapTupleIsValid(pg_rewrite_tuple = systable_getnext(pg_rewrite_scan)))
{ {
Form_pg_rewrite rewrite_form = (Form_pg_rewrite) GETSTRUCT(pg_rewrite_tuple);
bool isnull; bool isnull;
Datum ruleaction; Datum ruleaction;
Datum rule_evqual; Datum rule_evqual;
@ -698,18 +699,11 @@ RelationBuildRuleLock(Relation relation)
rule->ruleId = pg_rewrite_tuple->t_data->t_oid; rule->ruleId = pg_rewrite_tuple->t_data->t_oid;
rule->event = DatumGetInt32(heap_getattr(pg_rewrite_tuple, rule->event = rewrite_form->ev_type - '0';
Anum_pg_rewrite_ev_type, rule->attrno = rewrite_form->ev_attr;
pg_rewrite_tupdesc, rule->isInstead = rewrite_form->is_instead;
&isnull)) - 48;
rule->attrno = DatumGetInt16(heap_getattr(pg_rewrite_tuple, /* Must use heap_getattr to fetch ev_qual and ev_action */
Anum_pg_rewrite_ev_attr,
pg_rewrite_tupdesc,
&isnull));
rule->isInstead = DatumGetBool(heap_getattr(pg_rewrite_tuple,
Anum_pg_rewrite_is_instead,
pg_rewrite_tupdesc,
&isnull));
ruleaction = heap_getattr(pg_rewrite_tuple, ruleaction = heap_getattr(pg_rewrite_tuple,
Anum_pg_rewrite_ev_action, Anum_pg_rewrite_ev_action,

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.78 2002/04/17 20:57:56 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.79 2002/04/18 20:01:10 tgl Exp $
* *
* NOTES * NOTES
* These routines allow the parser/planner/executor to perform * These routines allow the parser/planner/executor to perform
@ -333,14 +333,14 @@ static const struct cachedesc cacheinfo[] = {
0, 0,
0 0
}}, }},
{RewriteRelationName, /* RULENAME */ {RewriteRelationName, /* RULERELNAME */
RewriteRulenameIndex, RewriteRelRulenameIndex,
Anum_pg_rewrite_ev_class, Anum_pg_rewrite_ev_class,
1, 2,
{ {
Anum_pg_rewrite_ev_class,
Anum_pg_rewrite_rulename, Anum_pg_rewrite_rulename,
0, 0,
0,
0 0
}}, }},
{ShadowRelationName, /* SHADOWNAME */ {ShadowRelationName, /* SHADOWNAME */

View File

@ -27,7 +27,7 @@
# Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group # Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California # Portions Copyright (c) 1994, Regents of the University of California
# #
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.148 2002/04/15 22:33:21 tgl Exp $ # $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.149 2002/04/18 20:01:10 tgl Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -689,19 +689,21 @@ CREATE VIEW pg_user AS \
CREATE VIEW pg_rules AS \ CREATE VIEW pg_rules AS \
SELECT \ SELECT \
N.nspname AS schemaname, \
C.relname AS tablename, \ C.relname AS tablename, \
R.rulename AS rulename, \ R.rulename AS rulename, \
pg_get_ruledef(R.rulename) AS definition \ pg_get_ruledef(R.oid) AS definition \
FROM pg_rewrite R, pg_class C \ FROM (pg_rewrite R JOIN pg_class C ON (C.oid = R.ev_class)) \
WHERE R.rulename !~ '^_RET' \ LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) \
AND C.oid = R.ev_class; WHERE R.rulename !~ '^_RET';
CREATE VIEW pg_views AS \ CREATE VIEW pg_views AS \
SELECT \ SELECT \
N.nspname AS schemaname, \
C.relname AS viewname, \ C.relname AS viewname, \
pg_get_userbyid(C.relowner) AS viewowner, \ pg_get_userbyid(C.relowner) AS viewowner, \
pg_get_viewdef(C.relname) AS definition \ pg_get_viewdef(C.oid) AS definition \
FROM pg_class C \ FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) \
WHERE C.relkind = 'v'; WHERE C.relkind = 'v';
-- XXX why does pg_tables include sequences? -- XXX why does pg_tables include sequences?

View File

@ -22,7 +22,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.248 2002/04/13 19:57:18 momjian Exp $ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.249 2002/04/18 20:01:10 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -2274,17 +2274,28 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs, const char *tablename)
PGresult *res2; PGresult *res2;
resetPQExpBuffer(query); resetPQExpBuffer(query);
appendPQExpBuffer(query, "SELECT definition as viewdef, ");
/* if (g_fout->remoteVersion < 70300)
* XXX 7.2 - replace with att from pg_views or some other {
* generic source appendPQExpBuffer(query, "SELECT definition as viewdef, "
*/ "(select oid from pg_rewrite where "
appendPQExpBuffer(query, "(select oid from pg_rewrite where " " rulename=('_RET' || viewname)::name) as view_oid"
" rulename=('_RET' || viewname)::name) as view_oid" " from pg_views where viewname = ");
" from pg_views where viewname = "); formatStringLiteral(query, tblinfo[i].relname, CONV_ALL);
formatStringLiteral(query, tblinfo[i].relname, CONV_ALL); appendPQExpBuffer(query, ";");
appendPQExpBuffer(query, ";"); }
else
{
/* Beginning in 7.3, viewname is not unique; use OID */
appendPQExpBuffer(query, "SELECT pg_get_viewdef(ev_class) as viewdef, "
"oid as view_oid"
" from pg_rewrite where"
" ev_class = '%s'::oid and"
" rulename = ('_RET' || ",
tblinfo[i].oid);
formatStringLiteral(query, tblinfo[i].relname, CONV_ALL);
appendPQExpBuffer(query, ")::name;");
}
res2 = PQexec(g_conn, query->data); res2 = PQexec(g_conn, query->data);
if (!res2 || PQresultStatus(res2) != PGRES_TUPLES_OK) if (!res2 || PQresultStatus(res2) != PGRES_TUPLES_OK)
@ -4995,23 +5006,41 @@ dumpRules(Archive *fout, const char *tablename,
continue; continue;
/* /*
* Get all rules defined for this table We include pg_rules in the * Get all rules defined for this table
* cross since it filters out all view rules (pjw 15-Sep-2000).
*
* XXXX: Use LOJ here
*/ */
resetPQExpBuffer(query); resetPQExpBuffer(query);
appendPQExpBuffer(query, "SELECT definition,"
" (select usename from pg_user where pg_class.relowner = usesysid) AS viewowner, " if (g_fout->remoteVersion < 70300)
" pg_rewrite.oid, pg_rewrite.rulename " {
"FROM pg_rewrite, pg_class, pg_rules " /*
"WHERE pg_class.relname = "); * We include pg_rules in the cross since it filters out all view
formatStringLiteral(query, tblinfo[t].relname, CONV_ALL); * rules (pjw 15-Sep-2000).
appendPQExpBuffer(query, */
" AND pg_rewrite.ev_class = pg_class.oid " appendPQExpBuffer(query, "SELECT definition,"
" AND pg_rules.tablename = pg_class.relname " " (select usename from pg_user where pg_class.relowner = usesysid) AS viewowner, "
" AND pg_rules.rulename = pg_rewrite.rulename " " pg_rewrite.oid, pg_rewrite.rulename "
"ORDER BY pg_rewrite.oid"); "FROM pg_rewrite, pg_class, pg_rules "
"WHERE pg_class.relname = ");
formatStringLiteral(query, tblinfo[t].relname, CONV_ALL);
appendPQExpBuffer(query,
" AND pg_rewrite.ev_class = pg_class.oid "
" AND pg_rules.tablename = pg_class.relname "
" AND pg_rules.rulename = pg_rewrite.rulename "
"ORDER BY pg_rewrite.oid");
}
else
{
appendPQExpBuffer(query, "SELECT pg_get_ruledef(pg_rewrite.oid) AS definition,"
" (select usename from pg_user where pg_class.relowner = usesysid) AS viewowner, "
" pg_rewrite.oid, pg_rewrite.rulename "
"FROM pg_rewrite, pg_class "
"WHERE pg_class.oid = '%s'::oid "
" AND pg_rewrite.ev_class = pg_class.oid "
" AND pg_rewrite.rulename !~ '^_RET' "
"ORDER BY pg_rewrite.oid",
tblinfo[t].oid);
}
res = PQexec(g_conn, query->data); res = PQexec(g_conn, query->data);
if (!res || if (!res ||
PQresultStatus(res) != PGRES_TUPLES_OK) PQresultStatus(res) != PGRES_TUPLES_OK)
@ -5041,6 +5070,7 @@ dumpRules(Archive *fout, const char *tablename,
resetPQExpBuffer(query); resetPQExpBuffer(query);
appendPQExpBuffer(query, "RULE %s", fmtId(PQgetvalue(res, i, i_rulename), force_quotes)); appendPQExpBuffer(query, "RULE %s", fmtId(PQgetvalue(res, i, i_rulename), force_quotes));
appendPQExpBuffer(query, " ON %s", fmtId(tblinfo[t].relname, force_quotes));
dumpComment(fout, query->data, PQgetvalue(res, i, i_oid), dumpComment(fout, query->data, PQgetvalue(res, i, i_oid),
"pg_rewrite", 0, NULL); "pg_rewrite", 0, NULL);

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: catversion.h,v 1.117 2002/04/17 20:57:56 tgl Exp $ * $Id: catversion.h,v 1.118 2002/04/18 20:01:10 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200204171 #define CATALOG_VERSION_NO 200204181
#endif #endif

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: indexing.h,v 1.64 2002/04/17 20:57:56 tgl Exp $ * $Id: indexing.h,v 1.65 2002/04/18 20:01:10 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -80,7 +80,7 @@
#define ProcedureOidIndex "pg_proc_oid_index" #define ProcedureOidIndex "pg_proc_oid_index"
#define RelCheckIndex "pg_relcheck_rcrelid_index" #define RelCheckIndex "pg_relcheck_rcrelid_index"
#define RewriteOidIndex "pg_rewrite_oid_index" #define RewriteOidIndex "pg_rewrite_oid_index"
#define RewriteRulenameIndex "pg_rewrite_rulename_index" #define RewriteRelRulenameIndex "pg_rewrite_rel_rulename_index"
#define ShadowNameIndex "pg_shadow_usename_index" #define ShadowNameIndex "pg_shadow_usename_index"
#define ShadowSysidIndex "pg_shadow_usesysid_index" #define ShadowSysidIndex "pg_shadow_usesysid_index"
#define StatisticRelidAttnumIndex "pg_statistic_relid_att_index" #define StatisticRelidAttnumIndex "pg_statistic_relid_att_index"
@ -178,7 +178,7 @@ DECLARE_UNIQUE_INDEX(pg_proc_proname_args_nsp_index on pg_proc using btree(prona
/* This following index is not used for a cache and is not unique */ /* This following index is not used for a cache and is not unique */
DECLARE_INDEX(pg_relcheck_rcrelid_index on pg_relcheck using btree(rcrelid oid_ops)); DECLARE_INDEX(pg_relcheck_rcrelid_index on pg_relcheck using btree(rcrelid oid_ops));
DECLARE_UNIQUE_INDEX(pg_rewrite_oid_index on pg_rewrite using btree(oid oid_ops)); DECLARE_UNIQUE_INDEX(pg_rewrite_oid_index on pg_rewrite using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_rewrite_rulename_index on pg_rewrite using btree(rulename name_ops)); DECLARE_UNIQUE_INDEX(pg_rewrite_rel_rulename_index on pg_rewrite using btree(ev_class oid_ops, rulename name_ops));
DECLARE_UNIQUE_INDEX(pg_shadow_usename_index on pg_shadow using btree(usename name_ops)); DECLARE_UNIQUE_INDEX(pg_shadow_usename_index on pg_shadow using btree(usename name_ops));
DECLARE_UNIQUE_INDEX(pg_shadow_usesysid_index on pg_shadow using btree(usesysid int4_ops)); DECLARE_UNIQUE_INDEX(pg_shadow_usesysid_index on pg_shadow using btree(usesysid int4_ops));
DECLARE_UNIQUE_INDEX(pg_statistic_relid_att_index on pg_statistic using btree(starelid oid_ops, staattnum int2_ops)); DECLARE_UNIQUE_INDEX(pg_statistic_relid_att_index on pg_statistic using btree(starelid oid_ops, staattnum int2_ops));

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_proc.h,v 1.227 2002/04/11 20:00:12 tgl Exp $ * $Id: pg_proc.h,v 1.228 2002/04/18 20:01:10 tgl Exp $
* *
* NOTES * NOTES
* The script catalog/genbki.sh reads this file and generates .bki * The script catalog/genbki.sh reads this file and generates .bki
@ -2150,9 +2150,11 @@ DATA(insert OID = 1639 ( oidge PGNSP PGUID 12 f t f t f i 2 16 "26 26" 10
DESCR("greater-than-or-equal"); DESCR("greater-than-or-equal");
/* System-view support functions */ /* System-view support functions */
DATA(insert OID = 1640 ( pg_get_ruledef PGNSP PGUID 12 f t f t f s 1 25 "19" 100 0 0 100 pg_get_ruledef - _null_ )); DATA(insert OID = 1573 ( pg_get_ruledef PGNSP PGUID 12 f t f t f s 1 25 "26" 100 0 0 100 pg_get_ruledef - _null_ ));
DESCR("source text of a rule"); DESCR("source text of a rule");
DATA(insert OID = 1641 ( pg_get_viewdef PGNSP PGUID 12 f t f t f s 1 25 "19" 100 0 0 100 pg_get_viewdef - _null_ )); DATA(insert OID = 1640 ( pg_get_viewdef PGNSP PGUID 12 f t f t f s 1 25 "25" 100 0 0 100 pg_get_viewdef_name - _null_ ));
DESCR("select statement of a view");
DATA(insert OID = 1641 ( pg_get_viewdef PGNSP PGUID 12 f t f t f s 1 25 "26" 100 0 0 100 pg_get_viewdef - _null_ ));
DESCR("select statement of a view"); DESCR("select statement of a view");
DATA(insert OID = 1642 ( pg_get_userbyid PGNSP PGUID 12 f t f t f s 1 19 "23" 100 0 0 100 pg_get_userbyid - _null_ )); DATA(insert OID = 1642 ( pg_get_userbyid PGNSP PGUID 12 f t f t f s 1 19 "23" 100 0 0 100 pg_get_userbyid - _null_ ));
DESCR("user name by UID (with fallback)"); DESCR("user name by UID (with fallback)");

View File

@ -4,11 +4,14 @@
* definition of the system "rewrite-rule" relation (pg_rewrite) * definition of the system "rewrite-rule" relation (pg_rewrite)
* along with the relation's initial contents. * along with the relation's initial contents.
* *
* As of Postgres 7.3, the primary key for this table is <ev_class, rulename>
* --- ie, rule names are only unique among the rules of a given table.
*
* *
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_rewrite.h,v 1.17 2001/11/05 17:46:32 momjian Exp $ * $Id: pg_rewrite.h,v 1.18 2002/04/18 20:01:11 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
@ -34,9 +37,9 @@
CATALOG(pg_rewrite) CATALOG(pg_rewrite)
{ {
NameData rulename; NameData rulename;
char ev_type;
Oid ev_class; Oid ev_class;
int2 ev_attr; int2 ev_attr;
char ev_type;
bool is_instead; bool is_instead;
/* NB: remaining fields must be accessed via heap_getattr */ /* NB: remaining fields must be accessed via heap_getattr */
@ -57,9 +60,9 @@ typedef FormData_pg_rewrite *Form_pg_rewrite;
*/ */
#define Natts_pg_rewrite 7 #define Natts_pg_rewrite 7
#define Anum_pg_rewrite_rulename 1 #define Anum_pg_rewrite_rulename 1
#define Anum_pg_rewrite_ev_type 2 #define Anum_pg_rewrite_ev_class 2
#define Anum_pg_rewrite_ev_class 3 #define Anum_pg_rewrite_ev_attr 3
#define Anum_pg_rewrite_ev_attr 4 #define Anum_pg_rewrite_ev_type 4
#define Anum_pg_rewrite_is_instead 5 #define Anum_pg_rewrite_is_instead 5
#define Anum_pg_rewrite_ev_qual 6 #define Anum_pg_rewrite_ev_qual 6
#define Anum_pg_rewrite_ev_action 7 #define Anum_pg_rewrite_ev_action 7

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: nodes.h,v 1.104 2002/04/05 11:56:54 momjian Exp $ * $Id: nodes.h,v 1.105 2002/04/18 20:01:11 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -181,7 +181,7 @@ typedef enum NodeTag
T_VariableShowStmt, T_VariableShowStmt,
T_VariableResetStmt, T_VariableResetStmt,
T_CreateTrigStmt, T_CreateTrigStmt,
T_DropTrigStmt, T_DropPropertyStmt,
T_CreatePLangStmt, T_CreatePLangStmt,
T_DropPLangStmt, T_DropPLangStmt,
T_CreateUserStmt, T_CreateUserStmt,

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: parsenodes.h,v 1.171 2002/04/17 20:57:57 tgl Exp $ * $Id: parsenodes.h,v 1.172 2002/04/18 20:01:11 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -940,13 +940,6 @@ typedef struct CreateTrigStmt
RangeVar *constrrel; /* opposite relation */ RangeVar *constrrel; /* opposite relation */
} CreateTrigStmt; } CreateTrigStmt;
typedef struct DropTrigStmt
{
NodeTag type;
char *trigname; /* TRIGGER' name */
RangeVar *relation; /* triggered relation */
} DropTrigStmt;
/* ---------------------- /* ----------------------
* Create/Drop PROCEDURAL LANGUAGE Statement * Create/Drop PROCEDURAL LANGUAGE Statement
* ---------------------- * ----------------------
@ -1060,7 +1053,7 @@ typedef struct CreateDomainStmt
} CreateDomainStmt; } CreateDomainStmt;
/* ---------------------- /* ----------------------
* Drop Table|Sequence|View|Index|Rule|Type Statement * Drop Table|Sequence|View|Index|Type|Domain Statement
* ---------------------- * ----------------------
*/ */
@ -1068,9 +1061,8 @@ typedef struct CreateDomainStmt
#define DROP_SEQUENCE 2 #define DROP_SEQUENCE 2
#define DROP_VIEW 3 #define DROP_VIEW 3
#define DROP_INDEX 4 #define DROP_INDEX 4
#define DROP_RULE 5 #define DROP_TYPE 5
#define DROP_TYPE 6 #define DROP_DOMAIN 6
#define DROP_DOMAIN 7
typedef struct DropStmt typedef struct DropStmt
{ {
@ -1080,6 +1072,25 @@ typedef struct DropStmt
int behavior; /* CASCADE or RESTRICT drop behavior */ int behavior; /* CASCADE or RESTRICT drop behavior */
} DropStmt; } DropStmt;
/* ----------------------
* Drop Rule|Trigger Statement
*
* In general this may be used for dropping any property of a relation;
* for example, someday soon we may have DROP ATTRIBUTE.
* ----------------------
*/
#define DROP_RULE 100
#define DROP_TRIGGER 101
typedef struct DropPropertyStmt
{
NodeTag type;
RangeVar *relation; /* owning relation */
char *property; /* name of rule, trigger, etc */
int removeType;
} DropPropertyStmt;
/* ---------------------- /* ----------------------
* Truncate Table Statement * Truncate Table Statement
* ---------------------- * ----------------------

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: rewriteDefine.h,v 1.13 2001/11/05 17:46:35 momjian Exp $ * $Id: rewriteDefine.h,v 1.14 2002/04/18 20:01:11 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -18,6 +18,7 @@
extern void DefineQueryRewrite(RuleStmt *args); extern void DefineQueryRewrite(RuleStmt *args);
extern void RenameRewriteRule(char *oldname, char *newname); extern void RenameRewriteRule(Oid owningRel, const char *oldName,
const char *newName);
#endif /* REWRITEDEFINE_H */ #endif /* REWRITEDEFINE_H */

View File

@ -7,14 +7,14 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: rewriteRemove.h,v 1.12 2002/03/29 19:06:26 tgl Exp $ * $Id: rewriteRemove.h,v 1.13 2002/04/18 20:01:11 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef REWRITEREMOVE_H #ifndef REWRITEREMOVE_H
#define REWRITEREMOVE_H #define REWRITEREMOVE_H
extern void RemoveRewriteRule(List *names); extern void RemoveRewriteRule(Oid owningRel, const char *ruleName);
extern void RelationRemoveRules(Oid relid); extern void RelationRemoveRules(Oid relid);
#endif /* REWRITEREMOVE_H */ #endif /* REWRITEREMOVE_H */

View File

@ -7,14 +7,14 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: rewriteSupport.h,v 1.20 2001/11/05 17:46:35 momjian Exp $ * $Id: rewriteSupport.h,v 1.21 2002/04/18 20:01:11 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#ifndef REWRITESUPPORT_H #ifndef REWRITESUPPORT_H
#define REWRITESUPPORT_H #define REWRITESUPPORT_H
extern bool IsDefinedRewriteRule(const char *ruleName); extern bool IsDefinedRewriteRule(Oid owningRel, const char *ruleName);
extern char *MakeRetrieveViewRuleName(const char *view_name); extern char *MakeRetrieveViewRuleName(const char *view_name);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: builtins.h,v 1.176 2002/04/11 20:00:17 tgl Exp $ * $Id: builtins.h,v 1.177 2002/04/18 20:01:11 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -337,6 +337,7 @@ extern Datum regproctooid(PG_FUNCTION_ARGS);
/* ruleutils.c */ /* ruleutils.c */
extern Datum pg_get_ruledef(PG_FUNCTION_ARGS); extern Datum pg_get_ruledef(PG_FUNCTION_ARGS);
extern Datum pg_get_viewdef(PG_FUNCTION_ARGS); extern Datum pg_get_viewdef(PG_FUNCTION_ARGS);
extern Datum pg_get_viewdef_name(PG_FUNCTION_ARGS);
extern Datum pg_get_indexdef(PG_FUNCTION_ARGS); extern Datum pg_get_indexdef(PG_FUNCTION_ARGS);
extern Datum pg_get_userbyid(PG_FUNCTION_ARGS); extern Datum pg_get_userbyid(PG_FUNCTION_ARGS);
extern Datum pg_get_expr(PG_FUNCTION_ARGS); extern Datum pg_get_expr(PG_FUNCTION_ARGS);

View File

@ -9,7 +9,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: syscache.h,v 1.46 2002/04/17 20:57:57 tgl Exp $ * $Id: syscache.h,v 1.47 2002/04/18 20:01:11 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -52,7 +52,7 @@
#define PROCOID 21 #define PROCOID 21
#define RELNAMENSP 22 #define RELNAMENSP 22
#define RELOID 23 #define RELOID 23
#define RULENAME 24 #define RULERELNAME 24
#define SHADOWNAME 25 #define SHADOWNAME 25
#define SHADOWSYSID 26 #define SHADOWSYSID 26
#define STATRELATT 27 #define STATRELATT 27

View File

@ -217,13 +217,13 @@ ERROR: parser: parse error at or near ";"
drop rule 314159; drop rule 314159;
ERROR: parser: parse error at or near "314159" ERROR: parser: parse error at or near "314159"
-- no such rule -- no such rule
drop rule nonesuch; drop rule nonesuch on noplace;
ERROR: Rule "nonesuch" not found ERROR: Relation "noplace" does not exist
-- bad keyword -- bad keyword
drop tuple rule nonesuch; drop tuple rule nonesuch;
ERROR: parser: parse error at or near "tuple" ERROR: parser: parse error at or near "tuple"
-- no such rule -- no such rule
drop instance rule nonesuch; drop instance rule nonesuch on noplace;
ERROR: parser: parse error at or near "instance" ERROR: parser: parse error at or near "instance"
-- no such rule -- no such rule
drop rewrite rule nonesuch; drop rewrite rule nonesuch;

View File

@ -648,8 +648,8 @@ select * from rtest_order2;
---+---+------------------------------------- ---+---+-------------------------------------
1 | 1 | rule 2 - this should run 1st 1 | 1 | rule 2 - this should run 1st
1 | 2 | rule 4 - this should run 2nd 1 | 2 | rule 4 - this should run 2nd
1 | 3 | rule 3 - this should run 3rd or 4th 1 | 3 | rule 1 - this should run 3rd or 4th
1 | 4 | rule 1 - this should run 3rd or 4th 1 | 4 | rule 3 - this should run 3rd or 4th
(4 rows) (4 rows)
-- --
@ -1173,7 +1173,7 @@ select * from foo;
1001 1001
(1 row) (1 row)
drop rule foorule; drop rule foorule on foo;
-- this should fail because f1 is not exposed for unqualified reference: -- this should fail because f1 is not exposed for unqualified reference:
create rule foorule as on insert to foo where f1 < 100 create rule foorule as on insert to foo where f1 < 100
do instead insert into foo2 values (f1); do instead insert into foo2 values (f1);
@ -1196,7 +1196,7 @@ select * from foo2;
2 2
(1 row) (1 row)
drop rule foorule; drop rule foorule on foo;
drop table foo; drop table foo;
drop table foo2; drop table foo2;
-- --
@ -1256,7 +1256,7 @@ select * from cchild;
2 | test2 2 | test2
(2 rows) (2 rows)
drop rule rrule; drop rule rrule on vview;
drop view vview; drop view vview;
drop table pparent; drop table pparent;
drop table cchild; drop table cchild;
@ -1268,7 +1268,7 @@ SELECT viewname, definition FROM pg_views ORDER BY viewname;
--------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
iexit | SELECT ih.name, ih.thepath, interpt_pp(ih.thepath, r.thepath) AS exit FROM ihighway ih, ramp r WHERE (ih.thepath ## r.thepath); iexit | SELECT ih.name, ih.thepath, interpt_pp(ih.thepath, r.thepath) AS exit FROM ihighway ih, ramp r WHERE (ih.thepath ## r.thepath);
pg_indexes | SELECT c.relname AS tablename, i.relname AS indexname, pg_get_indexdef(x.indexrelid) AS indexdef FROM pg_index x, pg_class c, pg_class i WHERE ((((c.relkind = 'r'::"char") AND (i.relkind = 'i'::"char")) AND (c.oid = x.indrelid)) AND (i.oid = x.indexrelid)); pg_indexes | SELECT c.relname AS tablename, i.relname AS indexname, pg_get_indexdef(x.indexrelid) AS indexdef FROM pg_index x, pg_class c, pg_class i WHERE ((((c.relkind = 'r'::"char") AND (i.relkind = 'i'::"char")) AND (c.oid = x.indrelid)) AND (i.oid = x.indexrelid));
pg_rules | SELECT c.relname AS tablename, r.rulename, pg_get_ruledef(r.rulename) AS definition FROM pg_rewrite r, pg_class c WHERE ((r.rulename !~ '^_RET'::text) AND (c.oid = r.ev_class)); pg_rules | SELECT n.nspname AS schemaname, c.relname AS tablename, r.rulename, pg_get_ruledef(r.oid) AS definition FROM ((pg_rewrite r JOIN pg_class c ON ((c.oid = r.ev_class))) LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (r.rulename !~ '^_RET'::text);
pg_stat_activity | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, u.usename, pg_stat_get_backend_activity(s.backendid) AS current_query FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_shadow u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.usesysid)); pg_stat_activity | SELECT d.oid AS datid, d.datname, pg_stat_get_backend_pid(s.backendid) AS procpid, pg_stat_get_backend_userid(s.backendid) AS usesysid, u.usename, pg_stat_get_backend_activity(s.backendid) AS current_query FROM pg_database d, (SELECT pg_stat_get_backend_idset() AS backendid) s, pg_shadow u WHERE ((pg_stat_get_backend_dbid(s.backendid) = d.oid) AND (pg_stat_get_backend_userid(s.backendid) = u.usesysid));
pg_stat_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM pg_class c, pg_class i, pg_index x WHERE (((c.relkind = 'r'::"char") AND (x.indrelid = c.oid)) AND (x.indexrelid = i.oid)); pg_stat_all_indexes | SELECT c.oid AS relid, i.oid AS indexrelid, c.relname, i.relname AS indexrelname, pg_stat_get_numscans(i.oid) AS idx_scan, pg_stat_get_tuples_returned(i.oid) AS idx_tup_read, pg_stat_get_tuples_fetched(i.oid) AS idx_tup_fetch FROM pg_class c, pg_class i, pg_index x WHERE (((c.relkind = 'r'::"char") AND (x.indrelid = c.oid)) AND (x.indexrelid = i.oid));
pg_stat_all_tables | SELECT c.oid AS relid, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, sum(pg_stat_get_numscans(i.indexrelid)) AS idx_scan, sum(pg_stat_get_tuples_fetched(i.indexrelid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del FROM (pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) WHERE (c.relkind = 'r'::"char") GROUP BY c.oid, c.relname; pg_stat_all_tables | SELECT c.oid AS relid, c.relname, pg_stat_get_numscans(c.oid) AS seq_scan, pg_stat_get_tuples_returned(c.oid) AS seq_tup_read, sum(pg_stat_get_numscans(i.indexrelid)) AS idx_scan, sum(pg_stat_get_tuples_fetched(i.indexrelid)) AS idx_tup_fetch, pg_stat_get_tuples_inserted(c.oid) AS n_tup_ins, pg_stat_get_tuples_updated(c.oid) AS n_tup_upd, pg_stat_get_tuples_deleted(c.oid) AS n_tup_del FROM (pg_class c LEFT JOIN pg_index i ON ((c.oid = i.indrelid))) WHERE (c.relkind = 'r'::"char") GROUP BY c.oid, c.relname;
@ -1289,7 +1289,7 @@ SELECT viewname, definition FROM pg_views ORDER BY viewname;
pg_stats | SELECT c.relname AS tablename, a.attname, s.stanullfrac AS null_frac, s.stawidth AS avg_width, s.stadistinct AS n_distinct, CASE WHEN (1 = s.stakind1) THEN s.stavalues1 WHEN (1 = s.stakind2) THEN s.stavalues2 WHEN (1 = s.stakind3) THEN s.stavalues3 WHEN (1 = s.stakind4) THEN s.stavalues4 ELSE NULL::"_text" END AS most_common_vals, CASE WHEN (1 = s.stakind1) THEN s.stanumbers1 WHEN (1 = s.stakind2) THEN s.stanumbers2 WHEN (1 = s.stakind3) THEN s.stanumbers3 WHEN (1 = s.stakind4) THEN s.stanumbers4 ELSE NULL::"_float4" END AS most_common_freqs, CASE WHEN (2 = s.stakind1) THEN s.stavalues1 WHEN (2 = s.stakind2) THEN s.stavalues2 WHEN (2 = s.stakind3) THEN s.stavalues3 WHEN (2 = s.stakind4) THEN s.stavalues4 ELSE NULL::"_text" END AS histogram_bounds, CASE WHEN (3 = s.stakind1) THEN s.stanumbers1[1] WHEN (3 = s.stakind2) THEN s.stanumbers2[1] WHEN (3 = s.stakind3) THEN s.stanumbers3[1] WHEN (3 = s.stakind4) THEN s.stanumbers4[1] ELSE NULL::float4 END AS correlation FROM pg_class c, pg_attribute a, pg_statistic s WHERE ((((c.oid = s.starelid) AND (c.oid = a.attrelid)) AND (a.attnum = s.staattnum)) AND has_table_privilege(c.oid, 'select'::text)); pg_stats | SELECT c.relname AS tablename, a.attname, s.stanullfrac AS null_frac, s.stawidth AS avg_width, s.stadistinct AS n_distinct, CASE WHEN (1 = s.stakind1) THEN s.stavalues1 WHEN (1 = s.stakind2) THEN s.stavalues2 WHEN (1 = s.stakind3) THEN s.stavalues3 WHEN (1 = s.stakind4) THEN s.stavalues4 ELSE NULL::"_text" END AS most_common_vals, CASE WHEN (1 = s.stakind1) THEN s.stanumbers1 WHEN (1 = s.stakind2) THEN s.stanumbers2 WHEN (1 = s.stakind3) THEN s.stanumbers3 WHEN (1 = s.stakind4) THEN s.stanumbers4 ELSE NULL::"_float4" END AS most_common_freqs, CASE WHEN (2 = s.stakind1) THEN s.stavalues1 WHEN (2 = s.stakind2) THEN s.stavalues2 WHEN (2 = s.stakind3) THEN s.stavalues3 WHEN (2 = s.stakind4) THEN s.stavalues4 ELSE NULL::"_text" END AS histogram_bounds, CASE WHEN (3 = s.stakind1) THEN s.stanumbers1[1] WHEN (3 = s.stakind2) THEN s.stanumbers2[1] WHEN (3 = s.stakind3) THEN s.stanumbers3[1] WHEN (3 = s.stakind4) THEN s.stanumbers4[1] ELSE NULL::float4 END AS correlation FROM pg_class c, pg_attribute a, pg_statistic s WHERE ((((c.oid = s.starelid) AND (c.oid = a.attrelid)) AND (a.attnum = s.staattnum)) AND has_table_privilege(c.oid, 'select'::text));
pg_tables | SELECT c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, c.relhasindex AS hasindexes, c.relhasrules AS hasrules, (c.reltriggers > 0) AS hastriggers FROM pg_class c WHERE ((c.relkind = 'r'::"char") OR (c.relkind = 's'::"char")); pg_tables | SELECT c.relname AS tablename, pg_get_userbyid(c.relowner) AS tableowner, c.relhasindex AS hasindexes, c.relhasrules AS hasrules, (c.reltriggers > 0) AS hastriggers FROM pg_class c WHERE ((c.relkind = 'r'::"char") OR (c.relkind = 's'::"char"));
pg_user | SELECT pg_shadow.usename, pg_shadow.usesysid, pg_shadow.usecreatedb, pg_shadow.usetrace, pg_shadow.usesuper, pg_shadow.usecatupd, '********'::text AS passwd, pg_shadow.valuntil, pg_shadow.useconfig FROM pg_shadow; pg_user | SELECT pg_shadow.usename, pg_shadow.usesysid, pg_shadow.usecreatedb, pg_shadow.usetrace, pg_shadow.usesuper, pg_shadow.usecatupd, '********'::text AS passwd, pg_shadow.valuntil, pg_shadow.useconfig FROM pg_shadow;
pg_views | SELECT c.relname AS viewname, pg_get_userbyid(c.relowner) AS viewowner, pg_get_viewdef(c.relname) AS definition FROM pg_class c WHERE (c.relkind = 'v'::"char"); pg_views | SELECT n.nspname AS schemaname, c.relname AS viewname, pg_get_userbyid(c.relowner) AS viewowner, pg_get_viewdef(c.oid) AS definition FROM (pg_class c LEFT JOIN pg_namespace n ON ((n.oid = c.relnamespace))) WHERE (c.relkind = 'v'::"char");
rtest_v1 | SELECT rtest_t1.a, rtest_t1.b FROM rtest_t1; rtest_v1 | SELECT rtest_t1.a, rtest_t1.b FROM rtest_t1;
rtest_vcomp | SELECT x.part, (x.size * y.factor) AS size_in_cm FROM rtest_comp x, rtest_unitfact y WHERE (x.unit = y.unit); rtest_vcomp | SELECT x.part, (x.size * y.factor) AS size_in_cm FROM rtest_comp x, rtest_unitfact y WHERE (x.unit = y.unit);
rtest_vview1 | SELECT x.a, x.b FROM rtest_view1 x WHERE (0 < (SELECT count(*) AS count FROM rtest_view2 y WHERE (y.a = x.a))); rtest_vview1 | SELECT x.a, x.b FROM rtest_view1 x WHERE (0 < (SELECT count(*) AS count FROM rtest_view2 y WHERE (y.a = x.a)));

View File

@ -239,13 +239,13 @@ drop rule;
drop rule 314159; drop rule 314159;
-- no such rule -- no such rule
drop rule nonesuch; drop rule nonesuch on noplace;
-- bad keyword -- bad keyword
drop tuple rule nonesuch; drop tuple rule nonesuch;
-- no such rule -- no such rule
drop instance rule nonesuch; drop instance rule nonesuch on noplace;
-- no such rule -- no such rule
drop rewrite rule nonesuch; drop rewrite rule nonesuch;

View File

@ -699,7 +699,7 @@ insert into foo values(1);
insert into foo values(1001); insert into foo values(1001);
select * from foo; select * from foo;
drop rule foorule; drop rule foorule on foo;
-- this should fail because f1 is not exposed for unqualified reference: -- this should fail because f1 is not exposed for unqualified reference:
create rule foorule as on insert to foo where f1 < 100 create rule foorule as on insert to foo where f1 < 100
@ -714,7 +714,7 @@ insert into foo values(100);
select * from foo; select * from foo;
select * from foo2; select * from foo2;
drop rule foorule; drop rule foorule on foo;
drop table foo; drop table foo;
drop table foo2; drop table foo2;
@ -751,7 +751,7 @@ update vview set descrip='test3' where pid=3;
select * from vview; select * from vview;
select * from cchild; select * from cchild;
drop rule rrule; drop rule rrule on vview;
drop view vview; drop view vview;
drop table pparent; drop table pparent;
drop table cchild; drop table cchild;