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

Commited1ff84

Browse files
committed
Tweak format_type so that we get good behavior for both column type
display (with a typemod) and function arg/result type display (withouta typemod).
1 parent40015cd commited1ff84

File tree

2 files changed

+78
-49
lines changed

2 files changed

+78
-49
lines changed

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

Lines changed: 74 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.22 2001/11/12 21:04:46 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.23 2001/11/19 19:51:20 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -27,29 +27,17 @@
2727
#include"mb/pg_wchar.h"
2828
#endif
2929

30+
3031
#defineMASK(b) (1 << (b))
3132

3233
#defineMAX_INT32_LEN 11
3334
#define_textin(str) DirectFunctionCall1(textin, CStringGetDatum(str))
3435

35-
36-
staticchar*format_type_internal(Oidtype_oid,int32typemod,boolallow_invalid);
37-
38-
39-
staticchar*
40-
psnprintf(size_tlen,constchar*fmt,...)
41-
{
42-
va_listap;
43-
char*buf;
44-
45-
buf=palloc(len);
46-
47-
va_start(ap,fmt);
48-
vsnprintf(buf,len,fmt,ap);
49-
va_end(ap);
50-
51-
returnbuf;
52-
}
36+
staticchar*format_type_internal(Oidtype_oid,int32typemod,
37+
booltypemod_given,boolallow_invalid);
38+
staticchar*psnprintf(size_tlen,constchar*fmt, ...)
39+
/* This lets gcc check the format string for consistency. */
40+
__attribute__((format(printf,2,3)));
5341

5442

5543
/*
@@ -61,11 +49,22 @@ psnprintf(size_t len, const char *fmt,...)
6149
* a standard type. Otherwise you just get pg_type.typname back,
6250
* double quoted if it contains funny characters.
6351
*
64-
* If typemod is null (in the SQL sense) then you won't get any
65-
* "..(x)" type qualifiers. The result is not technically correct,
66-
* because the various types interpret missing type modifiers
67-
* differently, but it can be used as a convenient way to format
68-
* system catalogs, e.g., pg_aggregate, in psql.
52+
* If typemod is NULL then we are formatting a type name in a context where
53+
* no typemod is available, eg a function argument or result type. This
54+
* yields a slightly different result from specifying typemod = -1 in some
55+
* cases. Given typemod = -1 we feel compelled to produce an output that
56+
* the parser will interpret as having typemod -1, so that pg_dump will
57+
* produce CREATE TABLE commands that recreate the original state. But
58+
* given NULL typemod, we assume that the parser's interpretation of
59+
* typemod doesn't matter, and so we are willing to output a slightly
60+
* "prettier" representation of the same type. For example, type = bpchar
61+
* and typemod = NULL gets you "character", whereas typemod = -1 gets you
62+
* "bpchar" --- the former will be interpreted as character(1) by the
63+
* parser, which does not yield typemod -1.
64+
*
65+
* XXX encoding a meaning in typemod = NULL is ugly; it'd have been
66+
* cleaner to make two functions of one and two arguments respectively.
67+
* Not worth changing it now, however.
6968
*/
7069
Datum
7170
format_type(PG_FUNCTION_ARGS)
@@ -74,17 +73,21 @@ format_type(PG_FUNCTION_ARGS)
7473
int32typemod;
7574
char*result;
7675

76+
/* Since this function is not strict, we must test for null args */
7777
if (PG_ARGISNULL(0))
7878
PG_RETURN_NULL();
7979

8080
type_oid=PG_GETARG_OID(0);
8181

82-
if (!PG_ARGISNULL(1))
83-
typemod=PG_GETARG_INT32(1);
82+
if (PG_ARGISNULL(1))
83+
{
84+
result=format_type_internal(type_oid,-1, false, true);
85+
}
8486
else
85-
typemod=-1;/* default typmod */
86-
87-
result=format_type_internal(type_oid,typemod, true);
87+
{
88+
typemod=PG_GETARG_INT32(1);
89+
result=format_type_internal(type_oid,typemod, true, true);
90+
}
8891

8992
PG_RETURN_DATUM(_textin(result));
9093
}
@@ -98,7 +101,7 @@ format_type(PG_FUNCTION_ARGS)
98101
char*
99102
format_type_be(Oidtype_oid)
100103
{
101-
returnformat_type_internal(type_oid,-1, false);
104+
returnformat_type_internal(type_oid,-1, false, false);
102105
}
103106

