From: Tom Lane Date: Fri, 19 Apr 2002 23:13:54 +0000 (+0000) Subject: Change naming rule for ON SELECT rules of views: they're all just X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=ff0008b629ad39dfdf260e874c57f3a575fa8b22;p=users%2Fbernd%2Fpostgres.git Change naming rule for ON SELECT rules of views: they're all just _RETURN now, since there's no need to keep 'em unique anymore. --- diff --git a/doc/src/sgml/ref/create_rule.sgml b/doc/src/sgml/ref/create_rule.sgml index 60ead372da..eb7959efe8 100644 --- a/doc/src/sgml/ref/create_rule.sgml +++ b/doc/src/sgml/ref/create_rule.sgml @@ -268,12 +268,12 @@ CREATE report an error because the query cycled too many times: -CREATE RULE "_RETemp" AS +CREATE RULE "_RETURN" AS ON SELECT TO emp DO INSTEAD SELECT * FROM toyemp; -CREATE RULE "_RETtoyemp" AS +CREATE RULE "_RETURN" AS ON SELECT TO toyemp DO INSTEAD SELECT * FROM emp; diff --git a/doc/src/sgml/rules.sgml b/doc/src/sgml/rules.sgml index ff86c032ba..3787f0f29d 100644 --- a/doc/src/sgml/rules.sgml +++ b/doc/src/sgml/rules.sgml @@ -289,7 +289,7 @@ CREATE VIEW myview AS SELECT * FROM mytab; CREATE TABLE myview (same attribute list as for mytab); -CREATE RULE "_RETmyview" AS ON SELECT TO myview DO INSTEAD +CREATE RULE "_RETURN" AS ON SELECT TO myview DO INSTEAD SELECT * FROM mytab; @@ -517,7 +517,7 @@ SELECT shoelace.sl_name, shoelace.sl_avail, range table and checks if there are rules in pg_rewrite for any relation. When processing the range table entry for shoelace (the only one up to now) it finds the - rule _RETshoelace with the parse tree + _RETURN rule with the parse tree SELECT s.sl_name, s.sl_avail, @@ -1494,7 +1494,7 @@ UPDATE shoelace_data SET Again it's an INSTEAD rule and the previous parse tree is trashed. Note that this query still uses the view shoelace. But the rule system isn't finished with this loop so it continues - and applies the rule _RETshoelace on it and we get + and applies the _RETURN rule on it and we get UPDATE shoelace_data SET diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 65a9b67c3c..381ae61712 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -40,8 +40,6 @@ #include "parser/parse_expr.h" #include "parser/parse_relation.h" #include "parser/parse_type.h" -#include "rewrite/rewriteDefine.h" -#include "rewrite/rewriteSupport.h" #include "utils/acl.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -2814,19 +2812,6 @@ renamerel(Oid relid, const char *newrelname) if (relkind != RELKIND_INDEX) TypeRename(oldrelname, namespaceId, newrelname); - /* - * If it's a view, must also rename the associated ON SELECT rule. - */ - if (relkind == RELKIND_VIEW) - { - char *oldrulename, - *newrulename; - - oldrulename = MakeRetrieveViewRuleName(oldrelname); - newrulename = MakeRetrieveViewRuleName(newrelname); - RenameRewriteRule(relid, oldrulename, newrulename); - } - /* * Update rel name in any RI triggers associated with the relation. */ diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index cfa800e5f7..ca6768a065 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -99,17 +99,14 @@ static RuleStmt * FormViewRetrieveRule(const RangeVar *view, Query *viewParse) { RuleStmt *rule; - char *rname; /* * Create a RuleStmt that corresponds to the suitable rewrite rule * args for DefineQueryRewrite(); */ - rname = MakeRetrieveViewRuleName(view->relname); - rule = makeNode(RuleStmt); rule->relation = copyObject((RangeVar *) view); - rule->rulename = pstrdup(rname); + rule->rulename = pstrdup(ViewSelectRuleName); rule->whereClause = NULL; rule->event = CMD_SELECT; rule->instead = true; diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c index e6303f4654..8e506e824c 100644 --- a/src/backend/rewrite/rewriteDefine.c +++ b/src/backend/rewrite/rewriteDefine.c @@ -176,7 +176,6 @@ DefineQueryRewrite(RuleStmt *stmt) { List *tllist; int i; - char *expected_name; /* * So there cannot be INSTEAD NOTHING, ... @@ -265,15 +264,26 @@ DefineQueryRewrite(RuleStmt *stmt) } /* - * ... and finally the rule must be named _RETviewname. + * ... and finally the rule must be named _RETURN. */ - expected_name = MakeRetrieveViewRuleName(event_obj->relname); - if (strcmp(expected_name, stmt->rulename) != 0) + if (strcmp(stmt->rulename, ViewSelectRuleName) != 0) { - elog(ERROR, "view rule for \"%s\" must be named \"%s\"", - event_obj->relname, expected_name); + /* + * In versions before 7.3, the expected name was _RETviewname. + * For backwards compatibility with old pg_dump output, accept + * that and silently change it to _RETURN. Since this is just + * a quick backwards-compatibility hack, limit the number of + * characters checked to a few less than NAMEDATALEN; this + * saves having to worry about where a multibyte character might + * have gotten truncated. + */ + if (strncmp(stmt->rulename, "_RET", 4) != 0 || + strncmp(stmt->rulename + 4, event_obj->relname, + NAMEDATALEN - 4 - 4) != 0) + elog(ERROR, "view rule for \"%s\" must be named \"%s\"", + event_obj->relname, ViewSelectRuleName); + stmt->rulename = pstrdup(ViewSelectRuleName); } - pfree(expected_name); /* * Are we converting a relation to a view? @@ -418,9 +428,7 @@ setRuleCheckAsUser_walker(Node *node, Oid *context) /* * Rename an existing rewrite rule. * - * There is not currently a user command to invoke this directly - * (perhaps there should be). But we need it anyway to rename the - * ON SELECT rule associated with a view, when the view is renamed. + * This is unused code at the moment. */ void RenameRewriteRule(Oid owningRel, const char *oldName, diff --git a/src/backend/rewrite/rewriteSupport.c b/src/backend/rewrite/rewriteSupport.c index b875a706aa..b5f0f3a5c6 100644 --- a/src/backend/rewrite/rewriteSupport.c +++ b/src/backend/rewrite/rewriteSupport.c @@ -20,10 +20,6 @@ #include "rewrite/rewriteSupport.h" #include "utils/syscache.h" -#ifdef MULTIBYTE -#include "mb/pg_wchar.h" -#endif - /* * Is there a rule by the given name? @@ -37,35 +33,6 @@ IsDefinedRewriteRule(Oid owningRel, const char *ruleName) 0, 0); } -/* - * makeViewRetrieveRuleName - * - * Given a view name, returns the name for the associated ON SELECT rule. - * - * XXX this is not the only place in the backend that knows about the _RET - * name-forming convention. - */ -char * -MakeRetrieveViewRuleName(const char *viewName) -{ - char *buf; - int buflen, - maxlen; - - buflen = strlen(viewName) + 5; - buf = palloc(buflen); - snprintf(buf, buflen, "_RET%s", viewName); - /* clip to less than NAMEDATALEN bytes, if necessary */ -#ifdef MULTIBYTE - maxlen = pg_mbcliplen(buf, strlen(buf), NAMEDATALEN - 1); -#else - maxlen = NAMEDATALEN - 1; -#endif - if (maxlen < buflen) - buf[maxlen] = '\0'; - - return buf; -} /* * SetRelationRuleStatus diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index e363308658..157c4bb9cc 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -283,7 +283,6 @@ pg_do_getviewdef(Oid viewoid) StringInfoData buf; int len; char *viewname; - char *name; /* * Connect to SPI manager @@ -313,9 +312,8 @@ pg_do_getviewdef(Oid viewoid) * Get the pg_rewrite tuple for the view's SELECT rule */ viewname = get_rel_name(viewoid); - name = MakeRetrieveViewRuleName(viewname); args[0] = ObjectIdGetDatum(viewoid); - args[1] = PointerGetDatum(name); + args[1] = PointerGetDatum(ViewSelectRuleName); nulls[0] = ' '; nulls[1] = ' '; spirc = SPI_execp(plan_getviewrule, args, nulls, 2); @@ -338,7 +336,6 @@ pg_do_getviewdef(Oid viewoid) VARATT_SIZEP(ruledef) = len; memcpy(VARDATA(ruledef), buf.data, buf.len); pfree(buf.data); - pfree(name); /* * Disconnect from SPI manager diff --git a/src/bin/initdb/initdb.sh b/src/bin/initdb/initdb.sh index 87a28383f6..d99c7a6edc 100644 --- a/src/bin/initdb/initdb.sh +++ b/src/bin/initdb/initdb.sh @@ -695,7 +695,7 @@ CREATE VIEW pg_rules AS \ 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'; + WHERE R.rulename != '_RETURN'; CREATE VIEW pg_views AS \ SELECT \ diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 2f90c68245..f894599c47 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -2291,10 +2291,8 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs, const char *tablename) "oid as view_oid" " from pg_rewrite where" " ev_class = '%s'::oid and" - " rulename = ('_RET' || ", + " rulename = '_RETURN';", tblinfo[i].oid); - formatStringLiteral(query, tblinfo[i].relname, CONV_ALL); - appendPQExpBuffer(query, ")::name;"); } res2 = PQexec(g_conn, query->data); @@ -5006,7 +5004,7 @@ dumpRules(Archive *fout, const char *tablename, continue; /* - * Get all rules defined for this table + * Get all rules defined for this table, except view select rules */ resetPQExpBuffer(query); @@ -5036,7 +5034,7 @@ dumpRules(Archive *fout, const char *tablename, "FROM pg_rewrite, pg_class " "WHERE pg_class.oid = '%s'::oid " " AND pg_rewrite.ev_class = pg_class.oid " - " AND pg_rewrite.rulename !~ '^_RET' " + " AND pg_rewrite.rulename != '_RETURN' " "ORDER BY pg_rewrite.oid", tblinfo[t].oid); } diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index a182cc7787..35f1469026 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -385,9 +385,9 @@ objectDescription(const char *object) /* Rule description (ignore rules for views) */ "UNION ALL\n" " SELECT r.oid as oid, r.tableoid as tableoid,\n" - " CAST(r.rulename AS text) as name, CAST('%s' AS text) as object\n" + " CAST(r.rulename AS text) as name, CAST('%s' AS text) as object\n" " FROM pg_rewrite r\n" - " WHERE r.rulename !~ '^_RET'\n" + " WHERE r.rulename != '_RETURN'\n" /* Trigger description */ "UNION ALL\n" @@ -704,8 +704,8 @@ describeTableDetails(const char *name, bool desc) sprintf(buf, "SELECT r.rulename\n" "FROM pg_rewrite r, pg_class c\n" - "WHERE c.relname='%s' AND c.oid = r.ev_class\n" - "AND r.rulename NOT LIKE '_RET%%'", + "WHERE c.relname = '%s' AND c.oid = r.ev_class\n" + "AND r.rulename != '_RETURN'", name); result = PSQLexec(buf); if (!result) diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index f9895ab490..ebb10f7370 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200204182 +#define CATALOG_VERSION_NO 200204191 #endif diff --git a/src/include/rewrite/rewriteSupport.h b/src/include/rewrite/rewriteSupport.h index 6f71b9f002..fca46b37f1 100644 --- a/src/include/rewrite/rewriteSupport.h +++ b/src/include/rewrite/rewriteSupport.h @@ -14,9 +14,10 @@ #ifndef REWRITESUPPORT_H #define REWRITESUPPORT_H -extern bool IsDefinedRewriteRule(Oid owningRel, const char *ruleName); +/* The ON SELECT rule of a view is always named this: */ +#define ViewSelectRuleName "_RETURN" -extern char *MakeRetrieveViewRuleName(const char *view_name); +extern bool IsDefinedRewriteRule(Oid owningRel, const char *ruleName); extern void SetRelationRuleStatus(Oid relationId, bool relHasRules, bool relIsBecomingView); diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index 75578b76e0..0816fc83e7 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -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); 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 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_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 <> '_RETURN'::name); 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_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;