Skip to content

Commit 165a724

Browse files
committed
moved update_trigger_func() from pl_range_funcs.c to pl_funcs.c
1 parent ded87de commit 165a724

File tree

2 files changed

+117
-119
lines changed

2 files changed

+117
-119
lines changed

src/pl_funcs.c

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
#include "utils.h"
1313
#include "pathman.h"
1414
#include "partition_creation.h"
15+
#include "partition_filter.h"
1516
#include "relation_info.h"
1617
#include "xact_handling.h"
1718

18-
#include "access/htup_details.h"
19+
#include "access/tupconvert.h"
1920
#include "access/nbtree.h"
21+
#include "access/htup_details.h"
2022
#include "access/xact.h"
2123
#include "catalog/indexing.h"
2224
#include "catalog/pg_type.h"
@@ -32,6 +34,9 @@
3234
#include "utils/syscache.h"
3335

3436

37+
static Oid get_partition_for_key(const PartRelationInfo *prel, Datum key);
38+
39+
3540
/* Function declarations */
3641

3742
PG_FUNCTION_INFO_V1( on_partitions_created );
@@ -69,6 +74,8 @@ PG_FUNCTION_INFO_V1( check_security_policy );
6974
PG_FUNCTION_INFO_V1( debug_capture );
7075
PG_FUNCTION_INFO_V1( get_pathman_lib_version );
7176

77+
PG_FUNCTION_INFO_V1( update_trigger_func );
78+
7279