104107
/*
@@ -107,15 +110,16 @@ format_type_be(Oid type_oid)
107110
char*
108111
format_type_with_typemod(Oidtype_oid,int32typemod)
109112
{
110-
returnformat_type_internal(type_oid,typemod, false);
113+
returnformat_type_internal(type_oid,typemod,true,false);
111114
}
112115

113116

114117

115118
staticchar*
116-
format_type_internal(Oidtype_oid,int32typemod,boolallow_invalid)
119+
format_type_internal(Oidtype_oid,int32typemod,
120+
booltypemod_given,boolallow_invalid)
117121
{
118-
boolwith_typemod= (typemod >=0);
122+
boolwith_typemod=typemod_given&&(typemod >=0);
119123
HeapTupletuple;
120124
Oidarray_base_type;
121125
int16typlen;
@@ -140,7 +144,7 @@ format_type_internal(Oid type_oid, int32 typemod, bool allow_invalid)
140144

141145
array_base_type= ((Form_pg_type)GETSTRUCT(tuple))->typelem;
142146
typlen= ((Form_pg_type)GETSTRUCT(tuple))->typlen;
143-
if (array_base_type!=0&&typlen<0)
147+
if (array_base_type!=InvalidOid&&typlen<0)
144148
{
145149
/* Switch our attention to the array element type */
146150
ReleaseSysCache(tuple);
@@ -167,15 +171,17 @@ format_type_internal(Oid type_oid, int32 typemod, bool allow_invalid)
167171
if (with_typemod)
168172
buf=psnprintf(5+MAX_INT32_LEN+1,"bit(%d)",
169173
(int)typemod);
170-
else
174+
elseif (typemod_given)
171175
{
172176
/*
173-
* bit withnotypmod is not the same as BIT, which means
177+
* bit with typmod -1 is not the same as BIT, which means
174178
* BIT(1) per SQL spec. Report it as the quoted typename
175179
* so that parser will not assign a bogus typmod.
176180
*/
177181
buf=pstrdup("\"bit\"");
178182
}
183+
else
184+
buf=pstrdup("bit");
179185
break;
180186

181187
caseBOOLOID:
@@ -186,15 +192,17 @@ format_type_internal(Oid type_oid, int32 typemod, bool allow_invalid)
186192
if (with_typemod)
187193
buf=psnprintf(11+MAX_INT32_LEN+1,"character(%d)",
188194
(int) (typemod-VARHDRSZ));
189-
else
195+
elseif (typemod_given)
190196
{
191197
/*
192-
* bpchar withnotypmod is not the same as CHARACTER,
198+
* bpchar with typmod -1 is not the same as CHARACTER,
193199
* which means CHARACTER(1) per SQL spec. Report it as
194200
* bpchar so that parser will not assign a bogus typmod.
195201
*/
196202
buf=pstrdup("bpchar");
197203
}
204+
else
205+
buf=pstrdup("character");
198206
break;
199207

200208
caseCHAROID:
@@ -352,6 +360,10 @@ format_type_internal(Oid type_oid, int32 typemod, bool allow_invalid)
352360

353361
default:
354362
name=NameStr(((Form_pg_type)GETSTRUCT(tuple))->typname);
363+
/*
364+
* Double-quote the name if it's not a standard identifier.
365+
* Note this is *necessary* for ruleutils.c's use.
366+
*/
355367
if (strspn(name,"abcdefghijklmnopqrstuvwxyz0123456789_")!=strlen(name)
356368
||isdigit((unsignedchar)name[0]))
357369
buf=psnprintf(strlen(name)+3,"\"%s\"",name);
@@ -456,13 +468,15 @@ oidvectortypes(PG_FUNCTION_ARGS)
456468

457469
for (num=0;num<numargs;num++)
458470
{
459-
char*typename=format_type_internal(oidArray[num],-1, true);
471+
char*typename=format_type_internal(oidArray[num],-1,
472+
false, true);
473+
size_tslen=strlen(typename);
460474

461-
if (left<strlen(typename)+2)
475+
if (left<(slen+2))
462476
{
463-
total+=strlen(typename)+2;
477+
total+=slen+2;
464478
result=repalloc(result,total);
465-
left+=strlen(typename)+2;
479+
left+=slen+2;
466480
}
467481

468482
if (num>0)
@@ -471,8 +485,25 @@ oidvectortypes(PG_FUNCTION_ARGS)
471485
left-=2;
472486
}
473487
strcat(result,typename);
474-
left-=strlen(typename);
488+
left-=slen;
475489
}
476490

477491
PG_RETURN_DATUM(_textin(result));
478492
}
493+
494+
495+
/* snprintf into a palloc'd string */
496+
staticchar*
497+
psnprintf(size_tlen,constchar*fmt, ...)
498+
{
499+
va_listap;
500+
char*buf;
501+
502+
buf=palloc(len);
503+
504+
va_start(ap,fmt);
505+
vsnprintf(buf,len,fmt,ap);
506+
va_end(ap);
507+
508+
returnbuf;
509+
}

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

Lines changed: 4 additions & 6 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.86 2001/10/25 05:49:45 momjian Exp $
6+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.87 2001/11/19 19:51:20 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -2054,11 +2054,9 @@ get_func_expr(Expr *expr, deparse_context *context)
20542054
/*
20552055
* Show typename with appropriate length decoration. Note that
20562056
* since exprIsLengthCoercion succeeded, the function's output
2057-
* type is the right thing to use.
2058-
*
2059-
* XXX In general it is incorrect to quote the result of
2060-
* format_type_with_typemod, but are there any special cases where
2061-
* we should do so?
2057+
* type is the right thing to report. Also note we don't need
2058+
* to quote the result of format_type_with_typemod: it takes
2059+
* care of double-quoting any identifier that needs it.
20622060
*/
20632061
typdesc=format_type_with_typemod(procStruct->prorettype,
20642062
coercedTypmod);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp