]> granicus.if.org Git - postgresql/commitdiff
Refactor get_partition_for_tuple a bit.
authorRobert Haas <rhaas@postgresql.org>
Fri, 8 Sep 2017 01:07:47 +0000 (21:07 -0400)
committerRobert Haas <rhaas@postgresql.org>
Fri, 8 Sep 2017 01:13:42 +0000 (21:13 -0400)
Pending patches for both default partitioning and hash partitioning
find the current coding pattern to be inconvenient.  Change it so that
we switch on the partitioning method first and then do whatever is
needed.

Amul Sul, reviewed by Jeevan Ladhe, with a few adjustments by me.

Discussion: http://postgr.es/m/CAAJ_b97mTb=dG2pv6+1ougxEVZFVnZJajW+0QHj46mEE7WsoOQ@mail.gmail.com
Discussion: http://postgr.es/m/CAOgcT0M37CAztEinpvjJc18EdHfm23fw0EG9-36Ya=+rEFUqaQ@mail.gmail.com

src/backend/catalog/partition.c

index 50162632f5ca3ab5bcc2c87a2f3bc737a713c6db..c6bd02f77dc04f2c7ce79d12ac9459162551c913 100644 (file)
@@ -1920,10 +1920,7 @@ get_partition_for_tuple(PartitionDispatch *pd,
        PartitionDispatch parent;
        Datum           values[PARTITION_MAX_KEYS];
        bool            isnull[PARTITION_MAX_KEYS];
-       int                     cur_offset,
-                               cur_index;
-       int                     i,
-                               result;
+       int                     result;
        ExprContext *ecxt = GetPerTupleExprContext(estate);
        TupleTableSlot *ecxt_scantuple_old = ecxt->ecxt_scantuple;
 
@@ -1935,6 +1932,7 @@ get_partition_for_tuple(PartitionDispatch *pd,
                PartitionDesc partdesc = parent->partdesc;
                TupleTableSlot *myslot = parent->tupslot;
                TupleConversionMap *map = parent->tupmap;
+               int             cur_index = -1;
 
                if (myslot != NULL && map != NULL)
                {
@@ -1966,61 +1964,67 @@ get_partition_for_tuple(PartitionDispatch *pd,
                ecxt->ecxt_scantuple = slot;
                FormPartitionKeyDatum(parent, slot, estate, values, isnull);
 
-               if (key->strategy == PARTITION_STRATEGY_RANGE)
+               /* Route as appropriate based on partitioning strategy. */
+               switch (key->strategy)
                {
-                       /*
-                        * Since we cannot route tuples with NULL partition keys through a
-                        * range-partitioned table, simply return that no partition exists
-                        */
-                       for (i = 0; i < key->partnatts; i++)
-                       {
-                               if (isnull[i])
+                       case PARTITION_STRATEGY_LIST:
+
+                               if (isnull[0])
                                {
-                                       *failed_at = parent;
-                                       *failed_slot = slot;
-                                       result = -1;
-                                       goto error_exit;
+                                       if (partition_bound_accepts_nulls(partdesc->boundinfo))
+                                               cur_index = partdesc->boundinfo->null_index;
                                }
-                       }
-               }
-
-               /*
-                * A null partition key is only acceptable if null-accepting list
-                * partition exists.
-                */
-               cur_index = -1;
-               if (isnull[0] && partition_bound_accepts_nulls(partdesc->boundinfo))
-                       cur_index = partdesc->boundinfo->null_index;
-               else if (!isnull[0])
-               {
-                       /* Else bsearch in partdesc->boundinfo */
-                       bool            equal = false;
-
-                       cur_offset = partition_bound_bsearch(key, partdesc->boundinfo,
-                                                                                                values, false, &equal);
-                       switch (key->strategy)
-                       {
-                               case PARTITION_STRATEGY_LIST:
+                               else
+                               {
+                                       bool            equal = false;
+                                       int                     cur_offset;
+
+                                       cur_offset = partition_bound_bsearch(key,
+                                                                                                                partdesc->boundinfo,
+                                                                                                                values,
+                                                                                                                false,
+                                                                                                                &equal);
                                        if (cur_offset >= 0 && equal)
                                                cur_index = partdesc->boundinfo->indexes[cur_offset];
-                                       else
-                                               cur_index = -1;
-                                       break;
+                               }
+                               break;
+
+                       case PARTITION_STRATEGY_RANGE:
+                               {
+                                       bool            equal = false;
+                                       int                     cur_offset;
+                                       int                     i;
+
+                                       /* No range includes NULL. */
+                                       for (i = 0; i < key->partnatts; i++)
+                                       {
+                                               if (isnull[i])
+                                               {
+                                                       *failed_at = parent;
+                                                       *failed_slot = slot;
+                                                       result = -1;
+                                                       goto error_exit;
+                                               }
+                                       }
 
-                               case PARTITION_STRATEGY_RANGE:
+                                       cur_offset = partition_bound_bsearch(key,
+                                                                                                                partdesc->boundinfo,
+                                                                                                                values,
+                                                                                                                false,
+                                                                                                                &equal);
 
                                        /*
-                                        * Offset returned is such that the bound at offset is
-                                        * found to be less or equal with the tuple. So, the bound
-                                        * at offset+1 would be the upper bound.
+                                        * The offset returned is such that the bound at cur_offset
+                                        * is less than or equal to the tuple value, so the bound
+                                        * at offset+1 is the upper bound.
                                         */
                                        cur_index = partdesc->boundinfo->indexes[cur_offset + 1];
-                                       break;
+                               }
+                               break;
 
-                               default:
-                                       elog(ERROR, "unexpected partition strategy: %d",
-                                                (int) key->strategy);
-                       }
+                       default:
+                               elog(ERROR, "unexpected partition strategy: %d",
+                                        (int) key->strategy);
                }
 
                /*