fix trigger

This commit is contained in:
chenbd
2024-03-28 15:53:13 +08:00
committed by yaoxin
parent 4e1310f00a
commit f2c67f12d2
4 changed files with 161 additions and 6 deletions

View File

@ -85,6 +85,11 @@
(bms_union(exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->updatedCols, \
exec_rt_fetch((relinfo)->ri_RangeTableIndex, estate)->extraUpdatedCols))
#define B_TRIGGER_INLINE_STR "inlinefunc"
#define B_TRIGGER_INLINE_LENGTH 10
#define B_TRIGGER_ID_LENGTH 8 /* for 65535 max = 5 chars, 3 '_' length total 8 */
#define B_TRIGGER_ID_MAX 65530 /* max id search time we will report error */
/* Local function prototypes */
static void ConvertTriggerToFK(CreateTrigStmt* stmt, Oid funcoid);
static void SetTriggerFlags(TriggerDesc* trigdesc, const Trigger* trigger);
@ -96,6 +101,7 @@ static HeapTuple ExecCallTriggerFunc(
static void AfterTriggerSaveEvent(EState* estate, ResultRelInfo* relinfo, uint32 event, bool row_trigger,
Oid oldPartitionOid, Oid newPartitionOid, int2 bucketid, HeapTuple oldtup, HeapTuple newtup, List* recheckIndexes,
Bitmapset* modifiedCols);
static char* rebuild_funcname_for_b_trigger(char* trigname, char* relname);
#ifdef PGXC
static bool pgxc_should_exec_triggers(
Relation rel, uint16 tgtype_event, int16 tgtype_level, int16 tgtype_timing, EState* estate = NULL);
@ -537,10 +543,10 @@ ObjectAddress CreateTrigger(CreateTrigStmt* stmt, const char* queryString, Oid r
n->isPrivate = false;
n->replace = false;
n->definer = stmt->definer;
size_t funcNameLen = strlen(stmt->trigname) + strlen(stmt->relation->relname) + strlen("__inlinefunc") + 1;
char* funcNameTmp = (char*)palloc(funcNameLen);
ret = snprintf_s(funcNameTmp,funcNameLen, funcNameLen-1, "%s_%s_inlinefunc",stmt->trigname,stmt->relation->relname);
securec_check_ss(ret, "\0", "\0");
char* trigname = pstrdup(stmt->trigname);
char* relname = pstrdup(stmt->relation->relname);
/* means we need to rebuild the function name */
char* funcNameTmp = rebuild_funcname_for_b_trigger(trigname, relname);
n->funcname = list_make1(makeString(funcNameTmp));
n->parameters = NULL;
n->returnType = makeTypeName("trigger");
@ -6319,3 +6325,54 @@ void ResetTrigShipFlag()
}
}
/* build a function name for b format trigger */
static char* rebuild_funcname_for_b_trigger(char* trigname, char* relname)
{
uint16 uid = 0;
char* funcname = NULL;
int ret = 0;
size_t funcNameLen = strlen(trigname) + strlen(relname) + B_TRIGGER_INLINE_LENGTH + B_TRIGGER_ID_LENGTH + 1;
size_t halfPos = (NAMEDATALEN - B_TRIGGER_INLINE_LENGTH - B_TRIGGER_ID_LENGTH) / 2 - 1;
/* reset overflow length */
if (funcNameLen >= NAMEDATALEN) {
/* we have to reduce name string for oversize */
if (strlen(trigname) > halfPos) {
trigname[halfPos - 1] = '\0';
}
if (strlen(relname) > halfPos) {
relname[halfPos - 1] = '\0';
}
funcNameLen = strlen(trigname) + strlen(relname) + B_TRIGGER_INLINE_LENGTH + B_TRIGGER_ID_LENGTH + 1;
}
funcname = (char*)palloc0(sizeof(char) * funcNameLen);
CatCList* catlist = NULL;
do {
if (uid++ > B_TRIGGER_ID_MAX) {
ereport(ERROR,
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
errmsg("You cannot create the trigger function because there are too many name conflicts."),
errdetail("We need to build a function internal, please rename the trigger.")));
}
ret = snprintf_s(funcname, funcNameLen, funcNameLen - 1, "%s_%s_%s_%hu", trigname, relname, B_TRIGGER_INLINE_STR, uid);
securec_check_ss(ret, "\0", "\0");
if (t_thrd.proc->workingVersionNum < 92470) {
catlist = SearchSysCacheList1(PROCNAMEARGSNSP, CStringGetDatum(funcname));
} else {
catlist = SearchSysCacheList1(PROCALLARGS, CStringGetDatum(funcname));
}
if (catlist != NULL) {
if (catlist->n_members > 0)
ReleaseSysCacheList(catlist);
else {
ReleaseSysCacheList(catlist);
break;
}
} else {
break;
}
} while (true);
return funcname;
}

View File

