diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 1759c8876c..148f0bc237 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -15293,10 +15293,18 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
to_regproc
+
+ to_regprocedure
+
+
to_regoper
+
+ to_regoperator
+
+
to_regtype
@@ -15481,11 +15489,21 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);
regproc
get the oid of the named function
+
+ to_regprocedure(func_name)
+ regprocedure
+ get the oid of the named function
+
to_regoper(operator_name)
regoper
get the oid of the named operator
+
+ to_regoperator(operator_name)
+ regoperator
+ get the oid of the named operator
+
to_regtype(type_name)
regtype
@@ -15658,10 +15676,12 @@ SELECT collation for ('foo' COLLATE "de_DE");
The to_regclass, to_regproc,
- to_regoper and to_regtype
- translate relation, function, operator, and type names to objects of
- type regclass>, regproc>, regoper> and
- regtype>, respectively. These functions differ from a cast from
+ to_regprocedure, to_regoper,
+ to_regoperator, and to_regtype
+ functions translate relation, function, operator, and type names to objects
+ of type regclass>, regproc>, regprocedure,
+ regoper>, regoperator, and regtype>,
+ respectively. These functions differ from a cast from
text in that they don't accept a numeric OID, and that they return null
rather than throwing an error if the name is not found (or, for
to_regproc and to_regoper, if
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index ed2bdbfb09..6210f45a19 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -322,6 +322,38 @@ regprocedurein(PG_FUNCTION_ARGS)
PG_RETURN_OID(result);
}
+/*
+ * to_regprocedure - converts "proname(args)" to proc OID
+ *
+ * If the name is not found, we return NULL.
+ */
+Datum
+to_regprocedure(PG_FUNCTION_ARGS)
+{
+ char *pro_name = PG_GETARG_CSTRING(0);
+ List *names;
+ int nargs;
+ Oid argtypes[FUNC_MAX_ARGS];
+ FuncCandidateList clist;
+
+ /*
+ * Parse the name and arguments, look up potential matches in the current
+ * namespace search list, and scan to see which one exactly matches the
+ * given argument types. (There will not be more than one match.)
+ */
+ parseNameAndArgTypes(pro_name, false, &names, &nargs, argtypes);
+
+ clist = FuncnameGetCandidates(names, nargs, NIL, false, false, true);
+
+ for (; clist; clist = clist->next)
+ {
+ if (memcmp(clist->args, argtypes, nargs * sizeof(Oid)) == 0)
+ PG_RETURN_OID(clist->oid);
+ }
+
+ PG_RETURN_NULL();
+}
+
/*
* format_procedure - converts proc OID to "pro_name(args)"
*
@@ -721,6 +753,45 @@ regoperatorin(PG_FUNCTION_ARGS)
PG_RETURN_OID(result);
}
+/*
+ * to_regoperator - converts "oprname(args)" to operator OID
+ *
+ * If the name is not found, we return NULL.
+ */
+Datum
+to_regoperator(PG_FUNCTION_ARGS)
+{
+ char *opr_name_or_oid = PG_GETARG_CSTRING(0);
+ Oid result;
+ List *names;
+ int nargs;
+ Oid argtypes[FUNC_MAX_ARGS];
+
+ /*
+ * Parse the name and arguments, look up potential matches in the current
+ * namespace search list, and scan to see which one exactly matches the
+ * given argument types. (There will not be more than one match.)
+ */
+ parseNameAndArgTypes(opr_name_or_oid, true, &names, &nargs, argtypes);
+ if (nargs == 1)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_PARAMETER),
+ errmsg("missing argument"),
+ errhint("Use NONE to denote the missing argument of a unary operator.")));
+ if (nargs != 2)
+ ereport(ERROR,
+ (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
+ errmsg("too many arguments"),
+ errhint("Provide two argument types for operator.")));
+
+ result = OpernameGetOprid(names, argtypes[0], argtypes[1]);
+
+ if (!OidIsValid(result))
+ PG_RETURN_NULL();
+
+ PG_RETURN_OID(result);
+}
+
/*
* format_operator - converts operator OID to "opr_name(args)"
*
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 74c6bff86d..c96fb61ec5 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 201404123
+#define CATALOG_VERSION_NO 201404161
#endif
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 643408d250..c77c03615f 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -175,6 +175,8 @@ DATA(insert OID = 45 ( regprocout PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0
DESCR("I/O");
DATA(insert OID = 3494 ( to_regproc PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 24 "2275" _null_ _null_ _null_ _null_ to_regproc _null_ _null_ _null_ ));
DESCR("convert proname to regproc");
+DATA(insert OID = 3479 ( to_regprocedure PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2202 "2275" _null_ _null_ _null_ _null_ to_regprocedure _null_ _null_ _null_ ));
+DESCR("convert proname to regprocedure");
DATA(insert OID = 46 ( textin PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 25 "2275" _null_ _null_ _null_ _null_ textin _null_ _null_ _null_ ));
DESCR("I/O");
DATA(insert OID = 47 ( textout PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 2275 "25" _null_ _null_ _null_ _null_ textout _null_ _null_ _null_ ));
@@ -3351,6 +3353,8 @@ DATA(insert OID = 2215 ( regoperout PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2
DESCR("I/O");
DATA(insert OID = 3492 ( to_regoper PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2203 "2275" _null_ _null_ _null_ _null_ to_regoper _null_ _null_ _null_ ));
DESCR("convert operator name to regoper");
+DATA(insert OID = 3476 ( to_regoperator PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2204 "2275" _null_ _null_ _null_ _null_ to_regoperator _null_ _null_ _null_ ));
+DESCR("convert operator name to regoperator");
DATA(insert OID = 2216 ( regoperatorin PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2204 "2275" _null_ _null_ _null_ _null_ regoperatorin _null_ _null_ _null_ ));
DESCR("I/O");
DATA(insert OID = 2217 ( regoperatorout PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2275 "2204" _null_ _null_ _null_ _null_ regoperatorout _null_ _null_ _null_ ));
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 11ff4fdef0..33b6dca191 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -602,6 +602,7 @@ extern char *regexp_fixed_prefix(text *text_re, bool case_insensitive,
extern Datum regprocin(PG_FUNCTION_ARGS);
extern Datum regprocout(PG_FUNCTION_ARGS);
extern Datum to_regproc(PG_FUNCTION_ARGS);
+extern Datum to_regprocedure(PG_FUNCTION_ARGS);
extern Datum regprocrecv(PG_FUNCTION_ARGS);
extern Datum regprocsend(PG_FUNCTION_ARGS);
extern Datum regprocedurein(PG_FUNCTION_ARGS);
@@ -613,6 +614,7 @@ extern Datum regoperout(PG_FUNCTION_ARGS);
extern Datum regoperrecv(PG_FUNCTION_ARGS);
extern Datum regopersend(PG_FUNCTION_ARGS);
extern Datum to_regoper(PG_FUNCTION_ARGS);
+extern Datum to_regoperator(PG_FUNCTION_ARGS);
extern Datum regoperatorin(PG_FUNCTION_ARGS);
extern Datum regoperatorout(PG_FUNCTION_ARGS);
extern Datum regoperatorrecv(PG_FUNCTION_ARGS);
diff --git a/src/test/regress/expected/regproc.out b/src/test/regress/expected/regproc.out
index 56ab245223..33421292fd 100644
--- a/src/test/regress/expected/regproc.out
+++ b/src/test/regress/expected/regproc.out
@@ -9,12 +9,24 @@ SELECT regoper('||/');
||/
(1 row)
+SELECT regoperator('+(int4,int4)');
+ regoperator
+--------------------
+ +(integer,integer)
+(1 row)
+
SELECT regproc('now');
regproc
---------
now
(1 row)
+SELECT regprocedure('abs(numeric)');
+ regprocedure
+--------------
+ abs(numeric)
+(1 row)
+
SELECT regclass('pg_class');
regclass
----------
@@ -33,12 +45,24 @@ SELECT to_regoper('||/');
||/
(1 row)
+SELECT to_regoperator('+(int4,int4)');
+ to_regoperator
+--------------------
+ +(integer,integer)
+(1 row)
+
SELECT to_regproc('now');
to_regproc
------------
now
(1 row)
+SELECT to_regprocedure('abs(numeric)');
+ to_regprocedure
+-----------------
+ abs(numeric)
+(1 row)
+
SELECT to_regclass('pg_class');
to_regclass
-------------
@@ -58,12 +82,24 @@ SELECT regoper('pg_catalog.||/');
||/
(1 row)
+SELECT regoperator('pg_catalog.+(int4,int4)');
+ regoperator
+--------------------
+ +(integer,integer)
+(1 row)
+
SELECT regproc('pg_catalog.now');
regproc
---------
now
(1 row)
+SELECT regprocedure('pg_catalog.abs(numeric)');
+ regprocedure
+--------------
+ abs(numeric)
+(1 row)
+
SELECT regclass('pg_catalog.pg_class');
regclass
----------
@@ -88,6 +124,12 @@ SELECT to_regproc('pg_catalog.now');
now
(1 row)
+SELECT to_regprocedure('pg_catalog.abs(numeric)');
+ to_regprocedure
+-----------------
+ abs(numeric)
+(1 row)
+
SELECT to_regclass('pg_catalog.pg_class');
to_regclass
-------------
@@ -106,10 +148,18 @@ SELECT regoper('||//');
ERROR: operator does not exist: ||//
LINE 3: SELECT regoper('||//');
^
+SELECT regoperator('++(int4,int4)');
+ERROR: operator does not exist: ++(int4,int4)
+LINE 1: SELECT regoperator('++(int4,int4)');
+ ^
SELECT regproc('know');
ERROR: function "know" does not exist
LINE 1: SELECT regproc('know');
^
+SELECT regprocedure('absinthe(numeric)');
+ERROR: function "absinthe(numeric)" does not exist
+LINE 1: SELECT regprocedure('absinthe(numeric)');
+ ^
SELECT regclass('pg_classes');
ERROR: relation "pg_classes" does not exist
LINE 1: SELECT regclass('pg_classes');
@@ -123,10 +173,18 @@ SELECT regoper('ng_catalog.||/');
ERROR: schema "ng_catalog" does not exist
LINE 1: SELECT regoper('ng_catalog.||/');
^
+SELECT regoperator('ng_catalog.+(int4,int4)');
+ERROR: operator does not exist: ng_catalog.+(int4,int4)
+LINE 1: SELECT regoperator('ng_catalog.+(int4,int4)');
+ ^
SELECT regproc('ng_catalog.now');
ERROR: schema "ng_catalog" does not exist
LINE 1: SELECT regproc('ng_catalog.now');
^
+SELECT regprocedure('ng_catalog.abs(numeric)');
+ERROR: schema "ng_catalog" does not exist
+LINE 1: SELECT regprocedure('ng_catalog.abs(numeric)');
+ ^
SELECT regclass('ng_catalog.pg_class');
ERROR: schema "ng_catalog" does not exist
LINE 1: SELECT regclass('ng_catalog.pg_class');
@@ -143,12 +201,24 @@ SELECT to_regoper('||//');
(1 row)
+SELECT to_regoperator('++(int4,int4)');
+ to_regoperator
+----------------
+
+(1 row)
+
SELECT to_regproc('know');
to_regproc
------------
(1 row)
+SELECT to_regprocedure('absinthe(numeric)');
+ to_regprocedure
+-----------------
+
+(1 row)
+
SELECT to_regclass('pg_classes');
to_regclass
-------------
@@ -168,12 +238,24 @@ SELECT to_regoper('ng_catalog.||/');
(1 row)
+SELECT to_regoperator('ng_catalog.+(int4,int4)');
+ to_regoperator
+----------------
+
+(1 row)
+
SELECT to_regproc('ng_catalog.now');
to_regproc
------------
(1 row)
+SELECT to_regprocedure('ng_catalog.abs(numeric)');
+ to_regprocedure
+-----------------
+
+(1 row)
+
SELECT to_regclass('ng_catalog.pg_class');
to_regclass
-------------
diff --git a/src/test/regress/sql/regproc.sql b/src/test/regress/sql/regproc.sql
index 1334cfb7aa..cc90838bea 100644
--- a/src/test/regress/sql/regproc.sql
+++ b/src/test/regress/sql/regproc.sql
@@ -7,24 +7,31 @@
-- without schemaname
SELECT regoper('||/');
+SELECT regoperator('+(int4,int4)');
SELECT regproc('now');
+SELECT regprocedure('abs(numeric)');
SELECT regclass('pg_class');
SELECT regtype('int4');
SELECT to_regoper('||/');
+SELECT to_regoperator('+(int4,int4)');
SELECT to_regproc('now');
+SELECT to_regprocedure('abs(numeric)');
SELECT to_regclass('pg_class');
SELECT to_regtype('int4');
-- with schemaname
SELECT regoper('pg_catalog.||/');
+SELECT regoperator('pg_catalog.+(int4,int4)');
SELECT regproc('pg_catalog.now');
+SELECT regprocedure('pg_catalog.abs(numeric)');
SELECT regclass('pg_catalog.pg_class');
SELECT regtype('pg_catalog.int4');
SELECT to_regoper('pg_catalog.||/');
SELECT to_regproc('pg_catalog.now');
+SELECT to_regprocedure('pg_catalog.abs(numeric)');
SELECT to_regclass('pg_catalog.pg_class');
SELECT to_regtype('pg_catalog.int4');
@@ -33,14 +40,18 @@ SELECT to_regtype('pg_catalog.int4');
-- without schemaname
SELECT regoper('||//');
+SELECT regoperator('++(int4,int4)');
SELECT regproc('know');
+SELECT regprocedure('absinthe(numeric)');
SELECT regclass('pg_classes');
SELECT regtype('int3');
-- with schemaname
SELECT regoper('ng_catalog.||/');
+SELECT regoperator('ng_catalog.+(int4,int4)');
SELECT regproc('ng_catalog.now');
+SELECT regprocedure('ng_catalog.abs(numeric)');
SELECT regclass('ng_catalog.pg_class');
SELECT regtype('ng_catalog.int4');
@@ -49,13 +60,17 @@ SELECT regtype('ng_catalog.int4');
-- without schemaname
SELECT to_regoper('||//');
+SELECT to_regoperator('++(int4,int4)');
SELECT to_regproc('know');
+SELECT to_regprocedure('absinthe(numeric)');
SELECT to_regclass('pg_classes');
SELECT to_regtype('int3');
-- with schemaname
SELECT to_regoper('ng_catalog.||/');
+SELECT to_regoperator('ng_catalog.+(int4,int4)');
SELECT to_regproc('ng_catalog.now');
+SELECT to_regprocedure('ng_catalog.abs(numeric)');
SELECT to_regclass('ng_catalog.pg_class');
SELECT to_regtype('ng_catalog.int4');