oidvectortypes: use SQL type names and separate by commas

psql \df: use format_type and oidvectortypes
map type REAL to float4, not float8
psql \dd :work around UNION bug
This commit is contained in:
Peter Eisentraut 2000-07-09 21:30:21 +00:00
parent f90771236d
commit b54faa1b15
5 changed files with 112 additions and 86 deletions

View File

@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.176 2000/07/07 19:24:35 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.177 2000/07/09 21:30:10 petere Exp $
* *
* HISTORY * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
@ -3944,7 +3944,7 @@ Numeric: FLOAT opt_float
; ;
numeric: FLOAT { $$ = xlateSqlType("float"); } numeric: FLOAT { $$ = xlateSqlType("float"); }
| DOUBLE PRECISION { $$ = xlateSqlType("float"); } | DOUBLE PRECISION { $$ = xlateSqlType("float8"); }
| DECIMAL { $$ = xlateSqlType("decimal"); } | DECIMAL { $$ = xlateSqlType("decimal"); }
| DEC { $$ = xlateSqlType("decimal"); } | DEC { $$ = xlateSqlType("decimal"); }
| NUMERIC { $$ = xlateSqlType("numeric"); } | NUMERIC { $$ = xlateSqlType("numeric"); }
@ -5781,8 +5781,9 @@ xlateSqlType(char *name)
return "int2"; return "int2";
else if (strcmp(name, "bigint") == 0) else if (strcmp(name, "bigint") == 0)
return "int8"; return "int8";
else if ((strcmp(name, "real") == 0) else if (strcmp(name, "real") == 0)
|| (strcmp(name, "float") == 0)) return "float4";
else if (strcmp(name, "float") == 0)
return "float8"; return "float8";
else if (strcmp(name, "decimal") == 0) else if (strcmp(name, "decimal") == 0)
return "numeric"; return "numeric";

View File

