drop trigger syntax
This commit is contained in:
@ -15,6 +15,8 @@
|
||||
<refsynopsisdiv>
|
||||
<synopsis>
|
||||
DROP TRIGGER [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ]
|
||||
In B compatibility also support:
|
||||
DROP TRIGGER [ IF EXISTS ] name [ CASCADE | RESTRICT ]
|
||||
</synopsis>
|
||||
</refsynopsisdiv>
|
||||
</refentry>
|
||||
|
||||
@ -700,12 +700,19 @@ static ObjectAddress get_object_address_relobject(ObjectType objtype, List* objn
|
||||
* work. But objects other than rules don't get this special
|
||||
* treatment.
|
||||
*/
|
||||
if (objtype != OBJECT_RULE)
|
||||
ereport(ERROR, (errcode(ERRCODE_UNEXPECTED_NODE_STATE), errmsg("must specify relation and object name")));
|
||||
address.classId = RewriteRelationId;
|
||||
address.objectId = get_rewrite_oid_without_relid(depname, &reloid, missing_ok);
|
||||
address.objectSubId = 0;
|
||||
|
||||
/*mysql drop trigger syntax*/
|
||||
if (objtype == OBJECT_TRIGGER && u_sess->attr.attr_sql.sql_compatibility == B_FORMAT)
|
||||
{
|
||||
address.classId = TriggerRelationId;
|
||||
address.objectId = get_trigger_oid_b(depname, &reloid, missing_ok);
|
||||
address.objectSubId = 0;
|
||||
} else {
|
||||
if (objtype != OBJECT_RULE)
|
||||
ereport(ERROR, (errcode(ERRCODE_UNEXPECTED_NODE_STATE), errmsg("must specify relation and object name")));
|
||||
address.classId = RewriteRelationId;
|
||||
address.objectId = get_rewrite_oid_without_relid(depname, &reloid, missing_ok);
|
||||
address.objectSubId = 0;
|
||||
}
|
||||
/*
|
||||
* Caller is expecting to get back the relation, even though we didn't
|
||||
* end up using it to find the rule.
|
||||
|
||||
@ -11197,6 +11197,52 @@ DropTrigStmt:
|
||||
n->concurrent = false;
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| DROP TRIGGER name opt_drop_behavior
|
||||
{
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
const char* message = "drop trigger name is not yet supported in distributed database.";
|
||||
InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);
|
||||
ereport(errstate,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("drop trigger name is not yet supported in distributed database.")));
|
||||
#endif
|
||||
if (u_sess->attr.attr_sql.sql_compatibility != B_FORMAT) {
|
||||
ereport(errstate,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("drop trigger without table name only support in B-format database")));
|
||||
}
|
||||
DropStmt *n = makeNode(DropStmt);
|
||||
n->removeType = OBJECT_TRIGGER;
|
||||
n->objects = list_make1(list_make1(makeString($3)));
|
||||
n->arguments = NIL;
|
||||
n->behavior = $4;
|
||||
n->missing_ok = false;
|
||||
n->concurrent = false;
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| DROP TRIGGER IF_P EXISTS name opt_drop_behavior
|
||||
{
|
||||
#ifdef ENABLE_MULTIPLE_NODES
|
||||
const char* message = "drop trigger if exists name is not yet supported in distributed database.";
|
||||
InsertErrorMessage(message, u_sess->plsql_cxt.plpgsql_yylloc);
|
||||
ereport(errstate,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("drop trigger if exists name is not yet supported in distributed database.")));
|
||||
#endif
|
||||
if (u_sess->attr.attr_sql.sql_compatibility != B_FORMAT) {
|
||||
ereport(errstate,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("drop trigger without table name only support in B-format database")));
|
||||
}
|
||||
DropStmt *n = makeNode(DropStmt);
|
||||
n->removeType = OBJECT_TRIGGER;
|
||||
n->objects = list_make1(list_make1(makeString($5)));
|
||||
n->arguments = NIL;
|
||||
n->behavior = $6;
|
||||
n->missing_ok = true;
|
||||
n->concurrent = false;
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
||||
@ -59,7 +59,7 @@ bool open_join_children = true;
|
||||
bool will_shutdown = false;
|
||||
|
||||
/* hard-wired binary version number */
|
||||
const uint32 GRAND_VERSION_NUM = 92836;
|
||||
const uint32 GRAND_VERSION_NUM = 92837;
|
||||
|
||||
const uint32 SELECT_INTO_VAR_VERSION_NUM = 92834;
|
||||
const uint32 DOLPHIN_ENABLE_DROP_NUM = 92830;
|
||||
|
||||
@ -376,10 +376,16 @@ static void does_not_exist_skipping(ObjectType objtype, List* objname, List* obj
|
||||
args = format_type_be(typenameTypeId(NULL, (TypeName*)linitial(objargs)));
|
||||
break;
|
||||
case OBJECT_TRIGGER:
|
||||
msg = gettext_noop("trigger \"%s\" for table \"%s\" does not exist");
|
||||
name = NameListToString(objname);
|
||||
args = NameListToString(list_truncate(list_copy(objname), list_length(objname) - 1));
|
||||
break;
|
||||
if (list_length(objname) == 1) {
|
||||
msg = gettext_noop("trigger \"%s\" does not exist");
|
||||
name = NameListToString(objname);
|
||||
break;
|
||||
} else {
|
||||
msg = gettext_noop("trigger \"%s\" for table \"%s\" does not exist");
|
||||
name = NameListToString(objname);
|
||||
args = NameListToString(list_truncate(list_copy(objname), list_length(objname) - 1));
|
||||
break;
|
||||
}
|
||||
case OBJECT_RULE:
|
||||
msg = gettext_noop("rule \"%s\" for relation \"%s\" does not exist");
|
||||
name = strVal(llast(objname));
|
||||
|
||||
@ -467,23 +467,38 @@ Oid CreateTrigger(CreateTrigStmt* stmt, const char* queryString, Oid relOid, Oid
|
||||
* relation, so the trigger set won't be changing underneath us.
|
||||
*/
|
||||
if (!isInternal) {
|
||||
ScanKeyInit(
|
||||
&key, Anum_pg_trigger_tgrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel)));
|
||||
tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true, NULL, 1, &key);
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(tgscan))) {
|
||||
Form_pg_trigger pg_trigger = (Form_pg_trigger)GETSTRUCT(tuple);
|
||||
if (namestrcmp(&(pg_trigger->tgname), trigname) == 0) {
|
||||
if (stmt->funcSource != NULL && u_sess->attr.attr_sql.sql_compatibility == B_FORMAT) {
|
||||
ScanKeyInit(
|
||||
&key, Anum_pg_trigger_tgname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(trigname));
|
||||
tgscan = systable_beginscan(tgrel, TriggerNameIndexId, true, NULL, 1, &key);
|
||||
if (HeapTupleIsValid(tuple = systable_getnext(tgscan))) {
|
||||
if (stmt->if_not_exists) {
|
||||
ereport(NOTICE,
|
||||
(errmsg("trigger \"%s\" for relation \"%s\" already exists,skipping",
|
||||
trigname,
|
||||
RelationGetRelationName(rel))));
|
||||
(errmsg("trigger \"%s\" already exists, skipping",
|
||||
trigname)));
|
||||
systable_endscan(tgscan);
|
||||
heap_close(tgrel, RowExclusiveLock);
|
||||
heap_close(rel, NoLock);
|
||||
return trigoid;
|
||||
}
|
||||
else {
|
||||
systable_endscan(tgscan);
|
||||
heap_close(tgrel, RowExclusiveLock);
|
||||
heap_close(rel, NoLock);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
||||
errmsg("trigger \"%s\" already exists",
|
||||
trigname)));
|
||||
}
|
||||
}
|
||||
systable_endscan(tgscan);
|
||||
} else {
|
||||
ScanKeyInit(
|
||||
&key, Anum_pg_trigger_tgrelid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(RelationGetRelid(rel)));
|
||||
tgscan = systable_beginscan(tgrel, TriggerRelidNameIndexId, true, NULL, 1, &key);
|
||||
while (HeapTupleIsValid(tuple = systable_getnext(tgscan))) {
|
||||
Form_pg_trigger pg_trigger = (Form_pg_trigger)GETSTRUCT(tuple);
|
||||
if (namestrcmp(&(pg_trigger->tgname), trigname) == 0) {
|
||||
systable_endscan(tgscan);
|
||||
heap_close(tgrel, RowExclusiveLock);
|
||||
heap_close(rel, NoLock);
|
||||
@ -494,11 +509,10 @@ Oid CreateTrigger(CreateTrigStmt* stmt, const char* queryString, Oid relOid, Oid
|
||||
RelationGetRelationName(rel))));
|
||||
}
|
||||
}
|
||||
systable_endscan(tgscan);
|
||||
}
|
||||
systable_endscan(tgscan);
|
||||
}
|
||||
|
||||
|
||||
if (stmt->funcSource != NULL && u_sess->attr.attr_sql.sql_compatibility == B_FORMAT) {
|
||||
CreateFunctionStmt* n = makeNode(CreateFunctionStmt);
|
||||
n->isOraStyle = false;
|
||||
@ -1302,6 +1316,53 @@ Oid get_trigger_oid(Oid relid, const char* trigname, bool missing_ok)
|
||||
return oid;
|
||||
}
|
||||
|
||||
Oid get_trigger_oid_b(const char* trigname, Oid* reloid, bool missing_ok)
|
||||
{
|
||||
Relation tgrel;
|
||||
ScanKeyData skey;
|
||||
SysScanDesc tgscan;
|
||||
HeapTuple tup;
|
||||
Oid oid;
|
||||
int count = 0;
|
||||
|
||||
/*
|
||||
* Find the trigger, verify permissions, set up object address
|
||||
*/
|
||||
tgrel = heap_open(TriggerRelationId, AccessShareLock);
|
||||
|
||||
ScanKeyInit(&skey, Anum_pg_trigger_tgname, BTEqualStrategyNumber, F_NAMEEQ, CStringGetDatum(trigname));
|
||||
|
||||
tgscan = systable_beginscan(tgrel, TriggerNameIndexId, true, NULL, 1, &skey);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(tgscan))) {
|
||||
count ++;
|
||||
if (count == 1) {
|
||||
Form_pg_trigger pg_trigger = (Form_pg_trigger)GETSTRUCT(tup);
|
||||
*reloid = pg_trigger->tgrelid;
|
||||
oid = HeapTupleGetOid(tup);
|
||||
} else if (count > 1) {
|
||||
systable_endscan(tgscan);
|
||||
heap_close(tgrel, AccessShareLock);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("trigger named \"%s\" has more than one trigger, please use drop trigger on syntax", trigname)));
|
||||
}
|
||||
}
|
||||
if (count == 0) {
|
||||
if (!missing_ok) {
|
||||
systable_endscan(tgscan);
|
||||
heap_close(tgrel, AccessShareLock);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||
errmsg("trigger \"%s\" does not exist", trigname)));
|
||||
}
|
||||
oid = InvalidOid;
|
||||
}
|
||||
|
||||
systable_endscan(tgscan);
|
||||
heap_close(tgrel, AccessShareLock);
|
||||
return oid;
|
||||
}
|
||||
/*
|
||||
* Perform permissions and integrity checks before acquiring a relation lock.
|
||||
*/
|
||||
|
||||
@ -270,6 +270,8 @@ DECLARE_UNIQUE_INDEX(pg_tablespace_spcname_index, 2698, on pg_tablespace using b
|
||||
/* This following index is not used for a cache and is not unique */
|
||||
DECLARE_INDEX(pg_trigger_tgconstraint_index, 2699, on pg_trigger using btree(tgconstraint oid_ops));
|
||||
#define TriggerConstraintIndexId 2699
|
||||
DECLARE_INDEX(pg_trigger_tgname_index, 2700, on pg_trigger using btree(tgname name_ops));
|
||||
#define TriggerNameIndexId 2700
|
||||
DECLARE_UNIQUE_INDEX(pg_trigger_tgrelid_tgname_index, 2701, on pg_trigger using btree(tgrelid oid_ops, tgname name_ops));
|
||||
#define TriggerRelidNameIndexId 2701
|
||||
DECLARE_UNIQUE_INDEX(pg_trigger_oid_index, 2702, on pg_trigger using btree(oid oid_ops));
|
||||
|
||||
@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS pg_catalog.pg_trigger_tgname_index;
|
||||
@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS pg_catalog.pg_trigger_tgname_index;
|
||||
@ -0,0 +1,3 @@
|
||||
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 2700;
|
||||
CREATE INDEX pg_catalog.pg_trigger_tgname_index ON pg_catalog.pg_trigger USING BTREE(tgname name_ops);
|
||||
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 0;
|
||||
@ -0,0 +1,3 @@
|
||||
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 2700;
|
||||
CREATE INDEX pg_catalog.pg_trigger_tgname_index ON pg_catalog.pg_trigger USING BTREE(tgname name_ops);
|
||||
SET LOCAL inplace_upgrade_next_system_object_oids = IUO_CATALOG, false, true, 0, 0, 0, 0;
|
||||
@ -104,6 +104,7 @@ extern Oid CreateTrigger(CreateTrigStmt* stmt, const char* queryString, Oid relO
|
||||
|
||||
extern void RemoveTriggerById(Oid trigOid);
|
||||
extern Oid get_trigger_oid(Oid relid, const char* name, bool missing_ok);
|
||||
extern Oid get_trigger_oid_b(const char* name, Oid* reloid, bool missing_ok);
|
||||
|
||||
extern void renametrig(RenameStmt* stmt);
|
||||
|
||||
|
||||
@ -152,7 +152,7 @@ begin
|
||||
insert into food(id, foodtype, remark, time_flag) values (1,'ice cream', 'sdsdsdsd', now());
|
||||
end;
|
||||
/
|
||||
ERROR: trigger "animal_trigger1" for relation "animals" already exists
|
||||
ERROR: trigger "animal_trigger1" already exists
|
||||
create trigger if not exists animal_trigger1
|
||||
after insert on animals
|
||||
for each row
|
||||
@ -160,7 +160,31 @@ begin
|
||||
insert into food(id, foodtype, remark, time_flag) values (1,'ice cream', 'sdsdsdsd', now());
|
||||
end;
|
||||
/
|
||||
NOTICE: trigger "animal_trigger1" for relation "animals" already exists,skipping
|
||||
NOTICE: trigger "animal_trigger1" already exists, skipping
|
||||
CREATE OR REPLACE FUNCTION tri_insert_func() RETURNS TRIGGER AS
|
||||
$$
|
||||
DECLARE
|
||||
BEGIN
|
||||
INSERT INTO food(id, foodtype, remark, time_flag) values (1,'ice cream', 'sdsdsdsd', now());
|
||||
RETURN NEW;
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
create trigger trigger_rename_test
|
||||
after insert on animals
|
||||
for each row
|
||||
EXECUTE PROCEDURE tri_insert_func();
|
||||
create trigger trigger_rename_test
|
||||
after insert on food
|
||||
for each row
|
||||
EXECUTE PROCEDURE tri_insert_func();
|
||||
drop trigger trigger_rename_test;
|
||||
ERROR: trigger named "trigger_rename_test" has more than one trigger, please use drop trigger on syntax
|
||||
-- drop trigger test
|
||||
drop trigger animal_trigger1;
|
||||
drop trigger animal_trigger1;
|
||||
ERROR: trigger "animal_trigger1" does not exist
|
||||
drop trigger if exists animal_trigger1;
|
||||
NOTICE: trigger "animal_trigger1" does not exist, skipping
|
||||
drop table food;
|
||||
drop table animals;
|
||||
DROP TABLE t_trigger cascade;
|
||||
@ -331,6 +355,10 @@ END;
|
||||
ERROR: bad SQLSTATE '00000'
|
||||
CONTEXT: compilation of PL/pgSQL function "test_condition_6" near line 3
|
||||
\c regression
|
||||
drop trigger animal_trigger1;
|
||||
ERROR: drop trigger without table name only support in B-format database
|
||||
drop trigger if exists animal_trigger1;
|
||||
ERROR: drop trigger without table name only support in B-format database
|
||||
drop database db_mysql;
|
||||
-- test declare condition in other compatibility
|
||||
create or replace procedure test_condition_1 as
|
||||
|
||||
@ -642,6 +642,8 @@ Command: DROP TRIGGER
|
||||
Description: remove a trigger
|
||||
Syntax:
|
||||
DROP TRIGGER [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ]
|
||||
In B compatibility also support:
|
||||
DROP TRIGGER [ IF EXISTS ] name [ CASCADE | RESTRICT ]
|
||||
|
||||
\h alter table
|
||||
Command: ALTER TABLE
|
||||
|
||||
@ -139,6 +139,31 @@ begin
|
||||
insert into food(id, foodtype, remark, time_flag) values (1,'ice cream', 'sdsdsdsd', now());
|
||||
end;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE FUNCTION tri_insert_func() RETURNS TRIGGER AS
|
||||
$$
|
||||
DECLARE
|
||||
BEGIN
|
||||
INSERT INTO food(id, foodtype, remark, time_flag) values (1,'ice cream', 'sdsdsdsd', now());
|
||||
RETURN NEW;
|
||||
END
|
||||
$$ LANGUAGE PLPGSQL;
|
||||
|
||||
create trigger trigger_rename_test
|
||||
after insert on animals
|
||||
for each row
|
||||
EXECUTE PROCEDURE tri_insert_func();
|
||||
|
||||
create trigger trigger_rename_test
|
||||
after insert on food
|
||||
for each row
|
||||
EXECUTE PROCEDURE tri_insert_func();
|
||||
|
||||
drop trigger trigger_rename_test;
|
||||
-- drop trigger test
|
||||
drop trigger animal_trigger1;
|
||||
drop trigger animal_trigger1;
|
||||
drop trigger if exists animal_trigger1;
|
||||
drop table food;
|
||||
drop table animals;
|
||||
|
||||
@ -263,6 +288,8 @@ END;
|
||||
/
|
||||
|
||||
\c regression
|
||||
drop trigger animal_trigger1;
|
||||
drop trigger if exists animal_trigger1;
|
||||
drop database db_mysql;
|
||||
|
||||
-- test declare condition in other compatibility
|
||||
|
||||
Reference in New Issue
Block a user