Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit73b8a41

Browse files
committed
trigger creation rewrited in C
1 parent165a724 commit73b8a41

File tree

5 files changed

+167
-51
lines changed

5 files changed

+167
-51
lines changed

‎init.sql

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -560,31 +560,9 @@ LANGUAGE C;
560560
/*
561561
* Creates an update trigger
562562
*/
563-
CREATEOR REPLACE FUNCTION @extschema@.create_update_triggers(
564-
IN parent_relidREGCLASS)
565-
RETURNS VOIDAS
566-
$$
567-
DECLARE
568-
triggerTEXT :='CREATE TRIGGER %s
569-
BEFORE UPDATE ON %s
570-
FOR EACH ROW EXECUTE PROCEDURE
571-
@extschema@.update_trigger_func()';
572-
triggernameTEXT;
573-
recRECORD;
574-
575-
BEGIN
576-
triggername := @extschema@.build_update_trigger_name(parent_relid);
577-
578-
/* Create trigger on every partition*/
579-
FOR recin (SELECT*FROMpg_catalog.pg_inherits
580-
WHERE inhparent= parent_relid)
581-
LOOP
582-
EXECUTE format(trigger,
583-
triggername,
584-
rec.inhrelid::REGCLASS::TEXT);
585-
END LOOP;
586-
END
587-
$$ LANGUAGE plpgsql;
563+
CREATEOR REPLACE FUNCTION @extschema@.create_update_triggers(parent_relid REGCLASS)
564+
RETURNS VOIDAS'pg_pathman','create_update_triggers'
565+
LANGUAGE C;
588566

589567
/*
590568
* Drop triggers

‎src/partition_creation.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,6 @@ static Constraint *make_constraint_common(char *name, Node *raw_expr);
7777
staticValuemake_string_value_struct(char*str);
7878
staticValuemake_int_value_struct(intint_val);
7979

80-
staticRangeVar*makeRangeVarFromRelid(Oidrelid);
81-
8280

8381
/*
8482
* ---------------------------------------
@@ -1402,15 +1400,6 @@ make_int_value_struct(int int_val)
14021400
returnval;
14031401
}
14041402

1405-
staticRangeVar*
1406-
makeRangeVarFromRelid(Oidrelid)
1407-
{
1408-
char*relname=get_rel_name(relid);
1409-
char*namespace=get_namespace_name(get_rel_namespace(relid));
1410-
1411-
returnmakeRangeVar(namespace,relname,-1);
1412-
}
1413-
14141403

14151404
/*
14161405
* ---------------------

‎src/pl_funcs.c

Lines changed: 133 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@
2121
#include"access/htup_details.h"
2222
#include"access/xact.h"
2323
#include"catalog/indexing.h"
24+
#include"catalog/pg_trigger.h"
2425
#include"catalog/pg_type.h"
2526
#include"commands/tablespace.h"
2627
#include"commands/trigger.h"
2728
#include"funcapi.h"
2829
#include"miscadmin.h"
2930
#include"utils/builtins.h"
31+
#include"utils/fmgroids.h"
3032
#include"utils/inval.h"
3133
#include"utils/jsonb.h"
3234
#include"utils/snapmgr.h"
@@ -35,6 +37,9 @@
3537

3638

3739
staticOidget_partition_for_key(constPartRelationInfo*prel,Datumkey);
40+
staticvoidcreate_single_update_trigger_internal(Oidrelid,
41+
constchar*attname);
42+
staticboolupdate_trigger_exists(Oidrelid,char*trigname);
3843

3944

4045
/* Function declarations */
@@ -74,7 +79,9 @@ PG_FUNCTION_INFO_V1( check_security_policy );
7479
PG_FUNCTION_INFO_V1(debug_capture );
7580
PG_FUNCTION_INFO_V1(get_pathman_lib_version );
7681

82+
PG_FUNCTION_INFO_V1(create_update_triggers );
7783
PG_FUNCTION_INFO_V1(update_trigger_func );
84+
PG_FUNCTION_INFO_V1(create_single_update_trigger );
7885

7986

