Skip to content

Commit dd01513

Browse files
committed
update trigger rewrited in C
1 parent ae6b49b commit dd01513

File tree

4 files changed

+165
-181
lines changed

4 files changed

+165
-181
lines changed

hash.sql

Lines changed: 0 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -164,116 +164,6 @@ END
164164
$$
165165
LANGUAGE plpgsql;
166166

167-
/*
168-
* Creates an update trigger
169-
*/
170-
CREATE OR REPLACE FUNCTION @extschema@.create_hash_update_trigger(
171-
parent_relid REGCLASS)
172-
RETURNS TEXT AS
173-
$$
174-
DECLARE
175-
func TEXT := 'CREATE OR REPLACE FUNCTION %1$s()
176-
RETURNS TRIGGER AS
177-
$body$
178-
DECLARE
179-
old_idx INTEGER; /* partition indices */
180-
new_idx INTEGER;
181-
182-
BEGIN
183-
old_idx := @extschema@.get_hash_part_idx(%9$s(OLD.%2$s), %3$s);
184-
new_idx := @extschema@.get_hash_part_idx(%9$s(NEW.%2$s), %3$s);
185-
186-
IF old_idx = new_idx THEN
187-
RETURN NEW;
188-
END IF;
189-
190-
EXECUTE format(''DELETE FROM %8$s WHERE %4$s'', old_idx)
191-
USING %5$s;
192-
193-
EXECUTE format(''INSERT INTO %8$s VALUES (%6$s)'', new_idx)
194-
USING %7$s;
195-
196-
RETURN NULL;
197-
END $body$
198-
LANGUAGE plpgsql';
199-
200-
trigger TEXT := 'CREATE TRIGGER %s
201-
BEFORE UPDATE ON %s
202-
FOR EACH ROW EXECUTE PROCEDURE %s()';
203-
204-
att_names TEXT;
205-
old_fields TEXT;
206-
new_fields TEXT;
207-
att_val_fmt TEXT;
208-
att_fmt TEXT;
209-
attr TEXT;
210-
plain_schema TEXT;
211-
plain_relname TEXT;
212-
child_relname_format TEXT;
213-
funcname TEXT;
214-
triggername TEXT;
215-
atttype REGTYPE;
216-
partitions_count INTEGER;
217-
218-
BEGIN
219-
attr := attname FROM @extschema@.pathman_config WHERE partrel = parent_relid;
220-
221-
IF attr IS NULL THEN
222-
RAISE EXCEPTION 'table "%" is not partitioned', parent_relid::TEXT;
223-
END IF;
224-
225-
SELECT string_agg(attname, ', '),
226-
string_agg('OLD.' || attname, ', '),
227-
string_agg('NEW.' || attname, ', '),
228-
string_agg('CASE WHEN NOT $' || attnum || ' IS NULL THEN ' ||
229-
attname || ' = $' || attnum || ' ' ||
230-
'ELSE ' ||
231-
attname || ' IS NULL END',
232-
' AND '),
233-
string_agg('$' || attnum, ', ')
234-
FROM pg_catalog.pg_attribute
235-
WHERE attrelid = parent_relid AND attnum > 0
236-
INTO att_names,
237-
old_fields,
238-
new_fields,
239-
att_val_fmt,
240-
att_fmt;
241-
242-
partitions_count := @extschema@.get_number_of_partitions(parent_relid);
243-
244-
/* Build trigger & trigger function's names */
245-
funcname := @extschema@.build_update_trigger_func_name(parent_relid);
246-
triggername := @extschema@.build_update_trigger_name(parent_relid);
247-
248-
/* Build partition name template */
249-
SELECT * INTO plain_schema, plain_relname
250-
FROM @extschema@.get_plain_schema_and_relname(parent_relid);
251-
252-
child_relname_format := quote_ident(plain_schema) || '.' ||
253-
quote_ident(plain_relname || '_%s');
254-
255-
/* Fetch base hash function for atttype */
256-
atttype := @extschema@.get_partition_key_type(parent_relid);
257-
258-
/* Format function definition and execute it */
259-
EXECUTE format(func, funcname, attr, partitions_count, att_val_fmt,
260-
old_fields, att_fmt, new_fields, child_relname_format,
261-
@extschema@.get_type_hash_func(atttype)::TEXT);
262-
263-
/* Create trigger on each partition */
264-
FOR num IN 0..partitions_count-1
265-
LOOP
266-
EXECUTE format(trigger,
267-
triggername,
268-
format(child_relname_format, num),
269-
funcname);
270-
END LOOP;
271-
272-
return funcname;
273-
END
274-
$$ LANGUAGE plpgsql;
275-
276-
277167
/*
278168
* Just create HASH partitions, called by create_hash_partitions().
279169
*/