7380
/*
7481
* User context for function show_partition_list_internal().
@@ -926,3 +933,112 @@ get_pathman_lib_version(PG_FUNCTION_ARGS)
926933
{
927934
PG_RETURN_CSTRING(psprintf("%x", CURRENT_LIB_VERSION));
928935
}
936+
937+
/*
938+
* Update trigger
939+
*/
940+
Datum
941+
update_trigger_func(PG_FUNCTION_ARGS)
942+
{
943+
const PartRelationInfo *prel;
944+
PartParentSearch parent_search;
945+
Oid parent;
946+
TriggerData *trigdata = (TriggerData *) fcinfo->context;
947+
char *key_name;
948+
Datum key;
949+
bool isnull;
950+
TupleConversionMap *conversion_map;
951+
952+
TupleDesc source_tupdesc;
953+
HeapTuple source_tuple;
954+
Oid source_relid;
955+
AttrNumber source_key;
956+
957+
Relation target_rel;
958+
TupleDesc target_tupdesc;
959+
HeapTuple target_tuple;
960+
Oid target_relid;
961+
962+
/* This function can only be invoked as a trigger */
963+
if (!CALLED_AS_TRIGGER(fcinfo))
964+
elog(ERROR, "Function invoked not in a trigger context");
965+
966+
/* Make sure that trigger was fired during UPDATE command */
967+
if (!TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
968+
elog(ERROR, "This function must only be used as UPDATE trigger");
969+
970+
source_relid = trigdata->tg_relation->rd_id;
971+
source_tuple = trigdata->tg_newtuple;
972+
source_tupdesc = trigdata->tg_relation->rd_att;
973+
974+
/* Find parent relation and partitioning info */
975+
parent = get_parent_of_partition(source_relid, &parent_search);
976+
if (parent_search != PPS_ENTRY_PART_PARENT)
977+
elog(ERROR, "relation \"%s\" is not a partition",
978+
get_rel_name_or_relid(source_relid));
979+
prel = get_pathman_relation_info(parent);
980+
shout_if_prel_is_invalid(parent, prel, PT_INDIFFERENT);
981+
982+
/*
983+
* Find partitioning key attribute of source partition. Keep in mind that
984+
* there could be dropped columns in parent relation or partition and so
985+
* key attribute may have different number
986+
*/
987+
key_name = get_attname(parent, prel->attnum);
988+
source_key = get_attnum(source_relid, key_name);
989+
key = heap_getattr(source_tuple, source_key, source_tupdesc, &isnull);
990+
991+
/* Find partition it should go into */
992+
target_relid = get_partition_for_key(prel, key);
993+
994+
/* If target partition is the same then do nothing */
995+
if (target_relid == source_relid)
996+
return PointerGetDatum(source_tuple);
997+
998+
target_rel = heap_open(target_relid, RowExclusiveLock);
999+
target_tupdesc = target_rel->rd_att;
1000+
1001+
/*
1002+
* Else if it's a different partition then build a TupleConversionMap
1003+
* between original partition and new one. And then do a convertation
1004+
*/
1005+
conversion_map = convert_tuples_by_name(source_tupdesc,
1006+
target_tupdesc,
1007+
"Failed to convert tuple");
1008+
target_tuple = do_convert_tuple(source_tuple, conversion_map);
1009+
1010+
/*
1011+
* To make an UPDATE on a tuple in case when the tuple should be moved from
1012+
* one partition to another we need to perform two actions. First, remove
1013+
* old tuple from original partition and then insert updated version
1014+
* of tuple to the target partition
1015+
*/
1016+
simple_heap_delete(trigdata->tg_relation, &trigdata->tg_trigtuple->t_self);
1017+
simple_heap_insert(target_rel, target_tuple);
1018+
1019+
heap_close(target_rel, RowExclusiveLock);
1020+
PG_RETURN_VOID();
1021+
}
1022+
1023+
/*
1024+
* Returns Oid of partition corresponding to partitioning key value. Throws
1025+
* an error if no partition found
1026+
*/
1027+
static Oid
1028+
get_partition_for_key(const PartRelationInfo *prel, Datum key)
1029+
{
1030+
Oid *parts;
1031+
int nparts;
1032+
1033+
/* Search for matching partitions */
1034+
parts = find_partitions_for_value(key, prel->atttype, prel, &nparts);
1035+
1036+
if (nparts > 1)
1037+
elog(ERROR, ERR_PART_ATTR_MULTIPLE);
1038+
else if (nparts == 0)
1039+
elog(ERROR,
1040+
"There is not partition to fit partition key \"%s\"",
1041+
datum_to_cstring(key, prel->atttype));
1042+
else
1043+
return parts[0];
1044+
}

src/pl_range_funcs.c

Lines changed: 0 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,6 @@
3131
#include "utils/syscache.h"
3232

3333

34-
/* TODO */
35-
#include "commands/trigger.h"
36-
#include "access/htup_details.h"
37-
#include "access/tupconvert.h"
38-
#include "partition_filter.h"
39-
40-
4134
static char *deparse_constraint(Oid relid, Node *expr);
4235
static ArrayType *construct_infinitable_array(Bound *elems,
4336
int nelems,
@@ -61,8 +54,6 @@ static bool interval_is_trivial(Oid atttype,
6154
Datum interval,
6255
Oid interval_type);
6356

64-
static Oid get_partition_for_key(const PartRelationInfo *prel, Datum key);
65-
6657
/* Function declarations */
6758

6859
PG_FUNCTION_INFO_V1( create_single_range_partition_pl );
@@ -78,8 +69,6 @@ PG_FUNCTION_INFO_V1( merge_range_partitions );
7869
PG_FUNCTION_INFO_V1( drop_range_partition_expand_next );
7970
PG_FUNCTION_INFO_V1( validate_interval_value );
8071

81-
PG_FUNCTION_INFO_V1( update_trigger_func );
82-
8372

8473
/*
8574
* -----------------------------
@@ -1018,110 +1007,3 @@ drop_table_by_oid(Oid relid)
10181007

10191008
RemoveRelations(n);
10201009
}
1021-
1022-
/*
1023-
* Update trigger
1024-
*/
1025-
Datum
1026-
update_trigger_func(PG_FUNCTION_ARGS)
1027-
{
1028-
const PartRelationInfo *prel;
1029-
PartParentSearch parent_search;
1030-
Oid parent;
1031-
TriggerData *trigdata = (TriggerData *) fcinfo->context;
1032-
char *key_name;
1033-
Datum key;
1034-
bool isnull;
1035-
TupleConversionMap *conversion_map;
1036-
1037-
TupleDesc source_tupdesc;
1038-
HeapTuple source_tuple;
1039-
Oid source_relid;
1040-
AttrNumber source_key;
1041-
1042-
Relation target_rel;
1043-
TupleDesc target_tupdesc;
1044-
HeapTuple target_tuple;
1045-
Oid target_relid;
1046-
1047-
/* This function can only be invoked as a trigger */
1048-
if (!CALLED_AS_TRIGGER(fcinfo))
1049-
elog(ERROR, "Function invoked not in a trigger context");
1050-
1051-
/* tuple to return to executor */
1052-
if (!TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
1053-
elog(ERROR, "This function must only be used as UPDATE trigger");
1054-
1055-
source_relid = trigdata->tg_relation->rd_id;
1056-
source_tuple = trigdata->tg_newtuple;
1057-
source_tupdesc = trigdata->tg_relation->rd_att;
1058-
1059-
parent = get_parent_of_partition(source_relid, &parent_search);
1060-
if (parent_search != PPS_ENTRY_PART_PARENT)
1061-
elog(ERROR, "relation \"%s\" is not a partition",
1062-
get_rel_name_or_relid(source_relid));
1063-
1064-
prel = get_pathman_relation_info(parent);
1065-
shout_if_prel_is_invalid(parent, prel, PT_INDIFFERENT);
1066-
1067-
/*
1068-
* Find partitioning key attribute of source partition. Keep in mind that
1069-
* there could be dropped columns in parent relation or partition and so
1070-
* key attribute may have different number
1071-
*/
1072-
key_name = get_attname(parent, prel->attnum);
1073-
source_key = get_attnum(source_relid, key_name);
1074-
key = heap_getattr(source_tuple, source_key, source_tupdesc, &isnull);
1075-
1076-
/* Find partition it should go into */
1077-
target_relid = get_partition_for_key(prel, key);
1078-
1079-
/* If target partition is the same then do nothing */
1080-
if (target_relid == source_relid)
1081-
return PointerGetDatum(source_tuple);
1082-
1083-
target_rel = heap_open(target_relid, RowExclusiveLock);
1084-
target_tupdesc = target_rel->rd_att;
1085-
1086-
/*
1087-
* Else if it's a different partition then build a TupleConversionMap
1088-
* between original partition and new one. And then do a convertation
1089-
*/
1090-
conversion_map = convert_tuples_by_name(source_tupdesc,
1091-
target_tupdesc,
1092-
"Failed to convert tuple");
1093-
target_tuple = do_convert_tuple(source_tuple, conversion_map);
1094-
1095-
/* Delete old tuple from original partition */
1096-
simple_heap_delete(trigdata->tg_relation, &trigdata->tg_trigtuple->t_self);
1097-
1098-
/* Insert tuple into new partition */
1099-
simple_heap_insert(target_rel, target_tuple);
1100-
1101-
heap_close(target_rel, RowExclusiveLock);
1102-
1103-
PG_RETURN_VOID();
1104-
}
1105-
1106-
/*
1107-
* Returns Oid of partition corresponding to partitioning key value. Throws
1108-
* an error if no partition found
1109-
*/
1110-
static Oid
1111-
get_partition_for_key(const PartRelationInfo *prel, Datum key)
1112-
{
1113-
Oid *parts;
1114-
int nparts;
1115-
1116-
/* Search for matching partitions */
1117-
parts = find_partitions_for_value(key, prel->atttype, prel, &nparts);
1118-
1119-
if (nparts > 1)
1120-
elog(ERROR, ERR_PART_ATTR_MULTIPLE);
1121-
else if (nparts == 0)
1122-
elog(ERROR,
1123-
"There is not partition to fit partition key \"%s\"",
1124-
datum_to_cstring(key, prel->atttype));
1125-
else
1126-
return parts[0];
1127-
}

0 commit comments

Comments
 (0)