Skip to content

Commit 25dfba3

Browse files
committed
Make ruleutils.c use format_type for printing typenames. Minor tweaks
in quoting rules and recognition of implicit type coercions.
1 parent 7677fe0 commit 25dfba3

File tree

3 files changed

+39
-50
lines changed

3 files changed

+39
-50
lines changed

src/backend/parser/parse_expr.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.115 2002/04/16 23:08:11 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.116 2002/04/28 00:49:12 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1062,8 +1062,8 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod)
10621062
}
10631063

10641064
/*
1065-
* Furthermore, the name of the function must be the same as the
1066-
* argument/result type's name.
1065+
* Furthermore, the name and namespace of the function must be the same
1066+
* as its result type's name/namespace (cf. find_coercion_function).
10671067
*/
10681068
typeTuple = SearchSysCache(TYPEOID,
10691069
ObjectIdGetDatum(procStruct->prorettype),
@@ -1072,9 +1072,9 @@ exprIsLengthCoercion(Node *expr, int32 *coercedTypmod)
10721072
elog(ERROR, "cache lookup for type %u failed",
10731073
procStruct->prorettype);
10741074
typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
1075-
if (strncmp(NameStr(procStruct->proname),
1076-
NameStr(typeStruct->typname),
1077-
NAMEDATALEN) != 0)
1075+
if (strcmp(NameStr(procStruct->proname),
1076+
NameStr(typeStruct->typname)) != 0 ||
1077+
procStruct->pronamespace != typeStruct->typnamespace)
10781078
{
10791079
ReleaseSysCache(procTuple);
10801080
ReleaseSysCache(typeTuple);

src/backend/utils/adt/ruleutils.c

Lines changed: 27 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* back to source text
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.99 2002/04/25 02:56:55 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.100 2002/04/28 00:49:13 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -1805,23 +1805,12 @@ get_rule_expr(Node *node, deparse_context *context)
18051805
case T_RelabelType:
18061806
{
18071807
RelabelType *relabel = (RelabelType *) node;
1808-
HeapTuple typetup;
1809-
Form_pg_type typeStruct;
1810-
char *extval;
18111808

18121809
appendStringInfoChar(buf, '(');
18131810
get_rule_expr(relabel->arg, context);
1814-
typetup = SearchSysCache(TYPEOID,
1815-
ObjectIdGetDatum(relabel->resulttype),
1816-
0, 0, 0);
1817-
if (!HeapTupleIsValid(typetup))
1818-
elog(ERROR, "cache lookup of type %u failed",
1819-
relabel->resulttype);
1820-
typeStruct = (Form_pg_type) GETSTRUCT(typetup);
1821-
extval = pstrdup(NameStr(typeStruct->typname));
1822-
appendStringInfo(buf, ")::%s", quote_identifier(extval));
1823-
pfree(extval);
1824-
ReleaseSysCache(typetup);
1811+
appendStringInfo(buf, ")::%s",
1812+
format_type_with_typemod(relabel->resulttype,
1813+
relabel->resulttypmod));
18251814
}
18261815
break;
18271816

@@ -2095,23 +2084,25 @@ strip_type_coercion(Node *expr, Oid resultType)
20952084
elog(ERROR, "cache lookup for proc %u failed", func->funcid);
20962085
procStruct = (Form_pg_proc) GETSTRUCT(procTuple);
20972086
/* Double-check func has one arg and correct result type */
2087+
/* Also, it must be an implicit coercion function */
20982088
if (procStruct->pronargs != 1 ||
2099-
procStruct->prorettype != resultType)
2089+
procStruct->prorettype != resultType ||
2090+
!procStruct->proimplicit)
21002091
{
21012092
ReleaseSysCache(procTuple);
21022093
return expr;
21032094
}
2104-
/* See if function has same name as its result type */
2095+
/* See if function has same name/namespace as its result type */
21052096
typeTuple = SearchSysCache(TYPEOID,
21062097
ObjectIdGetDatum(procStruct->prorettype),
21072098
0, 0, 0);
21082099
if (!HeapTupleIsValid(typeTuple))
21092100
elog(ERROR, "cache lookup for type %u failed",
21102101
procStruct->prorettype);
21112102
typeStruct = (Form_pg_type) GETSTRUCT(typeTuple);
2112-
if (strncmp(NameStr(procStruct->proname),
2113-
NameStr(typeStruct->typname),
2114-
NAMEDATALEN) != 0)
2103+
if (strcmp(NameStr(procStruct->proname),
2104+
NameStr(typeStruct->typname)) != 0 ||
2105+
procStruct->pronamespace != typeStruct->typnamespace)
21152106
{
21162107
ReleaseSysCache(procTuple);
21172108
ReleaseSysCache(typeTuple);
@@ -2179,28 +2170,26 @@ get_const_expr(Const *constval, deparse_context *context)
21792170
char *extval;
21802171
char *valptr;
21812172

2182-
typetup = SearchSysCache(TYPEOID,
2183-
ObjectIdGetDatum(constval->consttype),
2184-
0, 0, 0);
2185-
if (!HeapTupleIsValid(typetup))
2186-
elog(ERROR, "cache lookup of type %u failed", constval->consttype);
2187-
2188-
typeStruct = (Form_pg_type) GETSTRUCT(typetup);
2189-
21902173
if (constval->constisnull)
21912174
{
21922175
/*
21932176
* Always label the type of a NULL constant. This not only
21942177
* prevents misdecisions about the type, but it ensures that our
21952178
* output is a valid b_expr.
21962179
*/
2197-
extval = pstrdup(NameStr(typeStruct->typname));
2198-
appendStringInfo(buf, "NULL::%s", quote_identifier(extval));
2199-
pfree(extval);
2200-
ReleaseSysCache(typetup);
2180+
appendStringInfo(buf, "NULL::%s",
2181+
format_type_with_typemod(constval->consttype, -1));
22012182
return;
22022183
}
22032184

2185+
typetup = SearchSysCache(TYPEOID,
2186+
ObjectIdGetDatum(constval->consttype),
2187+
0, 0, 0);
2188+
if (!HeapTupleIsValid(typetup))
2189+
elog(ERROR, "cache lookup of type %u failed", constval->consttype);
2190+
2191+
typeStruct = (Form_pg_type) GETSTRUCT(typetup);
2192+
22042193
extval = DatumGetCString(OidFunctionCall3(typeStruct->typoutput,
22052194
constval->constvalue,
22062195
ObjectIdGetDatum(typeStruct->typelem),
@@ -2251,9 +2240,9 @@ get_const_expr(Const *constval, deparse_context *context)
22512240
/* These types can be left unlabeled */
22522241
break;
22532242
default:
2254-
extval = pstrdup(NameStr(typeStruct->typname));
2255-
appendStringInfo(buf, "::%s", quote_identifier(extval));
2256-
pfree(extval);
2243+
appendStringInfo(buf, "::%s",
2244+
format_type_with_typemod(constval->consttype,
2245+
-1));
22572246
break;
22582247
}
22592248

@@ -2583,8 +2572,8 @@ const char *
25832572
quote_identifier(const char *ident)
25842573
{
25852574
/*
2586-
* Can avoid quoting if ident starts with a lowercase letter and
2587-
* contains only lowercase letters, digits, and underscores, *and* is
2575+
* Can avoid quoting if ident starts with a lowercase letter or underscore
2576+
* and contains only lowercase letters, digits, and underscores, *and* is
25882577
* not any SQL keyword. Otherwise, supply quotes.
25892578
*/
25902579
bool safe;
@@ -2594,7 +2583,7 @@ quote_identifier(const char *ident)
25942583
* would like to use <ctype.h> macros here, but they might yield
25952584
* unwanted locale-specific results...
25962585
*/
2597-
safe = (ident[0] >= 'a' && ident[0] <= 'z');
2586+
safe = ((ident[0] >= 'a' && ident[0] <= 'z') || ident[0] == '_');
25982587
if (safe)
25992588
{
26002589
const char *ptr;

src/test/regress/expected/rules.out

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,8 +1264,8 @@ drop table cchild;
12641264
-- Check that ruleutils are working
12651265
--
12661266
SELECT viewname, definition FROM pg_views ORDER BY viewname;
1267-
viewname | definition
1268-
--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1267+
viewname | definition
1268+
--------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
12691269
iexit | SELECT ih.name, ih.thepath, interpt_pp(ih.thepath, r.thepath) AS exit FROM ihighway ih, ramp r WHERE (ih.thepath ## r.thepath);
12701270
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));
12711271
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);
@@ -1286,7 +1286,7 @@ SELECT viewname, definition FROM pg_views ORDER BY viewname;
12861286
pg_statio_user_indexes | SELECT pg_statio_all_indexes.relid, pg_statio_all_indexes.indexrelid, pg_statio_all_indexes.relname, pg_statio_all_indexes.indexrelname, pg_statio_all_indexes.idx_blks_read, pg_statio_all_indexes.idx_blks_hit FROM pg_statio_all_indexes WHERE (pg_statio_all_indexes.relname !~ '^pg_'::text);
12871287
pg_statio_user_sequences | SELECT pg_statio_all_sequences.relid, pg_statio_all_sequences.relname, pg_statio_all_sequences.blks_read, pg_statio_all_sequences.blks_hit FROM pg_statio_all_sequences WHERE (pg_statio_all_sequences.relname !~ '^pg_'::text);
12881288
pg_statio_user_tables | SELECT pg_statio_all_tables.relid, pg_statio_all_tables.relname, pg_statio_all_tables.heap_blks_read, pg_statio_all_tables.heap_blks_hit, pg_statio_all_tables.idx_blks_read, pg_statio_all_tables.idx_blks_hit, pg_statio_all_tables.toast_blks_read, pg_statio_all_tables.toast_blks_hit, pg_statio_all_tables.tidx_blks_read, pg_statio_all_tables.tidx_blks_hit FROM pg_statio_all_tables WHERE (pg_statio_all_tables.relname !~ '^pg_'::text);
1289-
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));
1289+
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::real[] 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::real 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));
12901290
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"));
12911291
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;
12921292
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");
@@ -1308,8 +1308,8 @@ SELECT viewname, definition FROM pg_views ORDER BY viewname;
13081308

