summaryrefslogtreecommitdiff
path: root/src/backend/parser
diff options
context:
space:
mode:
authorRobert Haas2014-04-08 14:27:56 +0000
committerRobert Haas2014-04-08 14:27:56 +0000
commit0886fc6a5c75b294544263ea979b9cf6195407d9 (patch)
tree2cf04aae147dc80a980cab40a39d23af92822d0d /src/backend/parser
parent7ca32e255ba4f7e55bbdbcf0df996ac62798672b (diff)
Add new to_reg* functions for error-free OID lookups.
These functions won't throw an error if the object doesn't exist, or if (for functions and operators) there's more than one matching object. Yugo Nagata and Nozomi Anzai, reviewed by Amit Khandekar, Marti Raudsepp, Amit Kapila, and me.
Diffstat (limited to 'src/backend/parser')
-rw-r--r--src/backend/parser/parse_oper.c6
-rw-r--r--src/backend/parser/parse_type.c29
2 files changed, 30 insertions, 5 deletions
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c
index 99dbd30d75..a2b712d516 100644
--- a/src/backend/parser/parse_oper.c
+++ b/src/backend/parser/parse_oper.c
@@ -407,7 +407,7 @@ oper(ParseState *pstate, List *opname, Oid ltypeId, Oid rtypeId,
FuncCandidateList clist;
/* Get binary operators of given name */
- clist = OpernameGetCandidates(opname, 'b');
+ clist = OpernameGetCandidates(opname, 'b', false);
/* No operators found? Then fail... */
if (clist != NULL)
@@ -553,7 +553,7 @@ right_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location)
FuncCandidateList clist;
/* Get postfix operators of given name */
- clist = OpernameGetCandidates(op, 'r');
+ clist = OpernameGetCandidates(op, 'r', false);
/* No operators found? Then fail... */
if (clist != NULL)
@@ -631,7 +631,7 @@ left_oper(ParseState *pstate, List *op, Oid arg, bool noError, int location)
FuncCandidateList clist;
/* Get prefix operators of given name */
- clist = OpernameGetCandidates(op, 'l');
+ clist = OpernameGetCandidates(op, 'l', false);
/* No operators found? Then fail... */
if (clist != NULL)
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
index b329dfb168..b8c10e11c9 100644
--- a/src/backend/parser/parse_type.c
+++ b/src/backend/parser/parse_type.c
@@ -706,9 +706,12 @@ pts_error_callback(void *arg)
* Given a string that is supposed to be a SQL-compatible type declaration,
* such as "int4" or "integer" or "character varying(32)", parse
* the string and convert it to a type OID and type modifier.
+ * If missing_ok is true, InvalidOid is returned rather than raising an error
+ * when the type name is not found.
*/
void
-parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p)
+parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p,
+ bool missing_ok)
{
StringInfoData buf;
List *raw_parsetree_list;
@@ -717,6 +720,7 @@ parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p)
TypeCast *typecast;
TypeName *typeName;
ErrorContextCallback ptserrcontext;
+ Type tup;
/* make sure we give useful error for empty input */
if (strspn(str, " \t\n\r\f") == strlen(str))
@@ -782,7 +786,28 @@ parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p)
if (typeName->setof)
goto fail;
- typenameTypeIdAndMod(NULL, typeName, typeid_p, typmod_p);
+ tup = LookupTypeName(NULL, typeName, typmod_p, missing_ok);
+ if (tup == NULL)
+ {
+ if (!missing_ok)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("type \"%s\" does not exist",
+ TypeNameToString(typeName)),
+ parser_errposition(NULL, typeName->location)));
+ *typeid_p = InvalidOid;
+ }
+ else
+ {
+ if (!((Form_pg_type) GETSTRUCT(tup))->typisdefined)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("type \"%s\" is only a shell",
+ TypeNameToString(typeName)),
+ parser_errposition(NULL, typeName->location)));
+ *typeid_p = HeapTupleGetOid(tup);
+ ReleaseSysCache(tup);
+ }
pfree(buf.data);