Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3e21ecb

Browse files
committed
Make the rule deparser a little less quote-happy, so that
display of default expressions isn't quite so ugly.
1 parent7cd67c8 commit3e21ecb

File tree

1 file changed

+147
-63
lines changed

1 file changed

+147
-63
lines changed

‎src/backend/utils/adt/ruleutils.c

Lines changed: 147 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* out of it's tuple
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.27 1999/10/03 23:55:31 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.28 1999/10/04 04:37:23 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -47,6 +47,7 @@
4747
#include"catalog/pg_index.h"
4848
#include"catalog/pg_operator.h"
4949
#include"catalog/pg_shadow.h"
50+
#include"catalog/pg_type.h"
5051
#include"utils/builtins.h"
5152
#include"utils/lsyscache.h"
5253

@@ -104,6 +105,7 @@ static void get_func_expr(Expr *expr, deparse_context *context);
104105
staticvoidget_tle_expr(TargetEntry*tle,deparse_context*context);
105106
staticvoidget_const_expr(Const*constval,deparse_context*context);
106107
staticvoidget_sublink_expr(Node*node,deparse_context*context);
108+
staticchar*quote_identifier(char*ident);
107109
staticchar*get_relation_name(Oidrelid);
108110
staticchar*get_attribute_name(Oidrelid,int2attnum);
109111
staticboolcheck_if_rte_used(Node*node,Indexrt_index,intlevelsup);
@@ -404,9 +406,11 @@ pg_get_indexdef(Oid indexrelid)
404406
spi_nulls[1]='\0';
405407
spirc=SPI_execp(plan_getam,spi_args,spi_nulls,1);
406408
if (spirc!=SPI_OK_SELECT)
407-
elog(ERROR,"failed to get pg_am tuple for index %s",nameout(&(idxrelrec->relname)));
409+
elog(ERROR,"failed to get pg_am tuple for index %s",
410+
nameout(&(idxrelrec->relname)));
408411
if (SPI_processed!=1)
409-
elog(ERROR,"failed to get pg_am tuple for index %s",nameout(&(idxrelrec->relname)));
412+
elog(ERROR,"failed to get pg_am tuple for index %s",
413+
nameout(&(idxrelrec->relname)));
410414
spi_tup=SPI_tuptable->vals[0];
411415
spi_ttc=SPI_tuptable->tupdesc;
412416
spi_fno=SPI_fnumber(spi_ttc,"amname");
@@ -416,11 +420,12 @@ pg_get_indexdef(Oid indexrelid)
416420
* ----------
417421
*/
418422
initStringInfo(&buf);
419-
appendStringInfo(&buf,"CREATE %sINDEX\"%s\" ON\"%s\" USING %s (",
423+
appendStringInfo(&buf,"CREATE %sINDEX%s ON%s USING %s (",
420424
idxrec->indisunique ?"UNIQUE " :"",
421-
nameout(&(idxrelrec->relname)),
422-
nameout(&(indrelrec->relname)),
423-
SPI_getvalue(spi_tup,spi_ttc,spi_fno));
425+
quote_identifier(nameout(&(idxrelrec->relname))),
426+
quote_identifier(nameout(&(indrelrec->relname))),
427+
quote_identifier(SPI_getvalue(spi_tup,spi_ttc,
428+
spi_fno)));
424429

425430
/* ----------
426431
* Collect the indexed attributes
@@ -440,12 +445,9 @@ pg_get_indexdef(Oid indexrelid)
440445
* Add the indexed field name
441446
* ----------
442447
*/
443-
if (idxrec->indkey[keyno]==ObjectIdAttributeNumber-1)
444-
appendStringInfo(&keybuf,"\"oid\"");
445-
else
446-
appendStringInfo(&keybuf,"\"%s\"",
447-
get_attribute_name(idxrec->indrelid,
448-
idxrec->indkey[keyno]));
448+
appendStringInfo(&keybuf,"%s",
449+
quote_identifier(get_attribute_name(idxrec->indrelid,
450+
idxrec->indkey[keyno])));
449451

450452
/* ----------
451453
* If not a functional index, add the operator class name
@@ -464,8 +466,9 @@ pg_get_indexdef(Oid indexrelid)
464466
spi_tup=SPI_tuptable->vals[0];
465467
spi_ttc=SPI_tuptable->tupdesc;
466468
spi_fno=SPI_fnumber(spi_ttc,"opcname");
467-
appendStringInfo(&keybuf," \"%s\"",
468-
SPI_getvalue(spi_tup,spi_ttc,spi_fno));
469+
appendStringInfo(&keybuf," %s",
470+
quote_identifier(SPI_getvalue(spi_tup,spi_ttc,
471+
spi_fno)));
469472
}
470473
}
471474

@@ -484,8 +487,8 @@ pg_get_indexdef(Oid indexrelid)
484487
elog(ERROR,"cache lookup for proc %u failed",idxrec->indproc);
485488

486489
procStruct= (Form_pg_proc)GETSTRUCT(proctup);
487-
appendStringInfo(&buf,"\"%s\"(%s) ",
488-
nameout(&(procStruct->proname)),
490+
appendStringInfo(&buf,"%s(%s) ",
491+
quote_identifier(nameout(&(procStruct->proname))),
489492
keybuf.data);
490493

491494
spi_args[0]=ObjectIdGetDatum(idxrec->indclass[0]);
@@ -499,8 +502,9 @@ pg_get_indexdef(Oid indexrelid)
499502
spi_tup=SPI_tuptable->vals[0];
500503
spi_ttc=SPI_tuptable->tupdesc;
501504
spi_fno=SPI_fnumber(spi_ttc,"opcname");
502-
appendStringInfo(&buf,"\"%s\"",
503-
SPI_getvalue(spi_tup,spi_ttc,spi_fno));
505+
appendStringInfo(&buf,"%s",
506+
quote_identifier(SPI_getvalue(spi_tup,spi_ttc,
507+
spi_fno)));
504508
}
505509
else
506510
/* ----------
@@ -658,7 +662,8 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc)
658662
* Build the rules definition text
659663
* ----------
660664
*/
661-
appendStringInfo(buf,"CREATE RULE \"%s\" AS ON ",rulename);
665+
appendStringInfo(buf,"CREATE RULE %s AS ON ",
666+
quote_identifier(rulename));
662667

663668
/* The event the rule is fired for */
664669
switch (ev_type)
@@ -686,10 +691,12 @@ make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc)
686691
}
687692

688693
/* The relation the rule is fired on */
689-
appendStringInfo(buf," TO \"%s\"",get_relation_name(ev_class));
694+
appendStringInfo(buf," TO %s",
695+
quote_identifier(get_relation_name(ev_class)));
690696
if (ev_attr>0)
691-
appendStringInfo(buf,".\"%s\"",
692-
get_attribute_name(ev_class,ev_attr));
697+
appendStringInfo(buf,".%s",
698+
quote_identifier(get_attribute_name(ev_class,
699+
ev_attr)));
693700

694701
/* If the rule has an event qualification, add it */
695702
if (ev_qual==NULL)
@@ -954,7 +961,8 @@ get_select_query_def(Query *query, deparse_context *context)
954961

955962
/* and do if so */
956963
if (tell_as)
957-
appendStringInfo(buf," AS \"%s\"",tle->resdom->resname);
964+
appendStringInfo(buf," AS %s",
965+
quote_identifier(tle->resdom->resname));
958966
}
959967

960968
/* If we need other tables that *NEW* or *CURRENT* add the FROM clause */
@@ -978,9 +986,11 @@ get_select_query_def(Query *query, deparse_context *context)
978986

979987
appendStringInfo(buf,sep);
980988
sep=", ";
981-
appendStringInfo(buf,"\"%s\"",rte->relname);
989+
appendStringInfo(buf,"%s",
990+
quote_identifier(rte->relname));
982991
if (strcmp(rte->relname,rte->refname)!=0)
983-
appendStringInfo(buf," \"%s\"",rte->refname);
992+
appendStringInfo(buf," %s",
993+
quote_identifier(rte->refname));
984994
}
985995
}
986996
}
@@ -1072,7 +1082,8 @@ get_insert_query_def(Query *query, deparse_context *context)
10721082
* ----------
10731083
*/
10741084
rte= (RangeTblEntry*)nth(query->resultRelation-1,query->rtable);
1075-
appendStringInfo(buf,"INSERT INTO \"%s\"",rte->relname);
1085+
appendStringInfo(buf,"INSERT INTO %s",
1086+
quote_identifier(rte->relname));
10761087

10771088
/* Add the target list */
10781089
sep=" (";
@@ -1082,7 +1093,7 @@ get_insert_query_def(Query *query, deparse_context *context)
10821093

10831094
appendStringInfo(buf,sep);
10841095
sep=", ";
1085-
appendStringInfo(buf,"\"%s\"",tle->resdom->resname);
1096+
appendStringInfo(buf,"%s",quote_identifier(tle->resdom->resname));
10861097
}
10871098
appendStringInfo(buf,") ");
10881099