13091309
SELECT tablename, rulename, definition FROM pg_rules
13101310
ORDER BY tablename, rulename;
1311-
tablename | rulename | definition
1312-
---------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1311+
tablename | rulename | definition
1312+
---------------+-----------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
13131313
rtest_emp | rtest_emp_del | CREATE RULE rtest_emp_del AS ON DELETE TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (old.ename, "current_user"(), 'fired '::bpchar, '$0.00'::money, old.salary);
13141314
rtest_emp | rtest_emp_ins | CREATE RULE rtest_emp_ins AS ON INSERT TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'hired '::bpchar, new.salary, '$0.00'::money);
13151315
rtest_emp | rtest_emp_upd | CREATE RULE rtest_emp_upd AS ON UPDATE TO rtest_emp WHERE (new.salary <> old.salary) DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'honored '::bpchar, new.salary, old.salary);
@@ -1335,7 +1335,7 @@ SELECT tablename, rulename, definition FROM pg_rules
13351335
shoelace | shoelace_del | CREATE RULE shoelace_del AS ON DELETE TO shoelace DO INSTEAD DELETE FROM shoelace_data WHERE (shoelace_data.sl_name = old.sl_name);
13361336
shoelace | shoelace_ins | CREATE RULE shoelace_ins AS ON INSERT TO shoelace DO INSTEAD INSERT INTO shoelace_data (sl_name, sl_avail, sl_color, sl_len, sl_unit) VALUES (new.sl_name, new.sl_avail, new.sl_color, new.sl_len, new.sl_unit);
13371337
shoelace | shoelace_upd | CREATE RULE shoelace_upd AS ON UPDATE TO shoelace DO INSTEAD UPDATE shoelace_data SET sl_name = new.sl_name, sl_avail = new.sl_avail, sl_color = new.sl_color, sl_len = new.sl_len, sl_unit = new.sl_unit WHERE (shoelace_data.sl_name = old.sl_name);
1338-
shoelace_data | log_shoelace | CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data WHERE (new.sl_avail <> old.sl_avail) DO INSERT INTO shoelace_log (sl_name, sl_avail, log_who, log_when) VALUES (new.sl_name, new.sl_avail, 'Al Bundy'::name, 'Thu Jan 01 00:00:00 1970'::"timestamp");
1338+
shoelace_data | log_shoelace | CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data WHERE (new.sl_avail <> old.sl_avail) DO INSERT INTO shoelace_log (sl_name, sl_avail, log_who, log_when) VALUES (new.sl_name, new.sl_avail, 'Al Bundy'::name, 'Thu Jan 01 00:00:00 1970'::timestamp without time zone);
13391339
shoelace_ok | shoelace_ok_ins | CREATE RULE shoelace_ok_ins AS ON INSERT TO shoelace_ok DO INSTEAD UPDATE shoelace SET sl_avail = (shoelace.sl_avail + new.ok_quant) WHERE (shoelace.sl_name = new.ok_name);
13401340
(27 rows)
13411341

0 commit comments

Comments
 (0)