@ -1001,6 +1001,57 @@ end;
alter trigger testscm.animals_trigger2 on animals_scm rename to animals_trigger2_1;
drop trigger testscm.animals_trigger2_1 on animals_scm;
set search_path to public;
--bugfix for name long
drop table if exists T_ignore_case_in_dquotes_use_case0007;
NOTICE: table "t_ignore_case_in_dquotes_use_case0007" does not exist, skipping
drop table if exists T_ignore_case_in_dquotes_use_case0007_1;
NOTICE: table "t_ignore_case_in_dquotes_use_case0007_1" does not exist, skipping
create table T_ignore_case_in_dquotes_use_case0007(col1 int,col2 varchar(20));
create table T_ignore_case_in_dquotes_use_case0007_1(col1 int,col2 varchar(20));
create trigger Tri_ignore_case_in_dquotes_use_case0007
after insert on T_ignore_case_in_dquotes_use_case0007
for each row
begin
insert into T_ignore_case_in_dquotes_use_case0007_1 values (1,'INSERT');
end;
/
create trigger Tri_ignore_case_in_dquotes_use_case0008
after insert on T_ignore_case_in_dquotes_use_case0007
for each row
begin
insert into T_ignore_case_in_dquotes_use_case0007_1 values (1,'INSERT');
end;
/
create trigger Tri_ignore_case_in_dquotes_use_case0009
after insert on T_ignore_case_in_dquotes_use_case0007
for each row
begin
insert into T_ignore_case_in_dquotes_use_case0007_1 values (1,'INSERT');
end;
/
create trigger Tri_ignore_case_in_dquotes_use_case0011
after insert on T_ignore_case_in_dquotes_use_case0007
for each row
begin
insert into T_ignore_case_in_dquotes_use_case0007_1 values (1,'INSERT');
end;
/
insert into T_ignore_case_in_dquotes_use_case0007 values(11,'test');
select * from T_ignore_case_in_dquotes_use_case0007;
col1 | col2
------+------
11 | test
(1 row)
select * from T_ignore_case_in_dquotes_use_case0007_1;
col1 | col2
------+--------
1 | INSERT
1 | INSERT
1 | INSERT
1 | INSERT
(4 rows)
-- 1.5 cleanup
\c regression
drop database testdb_m;

View File

@ -61,7 +61,7 @@ insert into old_dump values(2,2);
ERROR: permission denied for relation tab_dump
DETAIL: N/A
CONTEXT: SQL statement "insert into tab_dump values(new.id,new.c1)"
PL/pgSQL function tri_dump_old_dump_inlinefunc() line 2 at SQL statement
PL/pgSQL function tri_dump_old_dump_inlinefunc_1() line 2 at SQL statement
\c test2_dump
--insert
insert into old_dump values(2,2);
@ -84,7 +84,7 @@ insert into old_dump values(2,2);
ERROR: permission denied for relation tab_dump
DETAIL: N/A
CONTEXT: SQL statement "insert into tab_dump values(new.id,new.c1)"
PL/pgSQL function tri_dump_old_dump_inlinefunc() line 2 at SQL statement
PL/pgSQL function tri_dump_old_dump_inlinefunc_1() line 2 at SQL statement
\c regression
drop database test_dump;
drop database test1_dump;

View File

@ -567,6 +567,52 @@ end;
alter trigger testscm.animals_trigger2 on animals_scm rename to animals_trigger2_1;
drop trigger testscm.animals_trigger2_1 on animals_scm;
set search_path to public;
--bugfix for name long
drop table if exists T_ignore_case_in_dquotes_use_case0007;
drop table if exists T_ignore_case_in_dquotes_use_case0007_1;
create table T_ignore_case_in_dquotes_use_case0007(col1 int,col2 varchar(20));
create table T_ignore_case_in_dquotes_use_case0007_1(col1 int,col2 varchar(20));
create trigger Tri_ignore_case_in_dquotes_use_case0007
after insert on T_ignore_case_in_dquotes_use_case0007
for each row
begin
insert into T_ignore_case_in_dquotes_use_case0007_1 values (1,'INSERT');
end;
/
create trigger Tri_ignore_case_in_dquotes_use_case0008
after insert on T_ignore_case_in_dquotes_use_case0007
for each row
begin
insert into T_ignore_case_in_dquotes_use_case0007_1 values (1,'INSERT');
end;
/
create trigger Tri_ignore_case_in_dquotes_use_case0009
after insert on T_ignore_case_in_dquotes_use_case0007
for each row
begin
insert into T_ignore_case_in_dquotes_use_case0007_1 values (1,'INSERT');
end;
/
create trigger Tri_ignore_case_in_dquotes_use_case0011
after insert on T_ignore_case_in_dquotes_use_case0007
for each row
begin
insert into T_ignore_case_in_dquotes_use_case0007_1 values (1,'INSERT');
end;
/
insert into T_ignore_case_in_dquotes_use_case0007 values(11,'test');
select * from T_ignore_case_in_dquotes_use_case0007;
select * from T_ignore_case_in_dquotes_use_case0007_1;
-- 1.5 cleanup
\c regression
drop database testdb_m;
@ -620,6 +666,7 @@ for each row
execute procedure food_insert_func();
alter trigger testscm_no.animals_trigger2 on testscm.animals_scm rename to animals_trigger2_1;
drop trigger testscm_no.animals_trigger2;
-- 2.2 cleanup
\c regression
drop database testdb;