@ -1,4 +1,4 @@
/* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.1 2000/07/07 19:24:37 petere Exp $ */ /* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.2 2000/07/09 21:30:12 petere Exp $ */
#include "postgres.h" #include "postgres.h"
@ -12,6 +12,7 @@
#define streq(a, b) (strcmp((a), (b))==0) #define streq(a, b) (strcmp((a), (b))==0)
#define MAX_INT32_LEN 11 #define MAX_INT32_LEN 11
#define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str))
static char * static char *
@ -30,7 +31,9 @@ psnprintf(size_t len, const char * fmt, ...)
} }
#define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str)) static char *
format_type_internal(Oid type_oid, int32 typemod, bool with_typemod);
/* /*
@ -51,15 +54,10 @@ psnprintf(size_t len, const char * fmt, ...)
Datum Datum
format_type(PG_FUNCTION_ARGS) format_type(PG_FUNCTION_ARGS)
{ {
Oid type_oid; Oid type_oid;
bool with_typemod; bool with_typemod;
int32 typemod = 0; int32 typemod = 0;
char * buf; char *result;
char * name;
Oid array_base_type;
int16 typlen;
bool is_array;
HeapTuple tuple;
if (PG_ARGISNULL(0)) if (PG_ARGISNULL(0))
PG_RETURN_NULL(); PG_RETURN_NULL();
@ -70,11 +68,31 @@ format_type(PG_FUNCTION_ARGS)
if (with_typemod) if (with_typemod)
typemod = PG_GETARG_INT32(1); typemod = PG_GETARG_INT32(1);
result = format_type_internal(type_oid, typemod, with_typemod);
PG_RETURN_TEXT_P(_textin(result));
}
static char *
format_type_internal(Oid type_oid, int32 typemod, bool with_typemod)
{
HeapTuple tuple;
Oid array_base_type;
int16 typlen;
bool is_array;
char *name;
char *buf;
if (type_oid == InvalidOid)
return "-";
tuple = SearchSysCacheTuple(TYPEOID, ObjectIdGetDatum(type_oid), tuple = SearchSysCacheTuple(TYPEOID, ObjectIdGetDatum(type_oid),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
PG_RETURN_TEXT_P(_textin("???")); return "???";
array_base_type = ((Form_pg_type) GETSTRUCT(tuple))->typelem; array_base_type = ((Form_pg_type) GETSTRUCT(tuple))->typelem;
typlen = ((Form_pg_type) GETSTRUCT(tuple))->typlen; typlen = ((Form_pg_type) GETSTRUCT(tuple))->typlen;
@ -84,15 +102,15 @@ format_type(PG_FUNCTION_ARGS)
ObjectIdGetDatum(array_base_type), ObjectIdGetDatum(array_base_type),
0, 0, 0); 0, 0, 0);
if (!HeapTupleIsValid(tuple)) if (!HeapTupleIsValid(tuple))
PG_RETURN_TEXT_P(_textin("???[]")); return "???[]";
is_array = true; is_array = true;
} }
else else
is_array = false; is_array = false;
name = NameStr(((Form_pg_type) GETSTRUCT(tuple))->typname); name = NameStr(((Form_pg_type) GETSTRUCT(tuple))->typname);
if (streq(name, "bit")) if (streq(name, "bit"))
{ {
if (with_typemod) if (with_typemod)
@ -116,14 +134,13 @@ format_type(PG_FUNCTION_ARGS)
* double-quote it to get at it in the parser. */ * double-quote it to get at it in the parser. */
else if (streq(name, "char")) else if (streq(name, "char"))
buf = pstrdup("\"char\""); buf = pstrdup("\"char\"");
#if 0
/* The parser has these backwards, so leave as is for now. */
else if (streq(name, "float4")) else if (streq(name, "float4"))
buf = pstrdup("real"); buf = pstrdup("real");
else if (streq(name, "float8")) else if (streq(name, "float8"))
buf = pstrdup("double precision"); buf = pstrdup("double precision");
#endif
else if (streq(name, "int2")) else if (streq(name, "int2"))
buf = pstrdup("smallint"); buf = pstrdup("smallint");
@ -177,5 +194,60 @@ format_type(PG_FUNCTION_ARGS)
buf = buf2; buf = buf2;
} }
PG_RETURN_TEXT_P(_textin(buf)); return buf;
}
/*
* oidvectortypes - converts a vector of type OIDs to "typname" list
*
* The interface for this function is wrong: it should be told how many
* OIDs are significant in the input vector, so that trailing InvalidOid
* argument types can be recognized.
*/
Datum
oidvectortypes(PG_FUNCTION_ARGS)
{
int numargs;
int num;
Oid *oidArray = (Oid *) PG_GETARG_POINTER(0);
char *result;
size_t total;
size_t left;
/* Try to guess how many args there are :-( */
numargs = 0;
for (num = 0; num < FUNC_MAX_ARGS; num++)
{
if (oidArray[num] != InvalidOid)
numargs = num + 1;
}
total = 20 * numargs + 1;
result = palloc(total);
result[0] = '\0';
left = total - 1;
for (num = 0; num < numargs; num++)
{
char * typename = format_type_internal(oidArray[num], 0, false);
if (left < strlen(typename) + 2)
{
total += strlen(typename) + 2;
result = repalloc(result, total);
left += strlen(typename) + 2;
}
if (num > 0)
{
strcat(result, ", ");
left -= 2;
}
strcat(result, typename);
left -= strlen(typename);
}
PG_RETURN_TEXT_P(_textin(result));
} }

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.57 2000/07/03 23:09:52 wieck Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.58 2000/07/09 21:30:12 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -238,53 +238,6 @@ regprocout(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result); PG_RETURN_CSTRING(result);
} }
/*
* oidvectortypes - converts a vector of type OIDs to "typname" list
*
* The interface for this function is wrong: it should be told how many
* OIDs are significant in the input vector, so that trailing InvalidOid
* argument types can be recognized.
*/
Datum
oidvectortypes(PG_FUNCTION_ARGS)
{
Oid *oidArray = (Oid *) PG_GETARG_POINTER(0);
HeapTuple typetup;
text *result;
int numargs,
num;
/* Try to guess how many args there are :-( */
numargs = 0;
for (num = 0; num < FUNC_MAX_ARGS; num++)
{
if (oidArray[num] != InvalidOid)
numargs = num + 1;
}
result = (text *) palloc((NAMEDATALEN + 1) * numargs + VARHDRSZ + 1);
*VARDATA(result) = '\0';
for (num = 0; num < numargs; num++)
{
typetup = SearchSysCacheTuple(TYPEOID,
ObjectIdGetDatum(oidArray[num]),
0, 0, 0);
if (HeapTupleIsValid(typetup))
{
char *s;
s = NameStr(((Form_pg_type) GETSTRUCT(typetup))->typname);
StrNCpy(VARDATA(result) + strlen(VARDATA(result)), s,
NAMEDATALEN);
strcat(VARDATA(result), " ");
}
else
strcat(VARDATA(result), "- ");
}
VARATT_SIZEP(result) = strlen(VARDATA(result)) + VARHDRSZ;
PG_RETURN_TEXT_P(result);
}
/***************************************************************************** /*****************************************************************************

View File

@ -3,7 +3,7 @@
* *
* Copyright 2000 by PostgreSQL Global Development Group * Copyright 2000 by PostgreSQL Global Development Group
* *
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.22 2000/07/07 19:24:38 petere Exp $ * $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.23 2000/07/09 21:30:19 petere Exp $
*/ */
#include "postgres.h" #include "postgres.h"
#include "describe.h" #include "describe.h"
@ -103,7 +103,7 @@ describeFunctions(const char *name, bool verbose)
* arguments, but have no types defined for those arguments * arguments, but have no types defined for those arguments
*/ */
strcpy(buf, strcpy(buf,
"SELECT t.typname as \"Result\", p.proname as \"Function\",\n" "SELECT format_type(p.prorettype, NULL) as \"Result\", p.proname as \"Function\",\n"
" oidvectortypes(p.proargtypes) as \"Arguments\""); " oidvectortypes(p.proargtypes) as \"Arguments\"");
if (verbose) if (verbose)
strcat(buf, ",\n u.usename as \"Owner\", l.lanname as \"Language\", p.prosrc as \"Source\",\n" strcat(buf, ",\n u.usename as \"Owner\", l.lanname as \"Language\", p.prosrc as \"Source\",\n"
@ -111,13 +111,13 @@ describeFunctions(const char *name, bool verbose)
if (!verbose) if (!verbose)
strcat(buf, strcat(buf,
"\nFROM pg_proc p, pg_type t\n" "\nFROM pg_proc p\n"
"WHERE p.prorettype = t.oid and (pronargs = 0 or oidvectortypes(p.proargtypes) != '')\n"); "WHERE p.prorettype <> 0 and (pronargs = 0 or oidvectortypes(p.proargtypes) <> '')\n");
else else
strcat(buf, strcat(buf,
"\nFROM pg_proc p, pg_type t, pg_language l, pg_user u\n" "\nFROM pg_proc p, pg_language l, pg_user u\n"
"WHERE p.prorettype = t.oid AND p.prolang = l.oid AND p.proowner = u.usesysid\n" "WHERE p.prolang = l.oid AND p.proowner = u.usesysid\n"
" AND (pronargs = 0 or oidvectortypes(p.proargtypes) != '')\n"); " AND p.prorettype <> 0 and (pronargs = 0 or oidvectortypes(p.proargtypes) <> '')\n");
if (name) if (name)
{ {
@ -380,7 +380,7 @@ objectDescription(const char *object)
descbuf[0] = '\0'; descbuf[0] = '\0';
/* Aggregate descriptions */ /* Aggregate descriptions */
strcat(descbuf, "SELECT DISTINCT a.aggname as \"Name\", 'aggregate'::text as \"Object\", d.description as \"Description\"\n" strcat(descbuf, "SELECT DISTINCT a.aggname::text as \"Name\", 'aggregate'::text as \"Object\", d.description as \"Description\"\n"
"FROM pg_aggregate a, pg_description d\n" "FROM pg_aggregate a, pg_description d\n"
"WHERE a.oid = d.objoid\n"); "WHERE a.oid = d.objoid\n");
if (object) if (object)
@ -392,7 +392,7 @@ objectDescription(const char *object)
/* Function descriptions (except in/outs for datatypes) */ /* Function descriptions (except in/outs for datatypes) */
strcat(descbuf, "\nUNION ALL\n\n"); strcat(descbuf, "\nUNION ALL\n\n");
strcat(descbuf, "SELECT DISTINCT p.proname as \"Name\", 'function'::text as \"Object\", d.description as \"Description\"\n" strcat(descbuf, "SELECT DISTINCT p.proname::text as \"Name\", 'function'::text as \"Object\", d.description as \"Description\"\n"
"FROM pg_proc p, pg_description d\n" "FROM pg_proc p, pg_description d\n"
"WHERE p.oid = d.objoid AND (p.pronargs = 0 or oidvectortypes(p.proargtypes) != '')\n"); "WHERE p.oid = d.objoid AND (p.pronargs = 0 or oidvectortypes(p.proargtypes) != '')\n");
if (object) if (object)
@ -404,7 +404,7 @@ objectDescription(const char *object)
/* Operator descriptions */ /* Operator descriptions */
strcat(descbuf, "\nUNION ALL\n\n"); strcat(descbuf, "\nUNION ALL\n\n");
strcat(descbuf, "SELECT DISTINCT o.oprname as \"Name\", 'operator'::text as \"Object\", d.description as \"Description\"\n" strcat(descbuf, "SELECT DISTINCT o.oprname::text as \"Name\", 'operator'::text as \"Object\", d.description as \"Description\"\n"
"FROM pg_operator o, pg_description d\n" "FROM pg_operator o, pg_description d\n"
/* must get comment via associated function */ /* must get comment via associated function */
"WHERE RegprocToOid(o.oprcode) = d.objoid\n"); "WHERE RegprocToOid(o.oprcode) = d.objoid\n");
@ -429,7 +429,7 @@ objectDescription(const char *object)
/* Relation (tables, views, indices, sequences) descriptions */ /* Relation (tables, views, indices, sequences) descriptions */
strcat(descbuf, "\nUNION ALL\n\n"); strcat(descbuf, "\nUNION ALL\n\n");
strcat(descbuf, "SELECT DISTINCT c.relname as \"Name\", 'relation'::text||'('||c.relkind||')' as \"Object\", d.description as \"Description\"\n" strcat(descbuf, "SELECT DISTINCT c.relname::text as \"Name\", 'relation'::text||'('||c.relkind||')' as \"Object\", d.description as \"Description\"\n"
"FROM pg_class c, pg_description d\n" "FROM pg_class c, pg_description d\n"
"WHERE c.oid = d.objoid\n"); "WHERE c.oid = d.objoid\n");
if (object) if (object)
@ -441,7 +441,7 @@ objectDescription(const char *object)
/* Rule description (ignore rules for views) */ /* Rule description (ignore rules for views) */
strcat(descbuf, "\nUNION ALL\n\n"); strcat(descbuf, "\nUNION ALL\n\n");
strcat(descbuf, "SELECT DISTINCT r.rulename as \"Name\", 'rule'::text as \"Object\", d.description as \"Description\"\n" strcat(descbuf, "SELECT DISTINCT r.rulename::text as \"Name\", 'rule'::text as \"Object\", d.description as \"Description\"\n"
"FROM pg_rewrite r, pg_description d\n" "FROM pg_rewrite r, pg_description d\n"
"WHERE r.oid = d.objoid AND r.rulename !~ '^_RET'\n"); "WHERE r.oid = d.objoid AND r.rulename !~ '^_RET'\n");
if (object) if (object)
@ -453,7 +453,7 @@ objectDescription(const char *object)
/* Trigger description */ /* Trigger description */
strcat(descbuf, "\nUNION ALL\n\n"); strcat(descbuf, "\nUNION ALL\n\n");
strcat(descbuf, "SELECT DISTINCT t.tgname as \"Name\", 'trigger'::text as \"Object\", d.description as \"Description\"\n" strcat(descbuf, "SELECT DISTINCT t.tgname::text as \"Name\", 'trigger'::text as \"Object\", d.description as \"Description\"\n"
"FROM pg_trigger t, pg_description d\n" "FROM pg_trigger t, pg_description d\n"
"WHERE t.oid = d.objoid\n"); "WHERE t.oid = d.objoid\n");
if (object) if (object)

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: builtins.h,v 1.122 2000/07/08 03:04:36 tgl Exp $ * $Id: builtins.h,v 1.123 2000/07/09 21:30:21 petere Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -325,7 +325,6 @@ extern Datum texticregexne(PG_FUNCTION_ARGS);
/* regproc.c */ /* regproc.c */
extern Datum regprocin(PG_FUNCTION_ARGS); extern Datum regprocin(PG_FUNCTION_ARGS);
extern Datum regprocout(PG_FUNCTION_ARGS); extern Datum regprocout(PG_FUNCTION_ARGS);
extern Datum oidvectortypes(PG_FUNCTION_ARGS);
extern Datum regproctooid(PG_FUNCTION_ARGS); extern Datum regproctooid(PG_FUNCTION_ARGS);
/* define macro to replace mixed-case function call - tgl 97/04/27 */ /* define macro to replace mixed-case function call - tgl 97/04/27 */
@ -601,7 +600,8 @@ extern Datum getdatabaseencoding(PG_FUNCTION_ARGS);
extern Datum PG_encoding_to_char(PG_FUNCTION_ARGS); extern Datum PG_encoding_to_char(PG_FUNCTION_ARGS);
extern Datum PG_char_to_encoding(PG_FUNCTION_ARGS); extern Datum PG_char_to_encoding(PG_FUNCTION_ARGS);
/* formatting for internal types */ /* format_type.c */
extern Datum format_type(PG_FUNCTION_ARGS); extern Datum format_type(PG_FUNCTION_ARGS);
extern Datum oidvectortypes(PG_FUNCTION_ARGS);
#endif /* BUILTINS_H */ #endif /* BUILTINS_H */