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?