drop-if-exists-no-double-check.patch
application/octet-stream
Filename: drop-if-exists-no-double-check.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| src/backend/catalog/objectaddress.c | 49 | 0 |
| src/backend/commands/dropcmds.c | 34 | 0 |
| src/backend/commands/tablecmds.c | 3 | 0 |
| src/backend/commands/typecmds.c | 2 | 0 |
| src/backend/parser/parse_func.c | 18 | 0 |
| src/backend/parser/parse_oper.c | 2 | 0 |
| src/backend/parser/parse_type.c | 38 | 0 |
| src/backend/parser/parse_utilcmd.c | 2 | 0 |
| src/include/parser/parse_type.h | 3 | 0 |
| src/test/regress/expected/drop_if_exists.out | 2 | 0 |
*** a/src/backend/catalog/objectaddress.c
--- b/src/backend/catalog/objectaddress.c
***************
*** 580,587 **** get_object_address(ObjectType objtype, List *objname, List *objargs,
{
TypeName *sourcetype = (TypeName *) linitial(objname);
TypeName *targettype = (TypeName *) linitial(objargs);
! Oid sourcetypeid = typenameTypeId(NULL, sourcetype);
! Oid targettypeid = typenameTypeId(NULL, targettype);
address.classId = CastRelationId;
address.objectId =
--- 580,595 ----
{
TypeName *sourcetype = (TypeName *) linitial(objname);
TypeName *targettype = (TypeName *) linitial(objargs);
! Oid sourcetypeid = typenameTypeId_extended(NULL,
! sourcetype, missing_ok);
! Oid targettypeid = typenameTypeId_extended(NULL,
! targettype, missing_ok);
!
! if (!OidIsValid(sourcetypeid) || !OidIsValid(targettypeid))
! {
! address.objectId = InvalidOid;
! break;
! }
address.classId = CastRelationId;
address.objectId =
***************
*** 942,983 **** get_object_address_relobject(ObjectType objtype, List *objname,
/* Extract relation name and open relation. */
relname = list_truncate(list_copy(objname), nnames - 1);
- relation = heap_openrv(makeRangeVarFromNameList(relname),
- AccessShareLock);
- reloid = RelationGetRelid(relation);
! switch (objtype)
{
! case OBJECT_RULE:
! address.classId = RewriteRelationId;
! address.objectId = get_rewrite_oid(reloid, depname, missing_ok);
! address.objectSubId = 0;
! break;
! case OBJECT_TRIGGER:
! address.classId = TriggerRelationId;
! address.objectId = get_trigger_oid(reloid, depname, missing_ok);
! address.objectSubId = 0;
! break;
! case OBJECT_CONSTRAINT:
! address.classId = ConstraintRelationId;
! address.objectId =
! get_relation_constraint_oid(reloid, depname, missing_ok);
! address.objectSubId = 0;
! break;
! default:
! elog(ERROR, "unrecognized objtype: %d", (int) objtype);
! /* placate compiler, which doesn't know elog won't return */
! address.classId = InvalidOid;
! address.objectId = InvalidOid;
! address.objectSubId = 0;
! }
! /* Avoid relcache leak when object not found. */
! if (!OidIsValid(address.objectId))
! {
! heap_close(relation, AccessShareLock);
! relation = NULL; /* department of accident prevention */
! return address;
}
}
--- 950,997 ----
/* Extract relation name and open relation. */
relname = list_truncate(list_copy(objname), nnames - 1);
! relation = heap_openrv_extended(makeRangeVarFromNameList(relname),
! AccessShareLock,
! missing_ok);
!
! if (relation != NULL)
{
! reloid = RelationGetRelid(relation);
! switch (objtype)
! {
! case OBJECT_RULE:
! address.classId = RewriteRelationId;
! address.objectId = get_rewrite_oid(reloid, depname, missing_ok);
! address.objectSubId = 0;
! break;
! case OBJECT_TRIGGER:
! address.classId = TriggerRelationId;
! address.objectId = get_trigger_oid(reloid, depname, missing_ok);
! address.objectSubId = 0;
! break;
! case OBJECT_CONSTRAINT:
! address.classId = ConstraintRelationId;
! address.objectId =
! get_relation_constraint_oid(reloid, depname, missing_ok);
! address.objectSubId = 0;
! break;
! default:
! elog(ERROR, "unrecognized objtype: %d", (int) objtype);
! /* placate compiler, which doesn't know elog won't return */
! address.classId = InvalidOid;
! address.objectId = InvalidOid;
! address.objectSubId = 0;
! }
!
! /* Avoid relcache leak when object not found. */
! if (!OidIsValid(address.objectId))
! {
! heap_close(relation, AccessShareLock);
! relation = NULL; /* department of accident prevention */
! return address;
! }
}
}
*** a/src/backend/commands/dropcmds.c
--- b/src/backend/commands/dropcmds.c
***************
*** 194,204 **** does_not_exist_skipping(ObjectType objtype, List *objname, List *objargs)
name = NameListToString(objname);
break;
case OBJECT_CAST:
! msg = gettext_noop("cast from type %s to type %s does not exist, skipping");
! name = format_type_be(typenameTypeId(NULL,
! (TypeName *) linitial(objname)));
! args = format_type_be(typenameTypeId(NULL,
! (TypeName *) linitial(objargs)));
break;
case OBJECT_TRIGGER:
msg = gettext_noop("trigger \"%s\" for table \"%s\" does not exist, skipping");
--- 194,233 ----
name = NameListToString(objname);
break;
case OBJECT_CAST:
! {
! Oid typid1,
! typid2;
! /*
! * when one from requested types is unknown, then do nothing,
! * because notice was raised already.
! */
! typid1 = typenameTypeId_extended(NULL, (TypeName *) linitial(objname), true);
! typid2 = typenameTypeId_extended(NULL, (TypeName *) linitial(objargs), true);
!
! if (OidIsValid(typid1) && OidIsValid(typid2))
! {
! msg = gettext_noop("cast from type %s to type %s does not exist, skipping");
! name = format_type_be(typid1);
! args = format_type_be(typid2);
! }
! else if (OidIsValid(typid1) && !OidIsValid(typid2))
! {
! msg = gettext_noop("type \"%s\" does not exist, skipping");
! name = TypeNameToString((TypeName *) linitial(objargs));
!
! }
! else if (!OidIsValid(typid1) && OidIsValid(typid2))
! {
! msg = gettext_noop("type \"%s\" does not exist, skipping");
! name = TypeNameToString((TypeName *) linitial(objname));
! }
! else
! {
! msg = gettext_noop("types \"%s\" and \"%s\" does not exist, skipping");
! name = TypeNameToString((TypeName *) linitial(objname));
! args = TypeNameToString((TypeName *) linitial(objargs));
! }
! }
break;
case OBJECT_TRIGGER:
msg = gettext_noop("trigger \"%s\" for table \"%s\" does not exist, skipping");
*** a/src/backend/commands/tablecmds.c
--- b/src/backend/commands/tablecmds.c
***************
*** 4484,4490 **** ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
MaxHeapAttributeNumber)));
}
! typeTuple = typenameType(NULL, colDef->typeName, &typmod);
tform = (Form_pg_type) GETSTRUCT(typeTuple);
typeOid = HeapTupleGetOid(typeTuple);
--- 4484,4490 ----
MaxHeapAttributeNumber)));
}
! typeTuple = typenameType(NULL, colDef->typeName, &typmod, false);
tform = (Form_pg_type) GETSTRUCT(typeTuple);
typeOid = HeapTupleGetOid(typeTuple);
***************
*** 7596,7602 **** ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
colName)));
/* Look up the target type (should not fail, since prep found it) */
! typeTuple = typenameType(NULL, typeName, &targettypmod);
tform = (Form_pg_type) GETSTRUCT(typeTuple);
targettype = HeapTupleGetOid(typeTuple);
/* And the collation */
--- 7596,7602 ----
colName)));
/* Look up the target type (should not fail, since prep found it) */
! typeTuple = typenameType(NULL, typeName, &targettypmod, false);
tform = (Form_pg_type) GETSTRUCT(typeTuple);
targettype = HeapTupleGetOid(typeTuple);
/* And the collation */
***************
*** 9812,9818 **** ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode)
HeapTuple classtuple;
/* Validate the type. */
! typetuple = typenameType(NULL, ofTypename, NULL);
check_of_type(typetuple);
typeid = HeapTupleGetOid(typetuple);
--- 9812,9818 ----
HeapTuple classtuple;
/* Validate the type. */
! typetuple = typenameType(NULL, ofTypename, NULL, false);
check_of_type(typetuple);
typeid = HeapTupleGetOid(typetuple);
*** a/src/backend/commands/typecmds.c
--- b/src/backend/commands/typecmds.c
***************
*** 307,313 **** DefineType(List *names, List *parameters)
Type likeType;
Form_pg_type likeForm;
! likeType = typenameType(NULL, defGetTypeName(likeTypeEl), NULL);
likeForm = (Form_pg_type) GETSTRUCT(likeType);
internalLength = likeForm->typlen;
byValue = likeForm->typbyval;
--- 307,313 ----
Type likeType;
Form_pg_type likeForm;
! likeType = typenameType(NULL, defGetTypeName(likeTypeEl), NULL, false);
likeForm = (Form_pg_type) GETSTRUCT(likeType);
internalLength = likeForm->typlen;
byValue = likeForm->typbyval;
***************
*** 741,747 **** DefineDomain(CreateDomainStmt *stmt)
/*
* Look up the base type.
*/
! typeTup = typenameType(NULL, stmt->typeName, &basetypeMod);
baseType = (Form_pg_type) GETSTRUCT(typeTup);
basetypeoid = HeapTupleGetOid(typeTup);
--- 741,747 ----
/*
* Look up the base type.
*/
! typeTup = typenameType(NULL, stmt->typeName, &basetypeMod, false);
baseType = (Form_pg_type) GETSTRUCT(typeTup);
basetypeoid = HeapTupleGetOid(typeTup);
*** a/src/backend/parser/parse_func.c
--- b/src/backend/parser/parse_func.c
***************
*** 1574,1590 **** LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
* 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;
--- 1574,1595 ----
* Convenience routine to look up a type, silently accepting shell types
*/
static Oid
! LookupTypeNameOid(const TypeName *typename, bool missing_ok)
{
Oid result;
Type typtup;
typtup = LookupTypeName(NULL, typename, NULL);
if (typtup == NULL)
+ {
+ if (missing_ok)
+ return InvalidOid;
+
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type \"%s\" does not exist",
TypeNameToString(typename))));
+ }
result = typeTypeId(typtup);
ReleaseSysCache(typtup);
return result;
***************
*** 1617,1623 **** LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError)
{
TypeName *t = (TypeName *) lfirst(args_item);
! argoids[i] = LookupTypeNameOid(t);
args_item = lnext(args_item);
}
--- 1622,1633 ----
{
TypeName *t = (TypeName *) lfirst(args_item);
! if (!OidIsValid(argoids[i] = LookupTypeNameOid(t, noError)))
! {
! Assert(noError);
! return InvalidOid;
! }
!
args_item = lnext(args_item);
}
***************
*** 1657,1663 **** LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError)
{
TypeName *t = (TypeName *) lfirst(lc);
! argoids[i] = LookupTypeNameOid(t);
i++;
}
--- 1667,1678 ----
{
TypeName *t = (TypeName *) lfirst(lc);
! if (!OidIsValid(argoids[i] = LookupTypeNameOid(t, noError)))
! {
! Assert(noError);
! return InvalidOid;
! }
!
i++;
}
*** a/src/backend/parser/parse_oper.c
--- b/src/backend/parser/parse_oper.c
***************
*** 148,159 **** LookupOperNameTypeNames(ParseState *pstate, List *opername,
if (oprleft == NULL)
leftoid = InvalidOid;
else
! leftoid = typenameTypeId(pstate, oprleft);
if (oprright == NULL)
rightoid = InvalidOid;
else
! rightoid = typenameTypeId(pstate, oprright);
return LookupOperName(pstate, opername, leftoid, rightoid,
noError, location);
--- 148,159 ----
if (oprleft == NULL)
leftoid = InvalidOid;
else
! leftoid = typenameTypeId_extended(pstate, oprleft, noError);
if (oprright == NULL)
rightoid = InvalidOid;
else
! rightoid = typenameTypeId_extended(pstate, oprright, noError);
return LookupOperName(pstate, opername, leftoid, rightoid,
noError, location);
*** a/src/backend/parser/parse_type.c
--- b/src/backend/parser/parse_type.c
***************
*** 192,208 **** LookupTypeName(ParseState *pstate, const TypeName *typeName,
* Callers of this can therefore assume the result is a fully valid type.
*/
Type
! typenameType(ParseState *pstate, const TypeName *typeName, int32 *typmod_p)
{
Type tup;
tup = LookupTypeName(pstate, typeName, typmod_p);
if (tup == NULL)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type \"%s\" does not exist",
TypeNameToString(typeName)),
parser_errposition(pstate, typeName->location)));
if (!((Form_pg_type) GETSTRUCT(tup))->typisdefined)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
--- 192,216 ----
* Callers of this can therefore assume the result is a fully valid type.
*/
Type
! typenameType(ParseState *pstate, const TypeName *typeName, int32 *typmod_p,
! bool missing_ok)
{
Type tup;
tup = LookupTypeName(pstate, typeName, typmod_p);
if (tup == NULL)
+ {
+ if (missing_ok)
+ /* be quite, caller is responsible to raise message */
+ return NULL;
+
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("type \"%s\" does not exist",
TypeNameToString(typeName)),
parser_errposition(pstate, typeName->location)));
+ }
+
if (!((Form_pg_type) GETSTRUCT(tup))->typisdefined)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
***************
*** 224,230 **** typenameTypeId(ParseState *pstate, const TypeName *typeName)
Oid typoid;
Type tup;
! tup = typenameType(pstate, typeName, NULL);
typoid = HeapTupleGetOid(tup);
ReleaseSysCache(tup);
--- 232,265 ----
Oid typoid;
Type tup;
! tup = typenameType(pstate, typeName, NULL, false);
! typoid = HeapTupleGetOid(tup);
! ReleaseSysCache(tup);
!
! return typoid;
! }
!
! /*
! * typenameTypeId_extended - given a TypeName, return the type's OID
! *
! * This is similar to typenameType, but we only hand back the type OID
! * not the syscache entry. When missing_ok is true, then doesn't raise
! * error when type is not exists.
! */
! Oid
! typenameTypeId_extended(ParseState *pstate, const TypeName *typeName,
! bool missing_ok)
! {
! Oid typoid;
! Type tup;
!
! tup = typenameType(pstate, typeName, NULL, missing_ok);
! if (tup == NULL)
! {
! Assert(missing_ok);
! return InvalidOid;
! }
!
typoid = HeapTupleGetOid(tup);
ReleaseSysCache(tup);
***************
*** 243,249 **** typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName,
{
Type tup;
! tup = typenameType(pstate, typeName, typmod_p);
*typeid_p = HeapTupleGetOid(tup);
ReleaseSysCache(tup);
}
--- 278,284 ----
{
Type tup;
! tup = typenameType(pstate, typeName, typmod_p, false);
*typeid_p = HeapTupleGetOid(tup);
ReleaseSysCache(tup);
}
*** a/src/backend/parser/parse_utilcmd.c
--- b/src/backend/parser/parse_utilcmd.c
***************
*** 942,948 **** transformOfType(CreateStmtContext *cxt, TypeName *ofTypename)
AssertArg(ofTypename);
! tuple = typenameType(NULL, ofTypename, NULL);
check_of_type(tuple);
ofTypeId = HeapTupleGetOid(tuple);
ofTypename->typeOid = ofTypeId; /* cached for later */
--- 942,948 ----
AssertArg(ofTypename);
! tuple = typenameType(NULL, ofTypename, NULL, false);
check_of_type(tuple);
ofTypeId = HeapTupleGetOid(tuple);
ofTypename->typeOid = ofTypeId; /* cached for later */
***************
*** 2652,2658 **** transformColumnType(CreateStmtContext *cxt, ColumnDef *column)
* All we really need to do here is verify that the type is valid,
* including any collation spec that might be present.
*/
! Type ctype = typenameType(cxt->pstate, column->typeName, NULL);
if (column->collClause)
{
--- 2652,2658 ----
* All we really need to do here is verify that the type is valid,
* including any collation spec that might be present.
*/
! Type ctype = typenameType(cxt->pstate, column->typeName, NULL, false);
if (column->collClause)
{
*** a/src/include/parser/parse_type.h
--- b/src/include/parser/parse_type.h
***************
*** 22,29 **** typedef HeapTuple Type;
extern Type LookupTypeName(ParseState *pstate, const TypeName *typeName,
int32 *typmod_p);
extern Type typenameType(ParseState *pstate, const TypeName *typeName,
! int32 *typmod_p);
extern Oid typenameTypeId(ParseState *pstate, const TypeName *typeName);
extern void typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName,
Oid *typeid_p, int32 *typmod_p);
--- 22,31 ----
extern Type LookupTypeName(ParseState *pstate, const TypeName *typeName,
int32 *typmod_p);
extern Type typenameType(ParseState *pstate, const TypeName *typeName,
! int32 *typmod_p, bool missing_ok);
extern Oid typenameTypeId(ParseState *pstate, const TypeName *typeName);
+ extern Oid typenameTypeId_extended(ParseState *pstate,
+ const TypeName *typeName, bool missing_ok);
extern void typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName,
Oid *typeid_p, int32 *typmod_p);
*** a/src/test/regress/expected/drop_if_exists.out
--- b/src/test/regress/expected/drop_if_exists.out
***************
*** 173,179 **** NOTICE: trigger "test_trigger_exists" for table "test_exists" does not exist, s
DROP TRIGGER test_trigger_exists ON no_such_table;
ERROR: relation "no_such_table" does not exist
DROP TRIGGER IF EXISTS test_trigger_exists ON no_such_table;
! ERROR: relation "no_such_table" does not exist
CREATE TRIGGER test_trigger_exists
BEFORE UPDATE ON test_exists
FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
--- 173,179 ----
DROP TRIGGER test_trigger_exists ON no_such_table;
ERROR: relation "no_such_table" does not exist
DROP TRIGGER IF EXISTS test_trigger_exists ON no_such_table;
! NOTICE: trigger "test_trigger_exists" for table "no_such_table" does not exist, skipping
CREATE TRIGGER test_trigger_exists
BEFORE UPDATE ON test_exists
FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
***************
*** 186,192 **** NOTICE: rule "test_rule_exists" for relation "test_exists" does not exist, skip
DROP RULE test_rule_exists ON no_such_table;
ERROR: relation "no_such_table" does not exist
DROP RULE IF EXISTS test_rule_exists ON no_such_table;
! ERROR: relation "no_such_table" does not exist
CREATE RULE test_rule_exists AS ON INSERT TO test_exists
DO INSTEAD
INSERT INTO test_exists VALUES (NEW.a, NEW.b || NEW.a::text);
--- 186,192 ----
DROP RULE test_rule_exists ON no_such_table;
ERROR: relation "no_such_table" does not exist
DROP RULE IF EXISTS test_rule_exists ON no_such_table;
! NOTICE: rule "test_rule_exists" for relation "no_such_table" does not exist, skipping
CREATE RULE test_rule_exists AS ON INSERT TO test_exists
DO INSTEAD
INSERT INTO test_exists VALUES (NEW.a, NEW.b || NEW.a::text);