>> 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

Reply via email to