Skip to content

Commit 469673f

Browse files
committed
Fix format_type() to display correct lengths for BIT/BIT VARYING.
Also, make it depend on type OIDs rather than type names for more consistency with rest of backend.
1 parent e67ff6b commit 469673f

File tree

1 file changed

+121
-105
lines changed

1 file changed

+121
-105
lines changed

src/backend/utils/adt/format_type.c

Lines changed: 121 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,34 @@
1-
/* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.2 2000/07/09 21:30:12 petere Exp $ */
1+
/*-------------------------------------------------------------------------
2+
*
3+
* format_type.c
4+
* Display type names "nicely".
5+
*
6+
*
7+
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
8+
* Portions Copyright (c) 1994, Regents of the University of California
9+
*
10+
* IDENTIFICATION
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.3 2000/08/21 18:23:18 tgl Exp $
12+
*
13+
*-------------------------------------------------------------------------
14+
*/
215

316
#include "postgres.h"
417

518
#include <ctype.h>
6-
#include <stdarg.h>
719

820
#include "fmgr.h"
921
#include "catalog/pg_type.h"
1022
#include "utils/builtins.h"
1123
#include "utils/syscache.h"
1224

13-
#define streq(a, b) (strcmp((a), (b))==0)
1425
#define MAX_INT32_LEN 11
1526
#define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str))
1627

1728

29+
static char *format_type_internal(Oid type_oid, int32 typemod);
30+
31+
1832
static char *
1933
psnprintf(size_t len, const char * fmt, ...)
2034
{
@@ -31,11 +45,6 @@ psnprintf(size_t len, const char * fmt, ...)
3145
}
3246

3347

34-
static char *
35-
format_type_internal(Oid type_oid, int32 typemod, bool with_typemod);
36-
37-
38-
3948
/*
4049
* SQL function: format_type(type_oid, typemod)
4150
*
@@ -55,29 +64,29 @@ Datum
5564
format_type(PG_FUNCTION_ARGS)
5665
{
5766
Oid type_oid;
58-
bool with_typemod;
59-
int32 typemod = 0;
67+
int32 typemod;
6068
char *result;
6169

6270
if (PG_ARGISNULL(0))
6371
PG_RETURN_NULL();
6472

65-
type_oid = DatumGetObjectId(PG_GETARG_DATUM(0));
73+
type_oid = PG_GETARG_OID(0);
6674

67-
with_typemod = !PG_ARGISNULL(1);
68-
if (with_typemod)
75+
if (!PG_ARGISNULL(1))
6976
typemod = PG_GETARG_INT32(1);
77+
else
78+
typemod = -1; /* default typmod */
7079

71-
result = format_type_internal(type_oid, typemod, with_typemod);
80+
result = format_type_internal(type_oid, typemod);
7281

73-
PG_RETURN_TEXT_P(_textin(result));
82+
PG_RETURN_DATUM(_textin(result));
7483
}
7584

7685

77-
7886
static char *
79-
format_type_internal(Oid type_oid, int32 typemod, bool with_typemod)
87+
format_type_internal(Oid type_oid, int32 typemod)
8088
{
89+
bool with_typemod = (typemod >= 0);
8190
HeapTuple tuple;
8291
Oid array_base_type;
8392
int16 typlen;
@@ -86,13 +95,13 @@ format_type_internal(Oid type_oid, int32 typemod, bool with_typemod)
8695
char *buf;
8796

8897
if (type_oid == InvalidOid)
89-
return "-";
98+
return pstrdup("-");
9099

91100
tuple = SearchSysCacheTuple(TYPEOID, ObjectIdGetDatum(type_oid),
92101
0, 0, 0);
93102

94103
if (!HeapTupleIsValid(tuple))
95-
return "???";
104+
return pstrdup("???");
96105

97106
array_base_type = ((Form_pg_type) GETSTRUCT(tuple))->typelem;
98107
typlen = ((Form_pg_type) GETSTRUCT(tuple))->typlen;
@@ -102,97 +111,104 @@ format_type_internal(Oid type_oid, int32 typemod, bool with_typemod)
102111
ObjectIdGetDatum(array_base_type),
103112
0, 0, 0);
104113
if (!HeapTupleIsValid(tuple))
105-
return "???[]";
114+
return pstrdup("???[]");
106115
is_array = true;
116+
type_oid = array_base_type;
107117
}
108118
else
109119
is_array = false;
110-
111-
name = NameStr(((Form_pg_type) GETSTRUCT(tuple))->typname);
112-
113120

114-
if (streq(name, "bit"))
121+
switch (type_oid)
115122
{
116-
if (with_typemod)
117-
buf = psnprintf(5 + MAX_INT32_LEN + 1, "bit(%d)", (int) typemod - 4);
118-
else
119-
buf = pstrdup("bit");
120-
}
121-
122-
else if (streq(name, "bool"))
123-
buf = pstrdup("boolean");
124-
125-
else if (streq(name, "bpchar"))
126-
{
127-
if (with_typemod)
128-
buf = psnprintf(11 + MAX_INT32_LEN + 1, "character(%d)", (int) typemod - 4);
129-
else
130-
buf = pstrdup("character");
131-
}
132-
133-
/* This char type is the single-byte version. You have to
134-
* double-quote it to get at it in the parser. */
135-
else if (streq(name, "char"))
136-
buf = pstrdup("\"char\"");
137-
138-
else if (streq(name, "float4"))
139-
buf = pstrdup("real");
140-
141-
else if (streq(name, "float8"))
142-
buf = pstrdup("double precision");
143-
144-
else if (streq(name, "int2"))
145-
buf = pstrdup("smallint");
146-
147-
else if (streq(name, "int4"))
148-
buf = pstrdup("integer");
149-
150-
else if (streq(name, "int8"))
151-
buf = pstrdup("bigint");
152-
153-
else if (streq(name, "numeric"))
154-
{
155-
if (with_typemod)
156-
buf = psnprintf(10 + 2 * MAX_INT32_LEN + 1, "numeric(%d,%d)",
157-
((typemod - VARHDRSZ) >> 16) & 0xffff,
158-
(typemod - VARHDRSZ) & 0xffff);
159-
else
160-
buf = pstrdup("numeric");
161-
}
162-
163-
else if (streq(name, "timetz"))
164-
buf = pstrdup("time with time zone");
165-
166-
else if (streq(name, "varbit"))
167-
{
168-
if (with_typemod)
169-
buf = psnprintf(13 + MAX_INT32_LEN + 1, "bit varying(%d)", (int) typemod - 4);
170-
else
171-
buf = pstrdup("bit varying");
172-
}
173-
174-
else if (streq(name, "varchar"))
175-
{
176-
if (with_typemod)
177-
buf = psnprintf(19 + MAX_INT32_LEN + 1, "character varying(%d)", (int) typemod - 4);
178-
else
179-
buf = pstrdup("character varying");
180-
}
181-
182-
else
183-
{
184-
if (strspn(name, "abcdefghijklmnopqrstuvwxyz0123456789_") != strlen(name)
185-
|| isdigit((int) name[0]))
186-
buf = psnprintf(strlen(name) + 3, "\"%s\"", name);
187-
else
188-
buf = name;
123+
case BOOLOID:
124+
buf = pstrdup("boolean");
125+
break;
126+
127+
case BPCHAROID:
128+
if (with_typemod)
129+
buf = psnprintf(11 + MAX_INT32_LEN + 1, "character(%d)",
130+
(int) (typemod - VARHDRSZ));
131+
else
132+
buf = pstrdup("character");
133+
break;
134+
135+
case CHAROID:
136+
/* This char type is the single-byte version. You have to
137+
* double-quote it to get at it in the parser.
138+
*/
139+
buf = pstrdup("\"char\"");
140+
break;
141+
142+
case FLOAT4OID:
143+
buf = pstrdup("real");
144+
break;
145+
146+
case FLOAT8OID:
147+
buf = pstrdup("double precision");
148+
break;
149+
150+
case INT2OID:
151+
buf = pstrdup("smallint");
152+
break;
153+
154+
case INT4OID:
155+
buf = pstrdup("integer");
156+
break;
157+
158+
case INT8OID:
159+
buf = pstrdup("bigint");
160+
break;
161+
162+
case NUMERICOID:
163+
if (with_typemod)
164+
buf = psnprintf(10 + 2 * MAX_INT32_LEN + 1, "numeric(%d,%d)",
165+
((typemod - VARHDRSZ) >> 16) & 0xffff,
166+
(typemod - VARHDRSZ) & 0xffff);
167+
else
168+
buf = pstrdup("numeric");
169+
break;
170+
171+
case TIMETZOID:
172+
buf = pstrdup("time with time zone");
173+
break;
174+
175+
case VARBITOID:
176+
if (with_typemod)
177+
buf = psnprintf(13 + MAX_INT32_LEN + 1, "bit varying(%d)",
178+
(int) typemod);
179+
else
180+
buf = pstrdup("bit varying");
181+
break;
182+
183+
case VARCHAROID:
184+
if (with_typemod)
185+
buf = psnprintf(19 + MAX_INT32_LEN + 1,
186+
"character varying(%d)",
187+
(int) (typemod - VARHDRSZ));
188+
else
189+
buf = pstrdup("character varying");
190+
break;
191+
192+
case ZPBITOID:
193+
if (with_typemod)
194+
buf = psnprintf(5 + MAX_INT32_LEN + 1, "bit(%d)",
195+
(int) typemod);
196+
else
197+
buf = pstrdup("bit");
198+
break;
199+
200+
default:
201+
name = NameStr(((Form_pg_type) GETSTRUCT(tuple))->typname);
202+
if (strspn(name, "abcdefghijklmnopqrstuvwxyz0123456789_") != strlen(name)
203+
|| isdigit((int) name[0]))
204+
buf = psnprintf(strlen(name) + 3, "\"%s\"", name);
205+
else
206+
buf = pstrdup(name);
207+
break;
189208
}
190209

191210
if (is_array)
192-
{
193-
char * buf2 = psnprintf(strlen(buf) + 3, "%s[]", buf);
194-
buf = buf2;
195-
}
211+
buf = psnprintf(strlen(buf) + 3, "%s[]", buf);
196212

197213
return buf;
198214
}
@@ -209,10 +225,10 @@ format_type_internal(Oid type_oid, int32 typemod, bool with_typemod)
209225
Datum
210226
oidvectortypes(PG_FUNCTION_ARGS)
211227
{
212-
int numargs;
213-
int num;
214228
Oid *oidArray = (Oid *) PG_GETARG_POINTER(0);
215229
char *result;
230+
int numargs;
231+
int num;
216232
size_t total;
217233
size_t left;
218234

@@ -231,7 +247,7 @@ oidvectortypes(PG_FUNCTION_ARGS)
231247

232248
for (num = 0; num < numargs; num++)
233249
{
234-
char * typename = format_type_internal(oidArray[num], 0, false);
250+
char * typename = format_type_internal(oidArray[num], -1);
235251

236252
if (left < strlen(typename) + 2)
237253
{
@@ -249,5 +265,5 @@ oidvectortypes(PG_FUNCTION_ARGS)
249265
left -= strlen(typename);
250266
}
251267

252-
PG_RETURN_TEXT_P(_textin(result));
268+
PG_RETURN_DATUM(_textin(result));
253269
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy