1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-25 01:02:05 +03:00

Make DROP IF EXISTS more consistently not fail

Some cases were still reporting errors and aborting, instead of a NOTICE
that the object was being skipped.  This makes it more difficult to
cleanly handle pg_dump --clean, so change that to instead skip missing
objects properly.

Per bug #7873 reported by Dave Rolsky; apparently this affects a large
number of users.

Authors: Pavel Stehule and Dean Rasheed.  Some tweaks by Álvaro Herrera
This commit is contained in:
Alvaro Herrera
2014-01-23 14:40:29 -03:00
parent 9f80f4835a
commit b152c6cd0d
17 changed files with 523 additions and 145 deletions

View File

@ -1259,7 +1259,8 @@ func_get_detail(List *funcname,
/* Get list of possible candidates from namespace search */
raw_candidates = FuncnameGetCandidates(funcname, nargs, fargnames,
expand_variadic, expand_defaults);
expand_variadic, expand_defaults,
false);
/*
* Quickly check if there is an exact match to the input datatypes (there
@ -1714,7 +1715,7 @@ FuncNameAsType(List *funcname)
Oid result;
Type typtup;
typtup = LookupTypeName(NULL, makeTypeNameFromNameList(funcname), NULL);
typtup = LookupTypeName(NULL, makeTypeNameFromNameList(funcname), NULL, false);
if (typtup == NULL)
return InvalidOid;
@ -1873,7 +1874,7 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
{
FuncCandidateList clist;
clist = FuncnameGetCandidates(funcname, nargs, NIL, false, false);
clist = FuncnameGetCandidates(funcname, nargs, NIL, false, false, noError);
while (clist)
{
@ -1892,27 +1893,6 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
return InvalidOid;
}
/*
* LookupTypeNameOid
* Convenience routine to look up a type, silently accepting shell types
*/
static Oid
LookupTypeNameOid(const TypeName *typename)
{
Oid result;
Type typtup;
typtup = LookupTypeName(NULL, typename, NULL);
if (typtup == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type \"%s\" does not exist",
TypeNameToString(typename))));
result = typeTypeId(typtup);
ReleaseSysCache(typtup);
return result;
}
/*
* LookupFuncNameTypeNames
* Like LookupFuncName, but the argument types are specified by a
@ -1940,7 +1920,7 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
{
TypeName *t = (TypeName *) lfirst(args_item);
argoids[i] = LookupTypeNameOid(t);
argoids[i] = LookupTypeNameOid(NULL, t, noError);
args_item = lnext(args_item);
}
@ -1980,7 +1960,7 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
{
TypeName *t = (TypeName *) lfirst(lc);
argoids[i] = LookupTypeNameOid(t);
argoids[i] = LookupTypeNameOid(NULL, t, noError);
i++;
}

View File

@ -148,12 +148,12 @@ LookupOperNameTypeNames(ParseState *pstate, List *opername,
if (oprleft == NULL)
leftoid = InvalidOid;
else
leftoid = typenameTypeId(pstate, oprleft);
leftoid = LookupTypeNameOid(pstate, oprleft, noError);
if (oprright == NULL)
rightoid = InvalidOid;
else
rightoid = typenameTypeId(pstate, oprright);
rightoid = LookupTypeNameOid(pstate, oprright, noError);
return LookupOperName(pstate, opername, leftoid, rightoid,
noError, location);

View File

@ -56,7 +56,7 @@ static int32 typenameTypeMod(ParseState *pstate, const TypeName *typeName,
*/
Type
LookupTypeName(ParseState *pstate, const TypeName *typeName,
int32 *typmod_p)
int32 *typmod_p, bool missing_ok)
{
Oid typoid;
HeapTuple tup;
@ -116,24 +116,32 @@ LookupTypeName(ParseState *pstate, const TypeName *typeName,
* concurrent DDL. But taking a lock would carry a performance
* penalty and would also require a permissions check.
*/
relid = RangeVarGetRelid(rel, NoLock, false);
relid = RangeVarGetRelid(rel, NoLock, missing_ok);
attnum = get_attnum(relid, field);
if (attnum == InvalidAttrNumber)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
field, rel->relname),
parser_errposition(pstate, typeName->location)));
typoid = get_atttype(relid, attnum);
{
if (missing_ok)
typoid = InvalidOid;
else
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
field, rel->relname),
parser_errposition(pstate, typeName->location)));
}
else
{
typoid = get_atttype(relid, attnum);
/* this construct should never have an array indicator */
Assert(typeName->arrayBounds == NIL);
/* this construct should never have an array indicator */
Assert(typeName->arrayBounds == NIL);
/* emit nuisance notice (intentionally not errposition'd) */
ereport(NOTICE,
(errmsg("type reference %s converted to %s",
TypeNameToString(typeName),
format_type_be(typoid))));
/* emit nuisance notice (intentionally not errposition'd) */
ereport(NOTICE,
(errmsg("type reference %s converted to %s",
TypeNameToString(typeName),
format_type_be(typoid))));
}
}
else
{
@ -149,10 +157,13 @@ LookupTypeName(ParseState *pstate, const TypeName *typeName,
/* Look in specific schema only */
Oid namespaceId;
namespaceId = LookupExplicitNamespace(schemaname, false);
typoid = GetSysCacheOid2(TYPENAMENSP,
PointerGetDatum(typname),
ObjectIdGetDatum(namespaceId));
namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
if (OidIsValid(namespaceId))
typoid = GetSysCacheOid2(TYPENAMENSP,
PointerGetDatum(typname),
ObjectIdGetDatum(namespaceId));
else
typoid = InvalidOid;
}
else
{
@ -184,6 +195,43 @@ LookupTypeName(ParseState *pstate, const TypeName *typeName,
return (Type) tup;
}
/*
* LookupTypeNameOid
* Given a TypeName object, lookup the pg_type syscache entry of the type.
* Returns InvalidOid if no such type can be found. If the type is found,
* return its Oid.
*
* NB: direct callers of this function need to be aware that the type OID
* returned may correspond to a shell type. Most code should go through
* typenameTypeId instead.
*
* pstate is only used for error location info, and may be NULL.
*/
Oid
LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, bool missing_ok)
{
Oid typoid;
Type tup;
tup = LookupTypeName(pstate, typeName, NULL, missing_ok);
if (tup == NULL)
{
if (!missing_ok)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type \"%s\" does not exist",
TypeNameToString(typeName)),
parser_errposition(pstate, typeName->location)));
return InvalidOid;
}
typoid = HeapTupleGetOid(tup);
ReleaseSysCache(tup);
return typoid;
}
/*
* typenameType - given a TypeName, return a Type structure and typmod
*
@ -196,7 +244,7 @@ typenameType(ParseState *pstate, const TypeName *typeName, int32 *typmod_p)
{
Type tup;
tup = LookupTypeName(pstate, typeName, typmod_p);
tup = LookupTypeName(pstate, typeName, typmod_p, false);
if (tup == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),