From 0b60432a84d63a7fccaae0fe123a0aa2ae67493b Mon Sep 17 00:00:00 2001 From: Erik Wienhold Date: Sun, 18 Feb 2024 17:33:35 +0100 Subject: [PATCH] Add to_regtypmod() for benchmarking against parse_type() --- src/backend/utils/adt/regproc.c | 18 ++++++++++ src/include/catalog/pg_proc.dat | 3 ++ src/test/regress/expected/regproc.out | 51 +++++++++++++++++++++++++++ src/test/regress/sql/regproc.sql | 26 ++++++++++++++ 4 files changed, 98 insertions(+) diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c index 4fee27a139..6285dc7192 100644 --- a/src/backend/utils/adt/regproc.c +++ b/src/backend/utils/adt/regproc.c @@ -2067,3 +2067,21 @@ parse_type(PG_FUNCTION_ARGS) return HeapTupleGetDatum(rettuple); #undef PARSE_TYPE_STRING_COLS } + +Datum +to_regtypmod(PG_FUNCTION_ARGS) +{ + const char *type; /* the type string we want to resolve */ + Oid typid; /* the resolved type oid */ + int32 typmod; /* the resolved type modifier */ + + type = text_to_cstring(PG_GETARG_TEXT_PP(0)); + + /* + * Parse type-name argument to obtain type OID and encoded typmod. We don't + * need to handle parseTypeString failure, just let the error be raised. + */ + (void) parseTypeString(type, &typid, &typmod, NULL); + + PG_RETURN_INT32(typmod); +} diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 6cad101bca..befeaeec37 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -2190,6 +2190,9 @@ proargtypes => 'text', proallargtypes => '{text,oid,int4}', proargmodes => '{i,o,o}', proargnames => '{typname,typid,typmod}', prosrc => 'parse_type' }, +{ oid => '8402', descr => 'covert type name to typmod', + proname => 'to_regtypmod', provolatile => 's', prorettype => 'int4', + proargtypes => 'text', prosrc => 'to_regtypmod' }, { oid => '1084', descr => 'I/O', proname => 'date_in', provolatile => 's', prorettype => 'date', proargtypes => 'cstring', prosrc => 'date_in' }, diff --git a/src/test/regress/expected/regproc.out b/src/test/regress/expected/regproc.out index 033f6a81a5..c548b320c3 100644 --- a/src/test/regress/expected/regproc.out +++ b/src/test/regress/expected/regproc.out @@ -595,3 +595,54 @@ SELECT format_type(typid, typmod) FROM p; character varying(128) (7 rows) +-- Test to_regtypmod +SELECT * FROM to_regtypmod('text'); + to_regtypmod +-------------- + -1 +(1 row) + +SELECT * FROM to_regtypmod(NULL); + to_regtypmod +-------------- + +(1 row) + +-- Test to_regtypmod errors +SELECT to_regtypmod('nonesuch'); -- error expected +ERROR: type "nonesuch" does not exist +SELECT to_regtypmod('interval nonesuch'); -- grammar error expected +ERROR: syntax error at or near "nonesuch" +LINE 1: SELECT to_regtypmod('interval nonesuch'); + ^ +CONTEXT: invalid type name "interval nonesuch" +SELECT to_regtypmod('year(4)'); -- grammar error expected +ERROR: type "year" does not exist +-- Test to_regtypmod with various aliases and grammar-based types +WITH s(s) AS ( + SELECT * FROM unnest(ARRAY[ + 'timestamp(4)', + 'interval(0)', + 'interval second(0)', + 'timestamptz', + 'timestamptz(6)', + 'varchar', + 'varchar(128)' + ]) +), +p(typid, typmod) AS ( + SELECT to_regtype(s), to_regtypmod(s) + FROM s +) +SELECT format_type(typid, typmod) FROM p; + format_type +-------------------------------- + timestamp(4) without time zone + interval(0) + interval second(0) + timestamp with time zone + timestamp(6) with time zone + character varying + character varying(128) +(7 rows) + diff --git a/src/test/regress/sql/regproc.sql b/src/test/regress/sql/regproc.sql index 489463aa9e..ac19737012 100644 --- a/src/test/regress/sql/regproc.sql +++ b/src/test/regress/sql/regproc.sql @@ -173,3 +173,29 @@ p(typid, typmod) AS ( ) SELECT format_type(typid, typmod) FROM p; +-- Test to_regtypmod +SELECT * FROM to_regtypmod('text'); +SELECT * FROM to_regtypmod(NULL); + +-- Test to_regtypmod errors +SELECT to_regtypmod('nonesuch'); -- error expected +SELECT to_regtypmod('interval nonesuch'); -- grammar error expected +SELECT to_regtypmod('year(4)'); -- grammar error expected + +-- Test to_regtypmod with various aliases and grammar-based types +WITH s(s) AS ( + SELECT * FROM unnest(ARRAY[ + 'timestamp(4)', + 'interval(0)', + 'interval second(0)', + 'timestamptz', + 'timestamptz(6)', + 'varchar', + 'varchar(128)' + ]) +), +p(typid, typmod) AS ( + SELECT to_regtype(s), to_regtypmod(s) + FROM s +) +SELECT format_type(typid, typmod) FROM p; -- 2.43.2