@@ -1124,7 +1135,8 @@ get_update_query_def(Query *query, deparse_context *context)
11241135
* ----------
11251136
*/
11261137
rte= (RangeTblEntry*)nth(query->resultRelation-1,query->rtable);
1127-
appendStringInfo(buf,"UPDATE \"%s\" SET ",rte->relname);
1138+
appendStringInfo(buf,"UPDATE %s SET ",
1139+
quote_identifier(rte->relname));
11281140

11291141
/* Add the comma separated list of 'attname = value' */
11301142
sep="";
@@ -1134,7 +1146,8 @@ get_update_query_def(Query *query, deparse_context *context)
11341146

11351147
appendStringInfo(buf,sep);
11361148
sep=", ";
1137-
appendStringInfo(buf,"\"%s\" = ",tle->resdom->resname);
1149+
appendStringInfo(buf,"%s = ",
1150+
quote_identifier(tle->resdom->resname));
11381151
get_tle_expr(tle,context);
11391152
}
11401153

@@ -1162,7 +1175,8 @@ get_delete_query_def(Query *query, deparse_context *context)
11621175
* ----------
11631176
*/
11641177
rte= (RangeTblEntry*)nth(query->resultRelation-1,query->rtable);
1165-
appendStringInfo(buf,"DELETE FROM \"%s\"",rte->relname);
1178+
appendStringInfo(buf,"DELETE FROM %s",
1179+
quote_identifier(rte->relname));
11661180

11671181
/* Add a WHERE clause if given */
11681182
if (query->qual!=NULL)
@@ -1227,11 +1241,12 @@ get_rule_expr(Node *node, deparse_context *context)
12271241
elseif (!strcmp(rte->refname,"*CURRENT*"))
12281242
appendStringInfo(buf,"old.");
12291243
else
1230-
appendStringInfo(buf,"\"%s\".",rte->refname);
1244+
appendStringInfo(buf,"%s.",
1245+
quote_identifier(rte->refname));
12311246
}
1232-
appendStringInfo(buf,"\"%s\"",
1233-
get_attribute_name(rte->relid,
1234-
var->varattno));
1247+
appendStringInfo(buf,"%s",
1248+
quote_identifier(get_attribute_name(rte->relid,
1249+
var->varattno)));
12351250
}
12361251
break;
12371252

