aboutsummaryrefslogtreecommitdiff
path: root/src/backend/partitioning/partprune.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/partitioning/partprune.c')
-rw-r--r--src/backend/partitioning/partprune.c71
1 files changed, 40 insertions, 31 deletions
diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c
index a19f596d4de..0b6c627b503 100644
--- a/src/backend/partitioning/partprune.c
+++ b/src/backend/partitioning/partprune.c
@@ -200,7 +200,7 @@ static PartClauseMatchStatus match_boolean_partition_clause(Oid partopfamily,
Expr *clause,
Expr *partkey,
Expr **outconst,
- bool *noteq);
+ bool *notclause);
static void partkey_datum_from_expr(PartitionPruneContext *context,
Expr *expr, int stateidx,
Datum *value, bool *isnull);
@@ -1798,13 +1798,14 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context,
Oid partopfamily = part_scheme->partopfamily[partkeyidx],
partcoll = part_scheme->partcollation[partkeyidx];
Expr *expr;
- bool noteq;
+ bool notclause;
/*
* Recognize specially shaped clauses that match a Boolean partition key.
*/
boolmatchstatus = match_boolean_partition_clause(partopfamily, clause,
- partkey, &expr, &noteq);
+ partkey, &expr,
+ &notclause);
if (boolmatchstatus == PARTCLAUSE_MATCH_CLAUSE)
{
@@ -1818,7 +1819,7 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context,
* punt it off to gen_partprune_steps_internal() to generate pruning
* steps.
*/
- if (noteq)
+ if (notclause)
{
List *new_clauses;
List *or_clause;
@@ -1836,9 +1837,8 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context,
else
{
/*
- * We only expect match_boolean_partition_clause to match for
- * IS_NOT_TRUE and IS_NOT_FALSE. IS_NOT_UNKNOWN is not
- * supported.
+ * We only expect match_boolean_partition_clause to return
+ * PARTCLAUSE_MATCH_CLAUSE for IS_NOT_TRUE and IS_NOT_FALSE.
*/
Assert(false);
}
@@ -1876,6 +1876,15 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context,
return PARTCLAUSE_MATCH_CLAUSE;
}
+ else if (boolmatchstatus == PARTCLAUSE_MATCH_NULLNESS)
+ {
+ /*
+ * Handle IS UNKNOWN and IS NOT UNKNOWN. These just logically
+ * translate to IS NULL and IS NOT NULL.
+ */
+ *clause_is_not_null = notclause;
+ return PARTCLAUSE_MATCH_NULLNESS;
+ }
else if (IsA(clause, OpExpr) &&
list_length(((OpExpr *) clause)->args) == 2)
{
@@ -3652,22 +3661,23 @@ perform_pruning_combine_step(PartitionPruneContext *context,
* match_boolean_partition_clause
*
* If we're able to match the clause to the partition key as specially-shaped
- * boolean clause, set *outconst to a Const containing a true or false value,
- * set *noteq according to if the clause was in the "not" form, i.e. "is not
- * true" or "is not false", and return PARTCLAUSE_MATCH_CLAUSE. Returns
- * PARTCLAUSE_UNSUPPORTED if the clause is not a boolean clause or if the
- * boolean clause is unsuitable for partition pruning. Returns
- * PARTCLAUSE_NOMATCH if it's a bool quals but just does not match this
- * partition key. *outconst is set to NULL in the latter two cases.
+ * boolean clause, set *outconst to a Const containing a true, false or NULL
+ * value, set *notclause according to if the clause was in the "not" form,
+ * i.e. "IS NOT TRUE", "IS NOT FALSE" or "IS NOT UNKNOWN" and return
+ * PARTCLAUSE_MATCH_CLAUSE for "IS [NOT] (TRUE|FALSE)" clauses and
+ * PARTCLAUSE_MATCH_NULLNESS for "IS [NOT] UNKNOWN" clauses. Otherwise,
+ * return PARTCLAUSE_UNSUPPORTED if the clause cannot be used for partition
+ * pruning, and PARTCLAUSE_NOMATCH for supported clauses that do not match this
+ * 'partkey'.
*/
static PartClauseMatchStatus
match_boolean_partition_clause(Oid partopfamily, Expr *clause, Expr *partkey,
- Expr **outconst, bool *noteq)
+ Expr **outconst, bool *notclause)
{
Expr *leftop;
*outconst = NULL;
- *noteq = false;
+ *notclause = false;
/*
* Partitioning currently can only use built-in AMs, so checking for
@@ -3680,11 +3690,6 @@ match_boolean_partition_clause(Oid partopfamily, Expr *clause, Expr *partkey,
{
BooleanTest *btest = (BooleanTest *) clause;
- /* Only IS [NOT] TRUE/FALSE are any good to us */
- if (btest->booltesttype == IS_UNKNOWN ||
- btest->booltesttype == IS_NOT_UNKNOWN)
- return PARTCLAUSE_UNSUPPORTED;
-
leftop = btest->arg;
if (IsA(leftop, RelabelType))
leftop = ((RelabelType *) leftop)->arg;
@@ -3694,23 +3699,28 @@ match_boolean_partition_clause(Oid partopfamily, Expr *clause, Expr *partkey,
switch (btest->booltesttype)
{
case IS_NOT_TRUE:
- *noteq = true;
+ *notclause = true;
/* fall through */
case IS_TRUE:
*outconst = (Expr *) makeBoolConst(true, false);
- break;
+ return PARTCLAUSE_MATCH_CLAUSE;
case IS_NOT_FALSE:
- *noteq = true;
+ *notclause = true;
/* fall through */
case IS_FALSE:
*outconst = (Expr *) makeBoolConst(false, false);
- break;
+ return PARTCLAUSE_MATCH_CLAUSE;
+ case IS_NOT_UNKNOWN:
+ *notclause = true;
+ /* fall through */
+ case IS_UNKNOWN:
+ return PARTCLAUSE_MATCH_NULLNESS;
default:
return PARTCLAUSE_UNSUPPORTED;
}
}
- if (*outconst)
- return PARTCLAUSE_MATCH_CLAUSE;
+ /* does not match partition key */
+ return PARTCLAUSE_NOMATCH;
}
else
{
@@ -3726,12 +3736,11 @@ match_boolean_partition_clause(Oid partopfamily, Expr *clause, Expr *partkey,
*outconst = (Expr *) makeBoolConst(!is_not_clause, false);
else if (equal(negate_clause((Node *) leftop), partkey))
*outconst = (Expr *) makeBoolConst(is_not_clause, false);
+ else
+ return PARTCLAUSE_NOMATCH;
- if (*outconst)
- return PARTCLAUSE_MATCH_CLAUSE;
+ return PARTCLAUSE_MATCH_CLAUSE;
}
-
- return PARTCLAUSE_NOMATCH;
}
/*