]> granicus.if.org Git - postgresql/commitdiff
Avoid useless "x = ANY(ARRAY[])" test for empty partition list.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 26 Jun 2017 14:43:20 +0000 (10:43 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 26 Jun 2017 14:43:20 +0000 (10:43 -0400)
This arises in practice if the partition only admits NULL values.

Jeevan Ladhe

Discussion: https://postgr.es/m/CAOgcT0OChrN--uuqH6wG6Z8+nxnCWJ+2Q-uhnK4KOANdRRxuAw@mail.gmail.com

src/backend/catalog/partition.c

index af07cd06aa8b8163aa9a0e98479c5a54c947ce39..f8c55b1fe775186a0f5d5db1b433fe8d09c1d1af 100644 (file)
@@ -1311,6 +1311,12 @@ get_qual_for_list(PartitionKey key, PartitionBoundSpec *spec)
        List       *arrelems = NIL;
        bool            list_has_null = false;
 
+       /*
+        * Only single-column list partitioning is supported, so we are worried
+        * only about the partition key with index 0.
+        */
+       Assert(key->partnatts == 1);
+
        /* Construct Var or expression representing the partition column */
        if (key->partattrs[0] != 0)
                keyCol = (Expr *) makeVar(1,
@@ -1333,20 +1339,28 @@ get_qual_for_list(PartitionKey key, PartitionBoundSpec *spec)
                        arrelems = lappend(arrelems, copyObject(val));
        }
 
-       /* Construct an ArrayExpr for the non-null partition values */
-       arr = makeNode(ArrayExpr);
-       arr->array_typeid = !type_is_array(key->parttypid[0])
-               ? get_array_type(key->parttypid[0])
-               : key->parttypid[0];
-       arr->array_collid = key->parttypcoll[0];
-       arr->element_typeid = key->parttypid[0];
-       arr->elements = arrelems;
-       arr->multidims = false;
-       arr->location = -1;
-
-       /* Generate the main expression, i.e., keyCol = ANY (arr) */
-       opexpr = make_partition_op_expr(key, 0, BTEqualStrategyNumber,
-                                                                       keyCol, (Expr *) arr);
+       if (arrelems)
+       {
+               /* Construct an ArrayExpr for the non-null partition values */
+               arr = makeNode(ArrayExpr);
+               arr->array_typeid = !type_is_array(key->parttypid[0])
+                       ? get_array_type(key->parttypid[0])
+                       : key->parttypid[0];
+               arr->array_collid = key->parttypcoll[0];
+               arr->element_typeid = key->parttypid[0];
+               arr->elements = arrelems;
+               arr->multidims = false;
+               arr->location = -1;
+
+               /* Generate the main expression, i.e., keyCol = ANY (arr) */
+               opexpr = make_partition_op_expr(key, 0, BTEqualStrategyNumber,
+                                                                               keyCol, (Expr *) arr);
+       }
+       else
+       {
+               /* If there are no partition values, we don't need an = ANY expr */
+               opexpr = NULL;
+       }
 
        if (!list_has_null)
        {
@@ -1361,7 +1375,7 @@ get_qual_for_list(PartitionKey key, PartitionBoundSpec *spec)
                nulltest->argisrow = false;
                nulltest->location = -1;
 
-               result = list_make2(nulltest, opexpr);
+               result = opexpr ? list_make2(nulltest, opexpr) : list_make1(nulltest);
        }
        else
        {
@@ -1369,16 +1383,21 @@ get_qual_for_list(PartitionKey key, PartitionBoundSpec *spec)
                 * Gin up a "col IS NULL" test that will be OR'd with the main
                 * expression.
                 */
-               Expr       *or;
-
                nulltest = makeNode(NullTest);
                nulltest->arg = keyCol;
                nulltest->nulltesttype = IS_NULL;
                nulltest->argisrow = false;
                nulltest->location = -1;
 
-               or = makeBoolExpr(OR_EXPR, list_make2(nulltest, opexpr), -1);
-               result = list_make1(or);
+               if (opexpr)
+               {
+                       Expr       *or;
+
+                       or = makeBoolExpr(OR_EXPR, list_make2(nulltest, opexpr), -1);
+                       result = list_make1(or);
+               }
+               else
+                       result = list_make1(nulltest);
        }
 
        return result;