@@ -1332,7 +1347,8 @@ get_rule_expr(Node *node, deparse_context *context)
13321347
{
13331348
Aggref*aggref= (Aggref*)node;
13341349

1335-
appendStringInfo(buf,"\"%s\"(",aggref->aggname);
1350+
appendStringInfo(buf,"%s(",
1351+
quote_identifier(aggref->aggname));
13361352
get_rule_expr(aggref->target,context);
13371353
appendStringInfo(buf,")");
13381354
}
@@ -1453,7 +1469,7 @@ get_func_expr(Expr *expr, deparse_context *context)
14531469
* Build a string of proname(args)
14541470
* ----------
14551471
*/
1456-
appendStringInfo(buf,"\"%s\"(",proname);
1472+
appendStringInfo(buf,"%s(",quote_identifier(proname));
14571473
sep="";
14581474
foreach(l,expr->args)
14591475
{
@@ -1566,7 +1582,7 @@ get_tle_expr(TargetEntry *tle, deparse_context *context)
15661582
/* ----------
15671583
* get_const_expr
15681584
*
1569-
*Make a string representationwith the type cast outof a Const
1585+
*Make a string representation of a Const
15701586
* ----------
15711587
*/
15721588
staticvoid
@@ -1598,34 +1614,55 @@ get_const_expr(Const *constval, deparse_context *context)
15981614
extval= (char*) (*fmgr_faddr(&finfo_output)) (constval->constvalue,
15991615
&isnull,-1);
16001616

1601-
/*
1602-
* We must quote any funny characters in the constant's representation.
1603-
* XXX Any MULTIBYTE considerations here?
1604-
*/
1605-
appendStringInfoChar(buf,'\'');
1606-
for (valptr=extval;*valptr;valptr++)
1617+
switch (constval->consttype)
16071618
{
1608-
charch=*valptr;
1609-
if (ch=='\''||ch=='\\')
1610-
{
1611-
appendStringInfoChar(buf,'\\');
1612-
appendStringInfoChar(buf,ch);
1613-
}
1614-
elseif (ch >=0&&ch<' ')
1615-
{
1616-
appendStringInfo(buf,"\\%03o",ch);
1617-
}
1618-
else
1619-
appendStringInfoChar(buf,ch);
1619+
caseINT2OID:
1620+
caseINT4OID:
1621+
caseOIDOID:/* int types */
1622+
caseFLOAT4OID:
1623+
caseFLOAT8OID:/* float types */
1624+
/* These types are printed without quotes */
1625+
appendStringInfo(buf,extval);
1626+
break;
1627+
default:
1628+
/*
1629+
* We must quote any funny characters in the constant's
1630+
* representation.
1631+
* XXX Any MULTIBYTE considerations here?
1632+
*/
1633+
appendStringInfoChar(buf,'\'');
1634+
for (valptr=extval;*valptr;valptr++)
1635+
{
1636+
charch=*valptr;
1637+
if (ch=='\''||ch=='\\')
1638+
{
1639+
appendStringInfoChar(buf,'\\');
1640+
appendStringInfoChar(buf,ch);
1641+
}
1642+
elseif (ch >=0&&ch<' ')
1643+
appendStringInfo(buf,"\\%03o", (int)ch);
1644+
else
1645+
appendStringInfoChar(buf,ch);
1646+
}
1647+
appendStringInfoChar(buf,'\'');
1648+
break;
16201649
}
1621-
appendStringInfoChar(buf,'\'');
1622-
pfree(extval);
16231650

1624-
extval= (char*)nameout(&(typeStruct->typname));
1625-
/* probably would be better to recognize UNKNOWN by OID... */
1626-
if (strcmp(extval,"unknown")!=0)
1627-
appendStringInfo(buf,"::\"%s\"",extval);
16281651
pfree(extval);
1652+
1653+
switch (constval->consttype)
1654+
{
1655+
caseINT4OID:
1656+
caseFLOAT8OID:
1657+
caseUNKNOWNOID:
1658+
/* These types can be left unlabeled */
1659+
break;
1660+
default:
1661+
extval= (char*)nameout(&(typeStruct->typname));
1662+
appendStringInfo(buf,"::%s",quote_identifier(extval));
1663+
pfree(extval);
1664+
break;
1665+
}
16291666
}
16301667

16311668

@@ -1696,6 +1733,52 @@ get_sublink_expr(Node *node, deparse_context *context)
16961733
appendStringInfo(buf,"))");
16971734
}
16981735

1736+
/* ----------
1737+
* quote_identifier- Quote an identifier only if needed
1738+
*
1739+
* When quotes are needed, we palloc the required space; slightly
1740+
* space-wasteful but well worth it for notational simplicity.
1741+
* ----------
1742+
*/
1743+
staticchar*
1744+
quote_identifier(char*ident)
1745+
{
1746+
/*
1747+
* Can avoid quoting if ident starts with a lowercase letter and
1748+
* contains only lowercase letters, digits, and underscores.
1749+
* Otherwise, supply quotes.
1750+
*/
1751+
boolsafe;
1752+
char*result;
1753+
1754+
/*
1755+
* would like to use <ctype.h> macros here, but they might yield
1756+
* unwanted locale-specific results...
1757+
*/
1758+
safe= (ident[0] >='a'&&ident[0] <='z');
1759+
if (safe)
1760+
{
1761+
char*ptr;
1762+
1763+
for (ptr=ident+1;*ptr;ptr++)
1764+
{
1765+
charch=*ptr;
1766+
1767+
safe= ((ch >='a'&&ch <='z')||
1768+
(ch >='0'&&ch <='9')||
1769+
(ch=='_'));
1770+
if (!safe)
1771+
break;
1772+
}
1773+
}
1774+
1775+
if (safe)
1776+
returnident;/* no change needed */
1777+
1778+
result= (char*)palloc(strlen(ident)+2+1);
1779+
sprintf(result,"\"%s\"",ident);
1780+
returnresult;
1781+
}
16991782

17001783
/* ----------
17011784
* get_relation_name- Get a relation name by Oid
@@ -1729,7 +1812,8 @@ get_attribute_name(Oid relid, int2 attnum)
17291812
Form_pg_attributeattStruct;
17301813

17311814
atttup=SearchSysCacheTuple(ATTNUM,
1732-
ObjectIdGetDatum(relid), (Datum)attnum,0,0);
1815+
ObjectIdGetDatum(relid), (Datum)attnum,
1816+
0,0);
17331817
if (!HeapTupleIsValid(atttup))
17341818
elog(ERROR,"cache lookup of attribute %d in relation %u failed",
17351819
attnum,relid);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp