Re: Proposal: variant of regclass

Поиск
Список
Период
Сортировка
От Tatsuo Ishii
Тема Re: Proposal: variant of regclass
Дата
Msg-id 20140416.162701.1405927981065737923.t-ishii@sraoss.co.jp
обсуждение исходный текст
Ответ на Re: Fwd: Proposal: variant of regclass  (Robert Haas <robertmhaas@gmail.com>)
Ответы Re: Proposal: variant of regclass  (Robert Haas <robertmhaas@gmail.com>)
Список pgsql-hackers
>> Well, I noticed that, too, but I didn't think it was my job to tell
>> the patch author what functions he should have wanted.  A follow-on
>> patch to add to_regprocedure and to_regoperator wouldn't be much work,
>> if you want that.
> 
> And here is a patch for that.

Looks good to me except duplicate oids. Included is a patch to fix that.

Best regards,
--
Tatsuo Ishii
SRA OSS, Inc. Japan
English: http://www.sraoss.co.jp/index_en.php
Japanese: http://www.sraoss.co.jp
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 0809a6d..db8691a 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -15294,10 +15294,18 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);   </indexterm>   <indexterm>
+    <primary>to_regprocedure</primary>
+   </indexterm>
+
+   <indexterm>    <primary>to_regoper</primary>   </indexterm>   <indexterm>
+    <primary>to_regoperator</primary>
+   </indexterm>
+
+   <indexterm>    <primary>to_regtype</primary>   </indexterm>
@@ -15482,11 +15490,21 @@ SELECT pg_type_is_visible('myschema.widget'::regtype);       <entry>get the oid of the named
function</entry>     </row>      <row>
 
+       <entry><literal><function>to_regprocedure(<parameter>func_name</parameter>)</function></literal></entry>
+       <entry><type>regprocedure</type></entry>
+       <entry>get the oid of the named function</entry>
+      </row>
+      <row>
<entry><literal><function>to_regoper(<parameter>operator_name</parameter>)</function></literal></entry>
<entry><type>regoper</type></entry>      <entry>get the oid of the named operator</entry>      </row>      <row>
 
+       <entry><literal><function>to_regoperator(<parameter>operator_name</parameter>)</function></literal></entry>
+       <entry><type>regoperator</type></entry>
+       <entry>get the oid of the named operator</entry>
+      </row>
+      <row>       <entry><literal><function>to_regtype(<parameter>type_name</parameter>)</function></literal></entry>
    <entry><type>regtype</type></entry>       <entry>get the oid of the named type</entry>
 
@@ -15658,10 +15676,12 @@ SELECT collation for ('foo' COLLATE "de_DE");  <para>   The <function>to_regclass</function>,
<function>to_regproc</function>,
-   <function>to_regoper</function> and <function>to_regtype</function>
-   translate relation, function, operator, and type names to objects of
-   type <type>regclass</>, <type>regproc</>, <type>regoper</> and
-   <type>regtype</>, respectively.  These functions differ from a cast from
+   <function>to_regprocedure</function>, <function>to_regoper</function>,
+   <function>to_regoperator</function>, and <function>to_regtype</function>
+   functions translate relation, function, operator, and type names to objects
+   of type <type>regclass</>, <type>regproc</>, <type>regprocedure</type>,
+   <type>regoper</>, <type>regoperator</type>, and <type>regtype</>,
+   respectively.  These functions differ from a cast from   text in that they don't accept a numeric OID, and that
theyreturn null   rather than throwing an error if the name is not found (or, for   <function>to_regproc</function> and
<function>to_regoper</function>,if
 
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index ed2bdbf..6210f45 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -323,6 +323,38 @@ regprocedurein(PG_FUNCTION_ARGS)}/*
+ * 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)" * * This exports the useful functionality of
regprocedureoutfor use
 
@@ -722,6 +754,45 @@ regoperatorin(PG_FUNCTION_ARGS)}/*
+ * 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)" * * This exports the useful functionality of
regoperatoroutfor use
 
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 643408d..c77c036 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
0DESCR("I/O");DATA(insertOID = 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
tf 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
2DESCR("I/O");DATA(insertOID = 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
ff 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 11ff4fd..33b6dca 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);externDatum 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);externDatum 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);externDatum to_regoper(PG_FUNCTION_ARGS);
 
+extern Datum to_regoperator(PG_FUNCTION_ARGS);extern Datum regoperatorin(PG_FUNCTION_ARGS);extern Datum
regoperatorout(PG_FUNCTION_ARGS);externDatum regoperatorrecv(PG_FUNCTION_ARGS);
 
diff --git a/src/test/regress/expected/regproc.out b/src/test/regress/expected/regproc.out
index 56ab245..3342129 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 existLINE 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 existLINE 1: SELECT
regclass('pg_classes');
@@ -123,10 +173,18 @@ SELECT regoper('ng_catalog.||/');ERROR:  schema "ng_catalog" does not existLINE 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 existLINE 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 existLINE 1:
SELECTregclass('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 1334cfb..cc90838 100644
--- a/src/test/regress/sql/regproc.sql
+++ b/src/test/regress/sql/regproc.sql
@@ -7,24 +7,31 @@-- without schemanameSELECT 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
schemanameSELECTregoper('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');SELECTto_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 schemanameSELECT regoper('||//');
+SELECT regoperator('++(int4,int4)');SELECT regproc('know');
+SELECT regprocedure('absinthe(numeric)');SELECT regclass('pg_classes');SELECT regtype('int3');-- with schemanameSELECT
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 schemanameSELECT 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
schemanameSELECTto_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');

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Peter Geoghegan
Дата:
Сообщение: Re: Clock sweep not caching enough B-Tree leaf pages?
Следующее
От: Andres Freund
Дата:
Сообщение: Re: Clock sweep not caching enough B-Tree leaf pages?