Re: Add SPLIT PARTITION/MERGE PARTITIONS commands - Mailing list pgsql-hackers

From jian he
Subject Re: Add SPLIT PARTITION/MERGE PARTITIONS commands
Date
Msg-id CACJufxG4agcK=jupKjs+wpN8gsbhRFyZD4=H9MW6pmJAKL5edg@mail.gmail.com
Whole thread Raw
In response to Re: Add SPLIT PARTITION/MERGE PARTITIONS commands  (stephane tachoires <stephane.tachoires@gmail.com>)
Responses Re: Add SPLIT PARTITION/MERGE PARTITIONS commands
List pgsql-hackers
hi.

+/*
+ * check_two_partitions_bounds_range
+ *
+ * (function for BY RANGE partitioning)
+ *
+ * This is a helper function for check_partitions_for_split() and
+ * calculate_partition_bound_for_merge().
check_partitions_for_split does not exist in v43-0001.


+ /*
+ * Rename the existing partition with a temporary name, leaving it
+ * free for the new partition.  We don't need to care about this
+ * in the future because we're going to eventually drop the
+ * existing partition anyway.
+ */
+ RenameRelationInternal(RelationGetRelid(sameNamePartition),
+   tmpRelName, false, false);
the third argument, is_internal should set to true?


+ /* Cycle for CHECK constraints. */
+ for (ccnum = 0; ccnum < constr->num_check; ccnum++)
+ {
+ char   *ccname = constr->check[ccnum].ccname;
+ char   *ccbin = constr->check[ccnum].ccbin;
+ bool ccenforced = constr->check[ccnum].ccenforced;
+ bool ccnoinherit = constr->check[ccnum].ccnoinherit;

a partitioned table can not have NO INHERIT check constraint,
you may see StoreRelCheck.
we can add an Assert: Assert(!ccnoinherit);

+ /* Reproduce not-null constraints. */
+ if (constr->has_not_null)
+ {
+ List   *nnconstraints;
+
+ nnconstraints = RelationGetNotNullConstraints(RelationGetRelid(modelRel),
+  false, true);
as mentioned in above, partitioned table cannot have NO INHERIT constraint,
maybe we should set RelationGetNotNullConstraints last argument to false


/*
 * calculate_partition_bound_for_merge
 *
 * Calculates the bound of merged partition "spec" by using the bounds of
 * partitions to be merged.
 *
 * parent:            partitioned table
 * partNames:        names of partitions to be merged
 * partOids:        Oids of partitions to be merged
 * spec (out):        bounds specification of the merged partition
 * pstate:            pointer to ParseState struct for determine error position
 */
void
calculate_partition_bound_for_merge(Relation parent,
                                    List *partNames,
                                    List *partOids,
                                    PartitionBoundSpec *spec,
                                    ParseState *pstate)

if we are within calculate_partition_bound_for_merge,
then we at least hold AccessShareLock for all the partOids
(see transformPartitionCmdForMerge)
partNames is a list of RangeVar one to one corresponding to partOids,
then we really do not need partNames at all for error messages handling, we can
just use get_rel_name.
so we don't need to pass partNames to calculate_partition_bound_for_merge
The attached patch is a rewrite for
calculate_partition_bound_for_merge and callees.
please let me know whether this improves code readability


in RelationBuildPartitionDesc
we have the following code pattern:
    foreach(cell, inhoids)
    {
        Oid            inhrelid = lfirst_oid(cell);
        HeapTuple    tuple;
        PartitionBoundSpec *boundspec = NULL;
        /* Try fetching the tuple from the catcache, for speed. */
        tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(inhrelid));
        if (HeapTupleIsValid(tuple))
        {
            datum = SysCacheGetAttr(RELOID, tuple,
                                    Anum_pg_class_relpartbound,
                                    &isnull);
            if (!isnull)
                boundspec = stringToNode(TextDatumGetCString(datum));
            ReleaseSysCache(tuple);
        }
        if (boundspec == NULL)
        {
            pg_class = table_open(RelationRelationId, AccessShareLock);
            ScanKeyInit(&key[0],
                        Anum_pg_class_oid,
                        BTEqualStrategyNumber, F_OIDEQ,
                        ObjectIdGetDatum(inhrelid));
            scan = systable_beginscan(pg_class, ClassOidIndexId, true,
                                      NULL, 1, key);
....
}
I wonder if we should do the same in get_partition_bound_spec?
you may also see comments in RelationBuildPartitionDesc, partdesc.c line 203.

Attachment

pgsql-hackers by date:

Previous
From: Laurenz Albe
Date:
Subject: Re: CHECKPOINT unlogged data
Next
From: Nisha Moond
Date:
Subject: Re: Fix slot synchronization with two_phase decoding enabled