Hi,
the following patch allows to retrieve the typemod. Without this patch,
it does not seem to be possible to generate the first column.
SELECT format_type(to_regtype(t), pg_to_typemod(t)),
format_type(to_regtype(t), NULL)
FROM (VALUES
('INTERVAL SECOND (5)'),
('Varchar(17)'),
('timestamptz (2)')) AS x(t);
format_type | format_type
-----------------------------+--------------------------
interval second(5) | interval
character varying(17) | character varying
timestamp(2) with time zone | timestamp with time zone
I did not find any advice on how to choose a new OID for pg_proc.
Best,
Sophie
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 698daf69ea..b0211fcad2 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -17126,6 +17126,11 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
<entry>get the path in the file system that this tablespace is located in</entry>
</row>
<row>
+ <entry><literal><function>pg_to_typemod(<parameter>type_name</parameter>)</function></literal></entry>
+ <entry><type>integer</type></entry>
+ <entry>get the typemod of the named type</entry>
+ </row>
+ <row>
<entry><literal><function>pg_typeof(<parameter>any</parameter>)</function></literal></entry>
<entry><type>regtype</type></entry>
<entry>get the data type of any value</entry>
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 1980ff5ac7..ac7407325a 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -30,6 +30,7 @@
#include "funcapi.h"
#include "miscadmin.h"
#include "pgstat.h"
+#include "parser/parse_type.h"
#include "parser/scansup.h"
#include "postmaster/syslogger.h"
#include "rewrite/rewriteHandler.h"
@@ -1002,3 +1003,24 @@ pg_get_replica_identity_index(PG_FUNCTION_ARGS)
else
PG_RETURN_NULL();
}
+
+/*
+ * pg_to_typemod - extracts typemod from "typename"
+ *
+ * This functions suplements to_regtype to obtain the required arguments for
+ * format_type(type_oid, typemod).
+ */
+Datum
+pg_to_typemod(PG_FUNCTION_ARGS)
+{
+ char *typ_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
+ Oid oid;
+ int32 result;
+
+ parseTypeString(typ_name, &oid, &result, true);
+
+ if (OidIsValid(oid))
+ PG_RETURN_INT32(result);
+ else
+ PG_RETURN_NULL();
+}
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index c969375981..c40603770b 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -1202,6 +1202,8 @@ DATA(insert OID = 972 ( hashbpcharextended PGNSP PGUID 12 1 0 0 0 f f f f t f
DESCR("hash");
DATA(insert OID = 1081 ( format_type PGNSP PGUID 12 1 0 0 0 f f f f f f s s 2 0 25 "26 23" _null_ _null_ _null_ _null_ _null_ format_type _null_ _null_ _null_ ));
DESCR("format a type oid and atttypmod to canonical SQL");
+DATA(insert OID = 4569 ( pg_to_typemod PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 23 "25" _null_ _null_ _null_ _null_ _null_ pg_to_typemod _null_ _null_ _null_ ));
+DESCR("get the typemod of the named type");
DATA(insert OID = 1084 ( date_in PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 1082 "2275" _null_ _null_ _null_ _null_ _null_ date_in _null_ _null_ _null_ ));
DESCR("I/O");
DATA(insert OID = 1085 ( date_out PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 2275 "1082" _null_ _null_ _null_ _null_ _null_ date_out _null_ _null_ _null_ ));
diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out
index 130a0e4be3..0584b22155 100644
--- a/src/test/regress/expected/misc_functions.out
+++ b/src/test/regress/expected/misc_functions.out
@@ -133,3 +133,26 @@ ERROR: function num_nulls() does not exist
LINE 1: SELECT num_nulls();
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
+---
+--- pg_get_typemod()
+---
+SELECT format_type(to_regtype(t), pg_to_typemod(t)) FROM (VALUES ('INTERVAL SECOND (5)'), ('Varchar(17)'), ('timestamptz (2)')) x(t);
+ format_type
+-----------------------------
+ interval second(5)
+ character varying(17)
+ timestamp(2) with time zone
+(3 rows)
+
+SELECT pg_to_typemod('int');
+ pg_to_typemod
+---------------
+ -1
+(1 row)
+
+SELECT pg_to_typemod('"Unknown Type"') IS NULL;
+ ?column?
+----------
+ t
+(1 row)
+
diff --git a/src/test/regress/sql/misc_functions.sql b/src/test/regress/sql/misc_functions.sql
index 1a20c1f765..24d89df1e5 100644
--- a/src/test/regress/sql/misc_functions.sql
+++ b/src/test/regress/sql/misc_functions.sql
@@ -29,3 +29,11 @@ SELECT num_nulls(VARIADIC '{}'::int[]);
-- should fail, one or more arguments is required
SELECT num_nonnulls();
SELECT num_nulls();
+
+---
+--- pg_get_typemod()
+---
+
+SELECT format_type(to_regtype(t), pg_to_typemod(t)) FROM (VALUES ('INTERVAL SECOND (5)'), ('Varchar(17)'), ('timestamptz (2)')) x(t);
+SELECT pg_to_typemod('int');
+SELECT pg_to_typemod('"Unknown Type"') IS NULL;