8087
/*
@@ -97,16 +104,6 @@ static void on_partitions_updated_internal(Oid partitioned_table, bool add_callb
97104
staticvoidon_partitions_removed_internal(Oidpartitioned_table,booladd_callbacks);
98105

99106

100-
/*
101-
* Extracted common check.
102-
*/
103-
staticbool
104-
check_relation_exists(Oidrelid)
105-
{
106-
returnget_rel_type_id(relid)!=InvalidOid;
107-
}
108-
109-
110107
/*
111108
* ----------------------------
112109
* Partition events callbacks
@@ -543,11 +540,7 @@ build_update_trigger_name(PG_FUNCTION_ARGS)
543540
Oidrelid=PG_GETARG_OID(0);
544541
constchar*result;/* trigger's name can't be qualified */
545542

546-
/* Check that relation exists */
547-
if (!check_relation_exists(relid))
548-
elog(ERROR,"Invalid relation %u",relid);
549-
550-
result=quote_identifier(psprintf("%s_upd_trig",get_rel_name(relid)));
543+
result=build_update_trigger_name_internal(relid);
551544

552545
PG_RETURN_TEXT_P(cstring_to_text(result));
553546
}
@@ -1020,6 +1013,7 @@ update_trigger_func(PG_FUNCTION_ARGS)
10201013
PG_RETURN_VOID();
10211014
}
10221015

1016+
10231017
/*
10241018
* Returns Oid of partition corresponding to partitioning key value. Throws
10251019
* an error if no partition found
@@ -1042,3 +1036,127 @@ get_partition_for_key(const PartRelationInfo *prel, Datum key)
10421036
else
10431037
returnparts[0];
10441038
}
1039+
1040+
/*
1041+
* Create UPDATE triggers for all partitions
1042+
*/
1043+
Datum
1044+
create_update_triggers(PG_FUNCTION_ARGS)
1045+
{
1046+
constPartRelationInfo*prel;
1047+
Oidparent=PG_GETARG_OID(0);
1048+
Oid*children;
1049+
char*attname,
1050+
*trigname;
1051+
inti;
1052+
1053+
prel=get_pathman_relation_info(parent);
1054+
shout_if_prel_is_invalid(parent,prel,PT_INDIFFERENT);
1055+
1056+
attname=get_attname(prel->key,prel->attnum);
1057+
children=PrelGetChildrenArray(prel);
1058+
trigname=build_update_trigger_name_internal(parent);
1059+
1060+
/* Create triggers for each partition */
1061+
for (i=0;i<PrelChildrenCount(prel);i++)
1062+
{
1063+
if (update_trigger_exists(children[i],trigname))
1064+
ereport(ERROR,
1065+
(errcode(ERRCODE_DUPLICATE_OBJECT),
1066+
errmsg("trigger \"%s\" for relation \"%s\" already exists",
1067+
trigname,get_rel_name_or_relid(children[i]))));
1068+
1069+
create_single_update_trigger_internal(children[i],attname);
1070+
}
1071+
1072+
PG_RETURN_VOID();
1073+
}
1074+
1075+
staticbool
1076+
update_trigger_exists(Oidrelid,char*trigname)
1077+
{
1078+
boolres= false;
1079+
Relationtgrel;
1080+
SysScanDesctgscan;
1081+
ScanKeyDatakey;
1082+
HeapTupletuple;
1083+
1084+
tgrel=heap_open(TriggerRelationId,RowExclusiveLock);
1085+
1086+
ScanKeyInit(&key,
1087+
Anum_pg_trigger_tgrelid,
1088+
BTEqualStrategyNumber,F_OIDEQ,
1089+
ObjectIdGetDatum(relid));
1090+
tgscan=systable_beginscan(tgrel,TriggerRelidNameIndexId, true,
1091+
NULL,1,&key);
1092+
while (HeapTupleIsValid(tuple=systable_getnext(tgscan)))
1093+
{
1094+
Form_pg_triggerpg_trigger= (Form_pg_trigger)GETSTRUCT(tuple);
1095+
1096+
if (namestrcmp(&(pg_trigger->tgname),trigname)==0)
1097+
{
1098+
res= true;
1099+
break;
1100+
}
1101+
}
1102+
systable_endscan(tgscan);
1103+
heap_close(tgrel,RowExclusiveLock);
1104+
1105+
returnres;
1106+
}
1107+
1108+
/*
1109+
* Create an UPDATE trigger for partition
1110+
*/
1111+
Datum
1112+
create_single_update_trigger(PG_FUNCTION_ARGS)
1113+
{
1114+
constPartRelationInfo*prel;
1115+
Oidpartition=PG_GETARG_OID(0);
1116+
Oidparent;
1117+
PartParentSearchparent_search;
1118+
char*attname;
1119+
1120+
/* Get parent's Oid */
1121+
parent=get_parent_of_partition(partition,&parent_search);
1122+
if (parent_search!=PPS_ENTRY_PART_PARENT)
1123+
elog(ERROR,"\"%s\" is not a partition",
1124+
get_rel_name_or_relid(partition));
1125+
1126+
/* Determine partitioning key name */
1127+
prel=get_pathman_relation_info(parent);
1128+
shout_if_prel_is_invalid(partition,prel,PT_INDIFFERENT);
1129+
attname=get_attname(prel->key,prel->attnum);
1130+
1131+
create_single_update_trigger_internal(partition,attname);
1132+
1133+
PG_RETURN_VOID();
1134+
}
1135+
1136+
staticvoid
1137+
create_single_update_trigger_internal(Oidrelid,constchar*attname)
1138+
{
1139+
CreateTrigStmt*stmt;
1140+
List*func;
1141+
1142+
func=list_make2(makeString(get_namespace_name(get_pathman_schema())),
1143+
makeString("update_trigger_func"));
1144+
1145+
stmt=makeNode(CreateTrigStmt);
1146+
stmt->trigname=build_update_trigger_name_internal(relid);
1147+
stmt->relation=makeRangeVarFromRelid(relid);
1148+
stmt->funcname=func;
1149+
stmt->args=NIL;
1150+
stmt->row= true;
1151+
stmt->timing=TRIGGER_TYPE_BEFORE;
1152+
stmt->events=TRIGGER_TYPE_UPDATE;
1153+
stmt->columns=list_make1(makeString((char*)attname));
1154+
stmt->whenClause=NULL;
1155+
stmt->isconstraint= false;
1156+
stmt->deferrable= false;
1157+
stmt->initdeferred= false;
1158+
stmt->constrrel=NULL;
1159+
1160+
(void)CreateTrigger(stmt,NULL,InvalidOid,InvalidOid,
1161+
InvalidOid,InvalidOid, false);
1162+
}

