>> 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(Oid procedure_oid, bool force_qualify); static void parseNameAndArgTypes(const char *string, bool allowNone, List **names, int *nargs, Oid *argtypes); +static Datum regclass_guts(char *class_name_or_oid, bool raiseError); /***************************************************************************** @@ -804,21 +805,50 @@ Datum regclassin(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 2 DESCR("I/O"); DATA(insert OID = 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 f s 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); extern Datum regclasssend(PG_FUNCTION_ARGS); +extern Datum toregclass(PG_FUNCTION_ARGS); extern Datum regtypein(PG_FUNCTION_ARGS); extern Datum regtypeout(PG_FUNCTION_ARGS); extern Datum regtyperecv(PG_FUNCTION_ARGS);
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers