diff options
author | Peter Eisentraut <peter_e@gmx.net> | 2000-07-07 19:24:43 +0000 |
---|---|---|
committer | Peter Eisentraut <peter_e@gmx.net> | 2000-07-07 19:24:43 +0000 |
commit | de85dd1d51ab7325984ef36302831ca21e3ae53e (patch) | |
tree | 384a5322e1b8dac3ce464ba8bf8206144b6a26e9 /src/backend | |
parent | 364985542ba58f2f43b5711941da26518f53c667 (diff) | |
download | postgresql-de85dd1d51ab7325984ef36302831ca21e3ae53e.tar.gz postgresql-de85dd1d51ab7325984ef36302831ca21e3ae53e.zip |
- format_type function, in use by psql
- added bigint as synonym of int8
- set typelem of varlen non-array types to 0
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/parser/gram.y | 4 | ||||
-rw-r--r-- | src/backend/utils/adt/Makefile | 4 | ||||
-rw-r--r-- | src/backend/utils/adt/format_type.c | 181 |
3 files changed, 186 insertions, 3 deletions
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 98a00acb8fc..15e5b2c3346 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.175 2000/07/03 23:09:41 wieck Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.176 2000/07/07 19:24:35 petere Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -5779,6 +5779,8 @@ xlateSqlType(char *name) return "int4"; else if (strcmp(name, "smallint") == 0) return "int2"; + else if (strcmp(name, "bigint") == 0) + return "int8"; else if ((strcmp(name, "real") == 0) || (strcmp(name, "float") == 0)) return "float8"; diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile index 298e15f0000..3bdce0998b4 100644 --- a/src/backend/utils/adt/Makefile +++ b/src/backend/utils/adt/Makefile @@ -4,7 +4,7 @@ # Makefile for utils/adt # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.37 2000/05/29 05:45:20 tgl Exp $ +# $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.38 2000/07/07 19:24:37 petere Exp $ # #------------------------------------------------------------------------- @@ -22,7 +22,7 @@ endif endif OBJS = acl.o arrayfuncs.o arrayutils.o bool.o cash.o char.o chunk.o \ - date.o datetime.o datum.o filename.o float.o \ + date.o datetime.o datum.o filename.o float.o format_type.o \ geo_ops.o geo_selfuncs.o int.o int8.o like.o lztext.o \ misc.o nabstime.o name.o not_in.o numeric.o numutils.o \ oid.o oracle_compat.o \ diff --git a/src/backend/utils/adt/format_type.c b/src/backend/utils/adt/format_type.c new file mode 100644 index 00000000000..af8eaa95441 --- /dev/null +++ b/src/backend/utils/adt/format_type.c @@ -0,0 +1,181 @@ +/* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.1 2000/07/07 19:24:37 petere Exp $ */ + +#include "postgres.h" + +#include <ctype.h> +#include <stdarg.h> + +#include "fmgr.h" +#include "catalog/pg_type.h" +#include "utils/builtins.h" +#include "utils/syscache.h" + +#define streq(a, b) (strcmp((a), (b))==0) +#define MAX_INT32_LEN 11 + + +static char * +psnprintf(size_t len, const char * fmt, ...) +{ + va_list ap; + char * buf; + + buf = palloc(len); + + va_start(ap, fmt); + vsnprintf(buf, len, fmt, ap); + va_end(ap); + + return buf; +} + + +#define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str)) + + +/* + * SQL function: format_type(type_oid, typemod) + * + * `type_oid' is from pg_type.oid, `typemod' is from + * pg_attribute.atttypmod. This function will get the type name and + * format it and the modifier to canonical SQL format, if the type is + * a standard type. Otherwise you just get pg_type.typname back, + * double quoted if it contains funny characters. + * + * If typemod is null (in the SQL sense) then you won't get any + * "..(x)" type qualifiers. The result is not technically correct, + * because the various types interpret missing type modifiers + * differently, but it can be used as a convenient way to format + * system catalogs, e.g., pg_aggregate, in psql. + */ +Datum +format_type(PG_FUNCTION_ARGS) +{ + Oid type_oid; + bool with_typemod; + int32 typemod = 0; + char * buf; + char * name; + Oid array_base_type; + int16 typlen; + bool is_array; + HeapTuple tuple; + + if (PG_ARGISNULL(0)) + PG_RETURN_NULL(); + + type_oid = DatumGetObjectId(PG_GETARG_DATUM(0)); + + with_typemod = !PG_ARGISNULL(1); + if (with_typemod) + typemod = PG_GETARG_INT32(1); + + tuple = SearchSysCacheTuple(TYPEOID, ObjectIdGetDatum(type_oid), + 0, 0, 0); + + if (!HeapTupleIsValid(tuple)) + PG_RETURN_TEXT_P(_textin("???")); + + array_base_type = ((Form_pg_type) GETSTRUCT(tuple))->typelem; + typlen = ((Form_pg_type) GETSTRUCT(tuple))->typlen; + if (array_base_type != 0 && typlen < 0) + { + tuple = SearchSysCacheTuple(TYPEOID, + ObjectIdGetDatum(array_base_type), + 0, 0, 0); + if (!HeapTupleIsValid(tuple)) + PG_RETURN_TEXT_P(_textin("???[]")); + is_array = true; + } + else + is_array = false; + + + name = NameStr(((Form_pg_type) GETSTRUCT(tuple))->typname); + + if (streq(name, "bit")) + { + if (with_typemod) + buf = psnprintf(5 + MAX_INT32_LEN + 1, "bit(%d)", (int) typemod - 4); + else + buf = pstrdup("bit"); + } + + else if (streq(name, "bool")) + buf = pstrdup("boolean"); + + else if (streq(name, "bpchar")) + { + if (with_typemod) + buf = psnprintf(11 + MAX_INT32_LEN + 1, "character(%d)", (int) typemod - 4); + else + buf = pstrdup("character"); + } + + /* This char type is the single-byte version. You have to + * double-quote it to get at it in the parser. */ + else if (streq(name, "char")) + buf = pstrdup("\"char\""); +#if 0 + /* The parser has these backwards, so leave as is for now. */ + else if (streq(name, "float4")) + buf = pstrdup("real"); + + else if (streq(name, "float8")) + buf = pstrdup("double precision"); +#endif + else if (streq(name, "int2")) + buf = pstrdup("smallint"); + + else if (streq(name, "int4")) + buf = pstrdup("integer"); + + else if (streq(name, "int8")) + buf = pstrdup("bigint"); + + else if (streq(name, "numeric")) + { + if (with_typemod) + buf = psnprintf(10 + 2 * MAX_INT32_LEN + 1, "numeric(%d,%d)", + ((typemod - VARHDRSZ) >> 16) & 0xffff, + (typemod - VARHDRSZ) & 0xffff); + else + buf = pstrdup("numeric"); + } + + else if (streq(name, "timetz")) + buf = pstrdup("time with time zone"); + + else if (streq(name, "varbit")) + { + if (with_typemod) + buf = psnprintf(13 + MAX_INT32_LEN + 1, "bit varying(%d)", (int) typemod - 4); + else + buf = pstrdup("bit varying"); + } + + else if (streq(name, "varchar")) + { + if (with_typemod) + buf = psnprintf(19 + MAX_INT32_LEN + 1, "character varying(%d)", (int) typemod - 4); + else + buf = pstrdup("character varying"); + } + + else + { + if (strspn(name, "abcdefghijklmnopqrstuvwxyz0123456789_") != strlen(name) + || isdigit((int) name[0])) + buf = psnprintf(strlen(name) + 3, "\"%s\"", name); + else + buf = name; + } + + if (is_array) + { + char * buf2 = psnprintf(strlen(buf) + 3, "%s[]", buf); + buf = buf2; + } + + PG_RETURN_TEXT_P(_textin(buf)); +} |