Re: Proposal: variant of regclass

Поиск
Список
Период
Сортировка
От Tatsuo Ishii
Тема Re: Proposal: variant of regclass
Дата
Msg-id 20131218.181806.1842914817487467213.t-ishii@sraoss.co.jp
обсуждение исходный текст
Ответ на Re: Proposal: variant of regclass  (Robert Haas <robertmhaas@gmail.com>)
Ответы Re: Proposal: variant of regclass
Список pgsql-hackers
>> For the pgpool-II use case, I'm happy to follow you because pgpool-II
>> always does a grammatical check (using raw parser) on a query first
>> and such syntax problem will be pointed out, thus never reaches to
>> the state where calling toregclass.
>>
>> One concern is, other users expect toregclass to detect such syntax
>> problems. Anybody?
> 
> It seems fine to me if the new function ignores the specific error of
> "relation does not exist" while continuing to throw other errors.

Thanks. Here is the revised conceptual patch. I'm going to post a
concrete patch and register it to 2014-01 Commit Fest.

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/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index c24a2c1..0406c30 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -45,6 +45,7 @@ static char *format_operator_internal(Oid operator_oid, bool force_qualify);static char
*format_procedure_internal(Oidprocedure_oid, bool force_qualify);static void parseNameAndArgTypes(const char *string,
boolallowNone,                     List **names, int *nargs, Oid *argtypes);
 
+static Datum regclass_guts(char *class_name_or_oid, bool
raiseError);/*****************************************************************************
@@ -804,21 +805,50 @@ Datumregclassin(PG_FUNCTION_ARGS){    char       *class_name_or_oid = PG_GETARG_CSTRING(0);
+    Oid            result;
+
+    result = regclass_guts(class_name_or_oid, true);
+    PG_RETURN_OID(result);
+}
+
+/*
+ * toregclass        - converts "classname" to class OID
+ *
+ * Diffrence from rgclassin is, this does not throw an error if the classname
+ * does not exist.
+ * Note: this is not an I/O function.
+ */
+Datum
+toregclass(PG_FUNCTION_ARGS)
+{
+    char       *class_name_or_oid = PG_GETARG_CSTRING(0);
+    Oid            result;
+
+    result = regclass_guts(class_name_or_oid, false);
+    PG_RETURN_OID(result);
+}
+
+/*
+ * Guts of regclassin and toregclass.
+ * If raiseError is false, returns InvalidOid upon error.
+ */
+static Datum regclass_guts(char *class_name_or_oid, bool raiseError)
+{    Oid            result = InvalidOid;    List       *names;    /* '-' ? */    if (strcmp(class_name_or_oid, "-") ==
0)
-        PG_RETURN_OID(InvalidOid);
+        return result;    /* Numeric OID? */    if (class_name_or_oid[0] >= '0' &&        class_name_or_oid[0] <= '9'
&&       strspn(class_name_or_oid, "0123456789") == strlen(class_name_or_oid))    {
 
-        result = DatumGetObjectId(DirectFunctionCall1(oidin,
+         result = DatumGetObjectId(DirectFunctionCall1(oidin,
CStringGetDatum(class_name_or_oid)));
-        PG_RETURN_OID(result);
+        return result;    }    /* Else it's a name, possibly schema-qualified */
@@ -848,16 +878,19 @@ regclassin(PG_FUNCTION_ARGS)        if (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
     result = HeapTupleGetOid(tuple);        else
 
-            ereport(ERROR,
-                    (errcode(ERRCODE_UNDEFINED_TABLE),
-               errmsg("relation \"%s\" does not exist", class_name_or_oid)));
+            if (raiseError)
+                ereport(ERROR,
+                        (errcode(ERRCODE_UNDEFINED_TABLE),
+                         errmsg("relation \"%s\" does not exist", class_name_or_oid)));
+            else
+                return InvalidOid;        /* We assume there can be only one match */
systable_endscan(sysscan);       heap_close(hdesc, AccessShareLock);
 
-        PG_RETURN_OID(result);
+        return result;    }    /*
@@ -865,11 +898,16 @@ regclassin(PG_FUNCTION_ARGS)     * pg_class entries in the current search path.     */    names =
stringToQualifiedNameList(class_name_or_oid);
+    if (names == NIL)
+        return InvalidOid;    /* We might not even have permissions on this relation; don't lock it. */
-    result = RangeVarGetRelid(makeRangeVarFromNameList(names), NoLock, false);
+    if (raiseError)
+        result = RangeVarGetRelid(makeRangeVarFromNameList(names), NoLock, false);
+    else
+        result = RangeVarGetRelid(makeRangeVarFromNameList(names), NoLock, true);
-    PG_RETURN_OID(result);
+    return result;}/*
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 0117500..472ccad 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -3304,13 +3304,14 @@ DATA(insert OID = 2218 (  regclassin        PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0
2DESCR("I/O");DATA(insertOID = 2219 (  regclassout        PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2275 "2205" _null_
_null__null_ _null_ regclassout _null_ _null_ _null_ ));DESCR("I/O");
 
+DATA(insert OID = 3179 (  toregclass        PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2205 "2275" _null_ _null_ _null_
_null_toregclass _null_ _null_ _null_ ));
 
+DESCR("convert classname to regclass");DATA(insert OID = 2220 (  regtypein            PGNSP PGUID 12 1 0 0 0 f f f f t
fs 1 0 2206 "2275" _null_ _null_ _null_ _null_ regtypein _null_ _null_ _null_ ));DESCR("I/O");DATA(insert OID = 2221 (
regtypeout       PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2275 "2206" _null_ _null_ _null_ _null_ regtypeout _null_
_null__null_ ));DESCR("I/O");DATA(insert OID = 1079 (  regclass            PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0
2205"25" _null_ _null_ _null_ _null_    text_regclass _null_ _null_ _null_ ));DESCR("convert text to regclass");
 
-DATA(insert OID = 2246 ( fmgr_internal_validator PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2278 "26" _null_ _null_
_null__null_ fmgr_internal_validator _null_ _null_ _null_ ));DESCR("(internal)");DATA(insert OID = 2247 (
fmgr_c_validator   PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 2278 "26" _null_ _null_ _null_ _null_ fmgr_c_validator
_null__null_ _null_ ));
 
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 1bfd145..1b57a7b 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -600,6 +600,7 @@ extern Datum regclassin(PG_FUNCTION_ARGS);extern Datum regclassout(PG_FUNCTION_ARGS);extern Datum
regclassrecv(PG_FUNCTION_ARGS);externDatum regclasssend(PG_FUNCTION_ARGS);
 
+extern Datum toregclass(PG_FUNCTION_ARGS);extern Datum regtypein(PG_FUNCTION_ARGS);extern Datum
regtypeout(PG_FUNCTION_ARGS);externDatum regtyperecv(PG_FUNCTION_ARGS); 

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

Предыдущее
От: Yeb Havinga
Дата:
Сообщение: Re: [v9.4] row level security
Следующее
От: Sergey Muraviov
Дата:
Сообщение: Re: Problem with displaying "wide" tables in psql