From 5efccc1cb43005a832776ed9158d2704fd976f8f Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 26 Jun 2017 10:43:20 -0400 Subject: [PATCH] Avoid useless "x = ANY(ARRAY[])" test for empty partition list. 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 | 57 ++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c index af07cd06aa..f8c55b1fe7 100644 --- a/src/backend/catalog/partition.c +++ b/src/backend/catalog/partition.c @@ -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; -- 2.40.0