Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4511f8b

Browse files
committed
fix detach_range_partition()
1 parent bd1085a commit 4511f8b

File tree

6 files changed

+57
-153
lines changed

6 files changed

+57
-153
lines changed

init.sql

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,7 @@ RETURNS BOOLEAN AS 'pg_pathman', 'is_operator_supported'
930930
LANGUAGE C;
931931

932932
/*
933-
* Referential integrity triggers
933+
* Referential integrity funcs and triggers
934934
*/
935935
CREATE OR REPLACE FUNCTION @extschema@.create_fk(
936936
fk_table REGCLASS,
@@ -939,6 +939,12 @@ CREATE OR REPLACE FUNCTION @extschema@.create_fk(
939939
RETURNS VOID AS 'pg_pathman', 'create_fk_constraint'
940940
LANGUAGE C STRICT;
941941

942+
CREATE OR REPLACE FUNCTION @extschema@.prepare_partition_drop(
943+
parent REGCLASS,
944+
partition REGCLASS)
945+
RETURNS VOID AS 'pg_pathman', 'prepare_partition_drop'
946+
LANGUAGE C STRICT;
947+
942948
CREATE OR REPLACE FUNCTION @extschema@.pathman_fkey_check_ins()
943949
RETURNS TRIGGER AS 'pg_pathman', 'pathman_fkey_check_ins'
944950
LANGUAGE C STRICT;

range.sql

Lines changed: 2 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,6 @@ CREATE OR REPLACE FUNCTION @extschema@.generate_bounds(
489489
RETURNS ANYARRAY AS 'pg_pathman', 'generate_bounds'
490490
LANGUAGE C;
491491

492-
493492
/*
494493
* Split RANGE partition
495494
*/
@@ -501,98 +500,6 @@ CREATE OR REPLACE FUNCTION @extschema@.split_range_partition(
501500
RETURNS REGCLASS AS 'pg_pathman', 'split_range_partitions'
502501
LANGUAGE C;
503502

504-
505-
CREATE OR REPLACE FUNCTION @extschema@._split_range_partition(
506-
partition_relid REGCLASS,
507-
split_value ANYELEMENT,
508-
partition_name TEXT DEFAULT NULL,
509-
tablespace TEXT DEFAULT NULL,
510-
OUT p_range ANYARRAY)
511-
RETURNS ANYARRAY AS
512-
$$
513-
DECLARE
514-
v_parent REGCLASS;
515-
v_attname TEXT;
516-
v_atttype REGTYPE;
517-
v_cond TEXT;
518-
v_new_partition TEXT;
519-
v_part_type INTEGER;
520-
v_check_name TEXT;
521-
522-
BEGIN
523-
v_parent = @extschema@.get_parent_of_partition(partition_relid);
524-
525-
/* Acquire lock on parent */
526-
PERFORM @extschema@.lock_partitioned_relation(v_parent);
527-
528-
/* Acquire data modification lock (prevent further modifications) */
529-
PERFORM @extschema@.prevent_relation_modification(partition_relid);
530-
531-
v_atttype = @extschema@.get_partition_key_type(v_parent);
532-
533-
SELECT attname, parttype
534-
FROM @extschema@.pathman_config
535-
WHERE partrel = v_parent
536-
INTO v_attname, v_part_type;
537-
538-
/* Check if this is a RANGE partition */
539-
IF v_part_type != 2 THEN
540-
RAISE EXCEPTION '"%" is not a RANGE partition', partition_relid::TEXT;
541-
END IF;
542-
543-
/* Get partition values range */
544-
EXECUTE format('SELECT @extschema@.get_part_range($1, NULL::%s)',
545-
@extschema@.get_base_type(v_atttype)::TEXT)
546-
USING partition_relid
547-
INTO p_range;
548-
549-
IF p_range IS NULL THEN
550-
RAISE EXCEPTION 'could not find specified partition';
551-
END IF;
552-
553-
/* Check if value fit into the range */
554-
IF p_range[1] > split_value OR p_range[2] <= split_value
555-
THEN
556-
RAISE EXCEPTION 'specified value does not fit into the range [%, %)',
557-
p_range[1], p_range[2];
558-
END IF;
559-
560-
/* Create new partition */
561-
v_new_partition := @extschema@.create_single_range_partition(v_parent,
562-
split_value,
563-
p_range[2],
564-
partition_name,
565-
tablespace);
566-
567-
/* Copy data */
568-
v_cond := @extschema@.build_range_condition(v_new_partition::regclass,
569-
v_attname, split_value, p_range[2]);
570-
EXECUTE format('WITH part_data AS (DELETE FROM %s WHERE %s RETURNING *)
571-
INSERT INTO %s SELECT * FROM part_data',
572-
partition_relid::TEXT,
573-
v_cond,
574-
v_new_partition);
575-
576-
/* Alter original partition */
577-
v_cond := @extschema@.build_range_condition(partition_relid::regclass,
578-
v_attname, p_range[1], split_value);
579-
v_check_name := @extschema@.build_check_constraint_name(partition_relid, v_attname);
580-
581-
EXECUTE format('ALTER TABLE %s DROP CONSTRAINT %s',
582-
partition_relid::TEXT,
583-
v_check_name);
584-
585-
EXECUTE format('ALTER TABLE %s ADD CONSTRAINT %s CHECK (%s)',
586-
partition_relid::TEXT,
587-
v_check_name,
588-
v_cond);
589-
590-
/* Tell backend to reload configuration */
591-
PERFORM @extschema@.on_update_partitions(v_parent);
592-
END
593-
$$
594-
LANGUAGE plpgsql;
595-
596503
/*
597504
* Merge multiple partitions. All data will be copied to the first one.
598505
* The rest of partitions will be dropped.
@@ -1088,6 +995,8 @@ BEGIN
1088995
RAISE EXCEPTION 'table "%" is not partitioned', parent_relid::TEXT;
1089996
END IF;
1090997

998+
PERFORM @extschema@.prepare_partition_drop(parent_relid, partition_relid);
999+
10911000
/* Remove inheritance */
10921001
EXECUTE format('ALTER TABLE %s NO INHERIT %s',
10931002
partition_relid::TEXT,

src/include/ref_integrity.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ HeapTuple get_index_for_key(Relation rel, AttrNumber attnum, Oid *index_id);
1414
List *get_ri_triggers_list(Oid relid, Oid constr);
1515
void ri_preparePartitionDrop(Oid parent,
1616
Relation partition,
17-
bool check_referencies);
17+
bool check_references);
1818
void ri_checkReferences(Relation partition, Oid constraintOid);
1919
void enable_ri_triggers(void);
2020
void disable_ri_triggers(void);

src/pl_funcs.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "pathman.h"
1616
#include "partition_creation.h"
1717
#include "partition_filter.h"
18+
#include "ref_integrity.h"
1819
#include "relation_info.h"
1920
#include "xact_handling.h"
2021

@@ -84,6 +85,7 @@ PG_FUNCTION_INFO_V1( create_update_triggers );
8485
PG_FUNCTION_INFO_V1( update_trigger_func );
8586
PG_FUNCTION_INFO_V1( create_single_update_trigger );
8687
PG_FUNCTION_INFO_V1( is_update_trigger_enabled );
88+
PG_FUNCTION_INFO_V1( prepare_partition_drop );
8789

8890

8991
/*
@@ -1152,3 +1154,17 @@ is_update_trigger_enabled(PG_FUNCTION_ARGS)
11521154
{
11531155
PG_RETURN_BOOL(is_update_trigger_enabled_internal(PG_GETARG_OID(0)));
11541156
}
1157+
1158+
Datum
1159+
prepare_partition_drop(PG_FUNCTION_ARGS)
1160+
{
1161+
Oid parent = PG_GETARG_OID(0);
1162+
Oid partition = PG_GETARG_OID(1);
1163+
Relation partition_rel;
1164+
1165+
partition_rel = heap_open(partition, AccessExclusiveLock);
1166+
ri_preparePartitionDrop(parent, partition_rel, true);
1167+
heap_close(partition_rel, AccessExclusiveLock);
1168+
1169+
PG_RETURN_VOID();
1170+
}

src/pl_range_funcs.c

Lines changed: 29 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
#include "init.h"
1212
#include "pathman.h"
1313
#include "partition_creation.h"
14+
#include "ref_integrity.h"
1415
#include "relation_info.h"
1516
#include "utils.h"
1617
#include "xact_handling.h"
17-
#include "ref_integrity.h"
1818

1919
#include "access/xact.h"
2020
#include "catalog/namespace.h"
@@ -40,7 +40,7 @@ static ArrayType *construct_infinitable_array(Bound *elems,
4040
bool elmbyval,
4141
char elmalign);
4242
static void check_range_adjacence(Oid cmp_proc, Oid collid, List *ranges);
43-
static char *build_range_condition_internal(Oid relid, const char *attname,
43+
static char *build_range_condition_internal(Oid relid, char *attname,
4444
const Bound *min, const Bound *max,
4545
Oid bounds_type);
4646
static void merge_range_partitions_internal(Oid parent,
@@ -380,7 +380,7 @@ Datum
380380
build_range_condition(PG_FUNCTION_ARGS)
381381
{
382382
Oid relid = PG_GETARG_OID(0);
383-
const char *attname = TextDatumGetCString(PG_GETARG_TEXT_P(1));
383+
char *attname = TextDatumGetCString(PG_GETARG_TEXT_P(1));
384384

385385
Bound min,
386386
max;
@@ -395,19 +395,13 @@ build_range_condition(PG_FUNCTION_ARGS)
395395
MakeBoundInf(PLUS_INFINITY) :
396396
MakeBound(PG_GETARG_DATUM(3));
397397

398-
// con = build_range_check_constraint(relid, text_to_cstring(attname),
399-
// &min, &max,
400-
// bounds_type);
401-
402-
// result = deparse_constraint(relid, con->raw_expr);
403398
result = build_range_condition_internal(relid, attname,
404399
&min, &max, bounds_type);
405-
406400
PG_RETURN_TEXT_P(cstring_to_text(result));
407401
}
408402

409403
static char *
410-
build_range_condition_internal(Oid relid, const char *attname,
404+
build_range_condition_internal(Oid relid, char *attname,
411405
const Bound *min, const Bound *max,
412406
Oid bounds_type)
413407
{
@@ -610,33 +604,30 @@ merge_range_partitions_internal(Oid parent, Oid *parts, uint32 nparts)
610604
Datum
611605
split_range_partitions(PG_FUNCTION_ARGS)
612606
{
613-
Oid partition = PG_GETARG_OID(0);
614-
Datum value = PG_GETARG_DATUM(1);
615-
Oid value_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
616-
// char *new_name = TextDatumGetCString(PG_GETARG_TEXT_P(2));
617-
Oid new_partition;
618-
// char *new_partition_name = NULL;
607+
Oid partition = PG_GETARG_OID(0);
608+
Datum value = PG_GETARG_DATUM(1);
609+
Oid value_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
610+
Oid new_partition;
619611

620-
/* Optional: name & tablespace */
621-
RangeVar *new_partition_rv = NULL;
622-
char *new_partition_ts = NULL;
612+
/* Optional: name & tablespace */
613+
RangeVar *new_partition_rv = NULL;
614+
char *new_partition_ts = NULL;
623615

624616
const PartRelationInfo *prel;
625-
Oid parent;
626-
char *attname;
627-
RangeEntry *rentry = NULL;
628-
FmgrInfo cmp_finfo;
629-
Bound fake_value_bound;
630-
RangeEntry *ranges;
631-
Bound min, max;
632-
633-
List *ri_constr, *ri_relids;
634-
char *bound;
635-
int i;
636-
PartParentSearch parent_search;
617+
Oid parent;
618+
char *attname;
619+
RangeEntry *rentry = NULL;
620+
FmgrInfo cmp_finfo;
621+
Bound fake_value_bound;
622+
RangeEntry *ranges;
623+
Bound min, max;
624+
625+
List *ri_constr,
626+
*ri_relids;
627+
char *bound;
628+
int i;
629+
PartParentSearch parent_search;
637630

638-
Relation partition_rel;
639-
Constraint *check;
640631
AttrNumber attnum;
641632
char *query;
642633

@@ -648,8 +639,6 @@ split_range_partitions(PG_FUNCTION_ARGS)
648639
partition_name = PG_GETARG_TEXT_P(2);
649640
qualified_name = textToQualifiedNameList(partition_name);
650641
new_partition_rv = makeRangeVarFromNameList(qualified_name);
651-
652-
// new_partition_rv = TextDatumGetCString(PG_GETARG_TEXT_P(2));
653642
}
654643

655644
if (!PG_ARGISNULL(3))
@@ -700,7 +689,6 @@ split_range_partitions(PG_FUNCTION_ARGS)
700689
pathman_get_fkeys(parent, &ri_constr, &ri_relids);
701690

702691
/* Create new partition */
703-
/* TODO: partition name and tablespace instead of NULL */
704692
new_partition = create_single_range_partition_internal(parent,
705693
&fake_value_bound,
706694
&max,
@@ -714,10 +702,10 @@ split_range_partitions(PG_FUNCTION_ARGS)
714702

715703
/* Copy data */
716704
bound = build_range_condition_internal(partition,
717-
attname,
718-
&fake_value_bound,
719-
&max,
720-
prel->atttype);
705+
attname,
706+
&fake_value_bound,
707+
&max,
708+
prel->atttype);
721709

722710
if (SPI_connect() != SPI_OK_CONNECT)
723711
elog(ERROR, "could not connect using SPI");
@@ -741,21 +729,6 @@ split_range_partitions(PG_FUNCTION_ARGS)
741729
attname, attnum, prel->atttype,
742730
&min, &fake_value_bound);
743731

744-
// drop_check_constraint(partition, attnum);
745-
// check = build_range_check_constraint(partition,
746-
// attname,
747-
// &min,
748-
// &fake_value_bound,
749-
// prel->atttype);
750-
751-
// /* TODO: think about locking */
752-
// partition_rel = heap_open(partition, ExclusiveLock);
753-
754-
// AddRelationNewConstraints(partition_rel, NIL,
755-
// list_make1(check),
756-
// false, true, true);
757-
// heap_close(partition_rel, AccessExclusiveLock);
758-
759732
/* get_pathman_relation_info() will refresh this entry */
760733
invalidate_pathman_relation_info(parent, NULL);
761734

@@ -824,7 +797,7 @@ drop_range_partition_expand_next(PG_FUNCTION_ARGS)
824797
&next->max);
825798
}
826799

827-
/* Perform checks and preparations regarding to reference integrity */
800+
/* Perform preparations regarding reference integrity */
828801
ri_preparePartitionDrop(parent, rel, false);
829802
CommandCounterIncrement();
830803

src/ref_integrity.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1900,7 +1900,7 @@ get_ri_triggers_list(Oid relid, Oid constr)
19001900
void
19011901
ri_preparePartitionDrop(Oid parent,
19021902
Relation partition,
1903-
bool check_referencies)
1903+
bool check_references)
19041904
{
19051905
List *ri_constr;
19061906
List *ri_refrelids;
@@ -1924,7 +1924,7 @@ ri_preparePartitionDrop(Oid parent,
19241924
shout_if_prel_is_invalid(parent, prel, PT_INDIFFERENT);
19251925

19261926
/* Check if there are references in FK table */
1927-
if (check_referencies)
1927+
if (check_references)
19281928
ri_checkReferences(partition, constr);
19291929

19301930
/*

0 commit comments

Comments
 (0)