‎src/utils.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,18 @@ check_security_policy_internal(Oid relid, Oid role)
103103
return true;
104104
}
105105

106+
/*
107+
* Create an update trigger name
108+
*/
109+
char*
110+
build_update_trigger_name_internal(Oidrelid)
111+
{
112+
/* Check that relation exists */
113+
if (!check_relation_exists(relid))
114+
elog(ERROR,"Invalid relation %u",relid);
106115

116+
return (char*)quote_identifier(psprintf("%s_upd_trig",get_rel_name(relid)));
117+
}
107118

108119
/*
109120
* Return pg_pathman schema's Oid or InvalidOid if that's not possible.
@@ -255,6 +266,23 @@ get_rel_persistence(Oid relid)
255266
}
256267
#endif
257268

269+
RangeVar*
270+
makeRangeVarFromRelid(Oidrelid)
271+
{
272+
char*relname=get_rel_name(relid);
273+
char*namespace=get_namespace_name(get_rel_namespace(relid));
274+
275+
returnmakeRangeVar(namespace,relname,-1);
276+
}
277+
278+
/*
279+
* Extracted common check.
280+
*/
281+
bool
282+
check_relation_exists(Oidrelid)
283+
{
284+
returnget_rel_type_id(relid)!=InvalidOid;
285+
}
258286

259287

260288
/*

‎src/utils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
boolclause_contains_params(Node*clause);
2828
boolis_date_type_internal(Oidtypid);
2929
boolcheck_security_policy_internal(Oidrelid,Oidrole);
30+
char*build_update_trigger_name_internal(Oidrelid);
3031

3132
/*
3233
* Misc.
@@ -43,6 +44,8 @@ Oid get_attribute_type(Oid relid, const char *attname, bool missing_ok);
4344
#ifPG_VERSION_NUM<90600
4445
charget_rel_persistence(Oidrelid);
4546
#endif
47+
RangeVar*makeRangeVarFromRelid(Oidrelid);
48+
boolcheck_relation_exists(Oidrelid);
4649

4750
/*
4851
* Operator-related stuff.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp