diff options
Diffstat (limited to 'src/backend/parser')
-rw-r--r-- | src/backend/parser/parse_type.c | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c index f7ad6894596..8f3850aa4e8 100644 --- a/src/backend/parser/parse_type.c +++ b/src/backend/parser/parse_type.c @@ -727,10 +727,15 @@ 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 return the result as a TypeName. - * If the string cannot be parsed as a type, an error is raised. + * + * If the string cannot be parsed as a type, an error is raised, + * unless escontext is an ErrorSaveContext node, in which case we may + * fill that and return NULL. But note that the ErrorSaveContext option + * is mostly aspirational at present: errors detected by the main + * grammar, rather than here, will still be thrown. */ TypeName * -typeStringToTypeName(const char *str) +typeStringToTypeName(const char *str, Node *escontext) { List *raw_parsetree_list; TypeName *typeName; @@ -763,49 +768,54 @@ typeStringToTypeName(const char *str) return typeName; fail: - ereport(ERROR, + ereturn(escontext, NULL, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("invalid type name \"%s\"", str))); - return NULL; /* keep compiler quiet */ } /* * 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. + * + * If escontext is an ErrorSaveContext node, then errors are reported by + * filling escontext and returning false, instead of throwing them. */ -void -parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, bool missing_ok) +bool +parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, + Node *escontext) { TypeName *typeName; Type tup; - typeName = typeStringToTypeName(str); + typeName = typeStringToTypeName(str, escontext); + if (typeName == NULL) + return false; - tup = LookupTypeName(NULL, typeName, typmod_p, missing_ok); + tup = LookupTypeName(NULL, typeName, typmod_p, + (escontext && IsA(escontext, ErrorSaveContext))); 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; + ereturn(escontext, false, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("type \"%s\" does not exist", + TypeNameToString(typeName)))); } else { Form_pg_type typ = (Form_pg_type) GETSTRUCT(tup); if (!typ->typisdefined) - ereport(ERROR, + { + ReleaseSysCache(tup); + ereturn(escontext, false, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("type \"%s\" is only a shell", - TypeNameToString(typeName)), - parser_errposition(NULL, typeName->location))); + TypeNameToString(typeName)))); + } *typeid_p = typ->oid; ReleaseSysCache(tup); } + + return true; } |