init.sql

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,3 +896,43 @@ CREATE OR REPLACE FUNCTION @extschema@.invoke_on_partition_created_callback(
896896
init_callback REGPROCEDURE)
897897
RETURNS VOID AS 'pg_pathman', 'invoke_on_partition_created_callback'
898898
LANGUAGE C;
899+
900+
901+
/*
902+
* Function for update triggers
903+
*/
904+
CREATE OR REPLACE FUNCTION @extschema@.update_trigger_func()
905+
RETURNS TRIGGER AS 'pg_pathman', 'update_trigger_func'
906+
LANGUAGE C;
907+
908+
909+
/*
910+
* Creates an update trigger
911+
*/
912+
CREATE OR REPLACE FUNCTION @extschema@.create_update_trigger(
913+
IN parent_relid REGCLASS)
914+
RETURNS TEXT AS
915+
$$
916+
DECLARE
917+
trigger TEXT := 'CREATE TRIGGER %s
918+
BEFORE UPDATE ON %s
919+
FOR EACH ROW EXECUTE PROCEDURE
920+
@extschema@.update_trigger_func()';
921+
triggername TEXT;
922+
rec RECORD;
923+
924+
BEGIN
925+
triggername := @extschema@.build_update_trigger_name(parent_relid);
926+
927+
/* Create trigger on every partition */
928+
FOR rec in (SELECT * FROM pg_catalog.pg_inherits
929+
WHERE inhparent = parent_relid)
930+
LOOP
931+
EXECUTE format(trigger,
932+
triggername,
933+
rec.inhrelid::REGCLASS::TEXT);
934+
END LOOP;
935+
936+
RETURN 'update_trigger_func()';
937+
END
938+
$$ LANGUAGE plpgsql;

range.sql

Lines changed: 7 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,7 @@ END
992992
$$
993993
LANGUAGE plpgsql;
994994

995+
995996
/*
996997
* Creates an update trigger
997998
*/
@@ -1000,91 +1001,26 @@ CREATE OR REPLACE FUNCTION @extschema@.create_range_update_trigger(
10001001
RETURNS TEXT AS
10011002
$$
10021003
DECLARE
1003-
func TEXT := 'CREATE OR REPLACE FUNCTION %1$s()
1004-
RETURNS TRIGGER AS
1005-
$body$
1006-
DECLARE
1007-
old_oid Oid;
1008-
new_oid Oid;
1009-
1010-
BEGIN
1011-
old_oid := TG_RELID;
1012-
new_oid := @extschema@.find_or_create_range_partition(
1013-
''%2$s''::regclass, NEW.%3$s);
1014-
1015-
IF old_oid = new_oid THEN
1016-
RETURN NEW;
1017-
END IF;
1018-
1019-
EXECUTE format(''DELETE FROM %%s WHERE %5$s'',
1020-
old_oid::regclass::text)
1021-
USING %6$s;
1022-
1023-
EXECUTE format(''INSERT INTO %%s VALUES (%7$s)'',
1024-
new_oid::regclass::text)
1025-
USING %8$s;
1026-
1027-
RETURN NULL;
1028-
END $body$
1029-
LANGUAGE plpgsql';
1030-
1031-
trigger TEXT := 'CREATE TRIGGER %s ' ||
1032-
'BEFORE UPDATE ON %s ' ||
1033-
'FOR EACH ROW EXECUTE PROCEDURE %s()';
1034-
1004+
trigger TEXT := 'CREATE TRIGGER %s
1005+
BEFORE UPDATE ON %s
1006+
FOR EACH ROW EXECUTE PROCEDURE
1007+
@extschema@.update_trigger_func()';
10351008
triggername TEXT;
1036-
funcname TEXT;
1037-
att_names TEXT;
1038-
old_fields TEXT;
1039-
new_fields TEXT;
1040-
att_val_fmt TEXT;
1041-
att_fmt TEXT;
1042-
attr TEXT;
10431009
rec RECORD;
10441010

10451011
BEGIN
1046-
attr := attname FROM @extschema@.pathman_config WHERE partrel = parent_relid;
1047-
1048-
IF attr IS NULL THEN
1049-
RAISE EXCEPTION 'table "%" is not partitioned', parent_relid::TEXT;
1050-
END IF;
1051-
1052-
SELECT string_agg(attname, ', '),
1053-
string_agg('OLD.' || attname, ', '),
1054-
string_agg('NEW.' || attname, ', '),
1055-
string_agg('CASE WHEN NOT $' || attnum || ' IS NULL THEN ' ||
1056-
attname || ' = $' || attnum || ' ' ||
1057-
'ELSE ' ||
1058-
attname || ' IS NULL END',
1059-
' AND '),
1060-
string_agg('$' || attnum, ', ')
1061-
FROM pg_attribute
1062-
WHERE attrelid::REGCLASS = parent_relid AND attnum > 0
1063-
INTO att_names,
1064-
old_fields,
1065-
new_fields,
1066-
att_val_fmt,
1067-
att_fmt;
1068-
1069-
/* Build trigger & trigger function's names */
1070-
funcname := @extschema@.build_update_trigger_func_name(parent_relid);
10711012
triggername := @extschema@.build_update_trigger_name(parent_relid);
10721013

1073-
/* Create function for trigger */
1074-
EXECUTE format(func, funcname, parent_relid, attr, 0, att_val_fmt,
1075-
old_fields, att_fmt, new_fields);
1076-
10771014
/* Create trigger on every partition */
10781015
FOR rec in (SELECT * FROM pg_catalog.pg_inherits
10791016
WHERE inhparent = parent_relid)
10801017
LOOP
10811018
EXECUTE format(trigger,
10821019
triggername,
1083-
rec.inhrelid::REGCLASS::TEXT,
1084-
funcname);
1020+
rec.inhrelid::REGCLASS::TEXT);
10851021
END LOOP;
10861022

1087-
RETURN funcname;
1023+
RETURN 'update_trigger_func()';
10881024
END
10891025
$$ LANGUAGE plpgsql;
10901026

0 commit comments

Comments
 (0)