summaryrefslogtreecommitdiff
path: root/src/backend/optimizer
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2010-01-01 23:03:10 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2010-01-01 23:03:10 +0000
commit7839d35991f1c79a291e67635d5f4c5750c16e9b (patch)
tree98f44976c68f2ac0b707f4efcc8f3949cdc9ac68 /src/backend/optimizer
parent29c4ad98293e3c5cb3fcdd413a3f4904efff8762 (diff)
Add an "argisrow" field to NullTest nodes, following a plan made way back in
8.2beta but never carried out. This avoids repetitive tests of whether the argument is of scalar or composite type. Also, be a bit more paranoid about composite arguments in some places where we previously weren't checking.
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r--src/backend/optimizer/path/indxpath.c5
-rw-r--r--src/backend/optimizer/plan/planagg.c5
-rw-r--r--src/backend/optimizer/util/clauses.c12
-rw-r--r--src/backend/optimizer/util/plancat.c3
-rw-r--r--src/backend/optimizer/util/predtest.c10
5 files changed, 22 insertions, 13 deletions
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 456a5b9be48..c69dd8686dd 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.243 2010/01/01 21:53:49 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.244 2010/01/01 23:03:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1256,7 +1256,8 @@ match_clause_to_indexcol(IndexOptInfo *index,
{
NullTest *nt = (NullTest *) clause;
- if (match_index_to_operand((Node *) nt->arg, indexcol, index))
+ if (!nt->argisrow &&
+ match_index_to_operand((Node *) nt->arg, indexcol, index))
return true;
return false;
}
diff --git a/src/backend/optimizer/plan/planagg.c b/src/backend/optimizer/plan/planagg.c
index a32a06fc28d..aa841ccff56 100644
--- a/src/backend/optimizer/plan/planagg.c
+++ b/src/backend/optimizer/plan/planagg.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.48 2010/01/01 21:53:49 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.49 2010/01/01 23:03:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -308,6 +308,9 @@ build_minmax_path(PlannerInfo *root, RelOptInfo *rel, MinMaxAggInfo *info)
ntest = makeNode(NullTest);
ntest->nulltesttype = IS_NOT_NULL;
ntest->arg = copyObject(info->target);
+ ntest->argisrow = type_is_rowtype(exprType((Node *) ntest->arg));
+ if (ntest->argisrow)
+ return false; /* punt on composites */
info->notnulltest = ntest;
/*
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 56b432c9bb2..b7db0e9d164 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.281 2009/12/15 17:57:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.282 2010/01/01 23:03:10 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -1295,7 +1295,7 @@ find_nonnullable_rels_walker(Node *node, bool top_level)
/* IS NOT NULL can be considered strict, but only at top level */
NullTest *expr = (NullTest *) node;
- if (top_level && expr->nulltesttype == IS_NOT_NULL)
+ if (top_level && expr->nulltesttype == IS_NOT_NULL && !expr->argisrow)
result = find_nonnullable_rels_walker((Node *) expr->arg, false);
}
else if (IsA(node, BooleanTest))
@@ -1497,7 +1497,7 @@ find_nonnullable_vars_walker(Node *node, bool top_level)
/* IS NOT NULL can be considered strict, but only at top level */
NullTest *expr = (NullTest *) node;
- if (top_level && expr->nulltesttype == IS_NOT_NULL)
+ if (top_level && expr->nulltesttype == IS_NOT_NULL && !expr->argisrow)
result = find_nonnullable_vars_walker((Node *) expr->arg, false);
}
else if (IsA(node, BooleanTest))
@@ -1601,7 +1601,7 @@ find_forced_null_var(Node *node)
/* check for var IS NULL */
NullTest *expr = (NullTest *) node;
- if (expr->nulltesttype == IS_NULL)
+ if (expr->nulltesttype == IS_NULL && !expr->argisrow)
{
Var *var = (Var *) expr->arg;
@@ -2856,6 +2856,7 @@ eval_const_expressions_mutator(Node *node,
newntest = makeNode(NullTest);
newntest->arg = (Expr *) relem;
newntest->nulltesttype = ntest->nulltesttype;
+ newntest->argisrow = ntest->argisrow;
newargs = lappend(newargs, newntest);
}
/* If all the inputs were constants, result is TRUE */
@@ -2867,7 +2868,7 @@ eval_const_expressions_mutator(Node *node,
/* Else we need an AND node */
return (Node *) make_andclause(newargs);
}
- if (arg && IsA(arg, Const))
+ if (!ntest->argisrow && arg && IsA(arg, Const))
{
Const *carg = (Const *) arg;
bool result;
@@ -2893,6 +2894,7 @@ eval_const_expressions_mutator(Node *node,
newntest = makeNode(NullTest);
newntest->arg = (Expr *) arg;
newntest->nulltesttype = ntest->nulltesttype;
+ newntest->argisrow = ntest->argisrow;
return (Node *) newntest;
}
if (IsA(node, BooleanTest))
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 4640bbd205d..f18b66ca146 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.159 2009/07/16 06:33:43 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.160 2010/01/01 23:03:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -541,6 +541,7 @@ get_relation_constraints(PlannerInfo *root,
att->atttypmod,
0);
ntest->nulltesttype = IS_NOT_NULL;
+ ntest->argisrow = type_is_rowtype(att->atttypid);
result = lappend(result, ntest);
}
}
diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c
index 87a822dce07..7c30c62a2a2 100644
--- a/src/backend/optimizer/util/predtest.c
+++ b/src/backend/optimizer/util/predtest.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.28 2009/12/27 18:55:52 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.29 2010/01/01 23:03:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1043,7 +1043,7 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause)
Expr *nonnullarg = ((NullTest *) predicate)->arg;
/* row IS NOT NULL does not act in the simple way we have in mind */
- if (!type_is_rowtype(exprType((Node *) nonnullarg)))
+ if (!((NullTest *) predicate)->argisrow)
{
if (is_opclause(clause) &&
list_member_strip(((OpExpr *) clause)->args, nonnullarg) &&
@@ -1102,7 +1102,7 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause)
Expr *isnullarg = ((NullTest *) predicate)->arg;
/* row IS NULL does not act in the simple way we have in mind */
- if (type_is_rowtype(exprType((Node *) isnullarg)))
+ if (((NullTest *) predicate)->argisrow)
return false;
/* Any strict op/func on foo refutes foo IS NULL */
@@ -1118,6 +1118,7 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause)
/* foo IS NOT NULL refutes foo IS NULL */
if (clause && IsA(clause, NullTest) &&
((NullTest *) clause)->nulltesttype == IS_NOT_NULL &&
+ !((NullTest *) clause)->argisrow &&
equal(((NullTest *) clause)->arg, isnullarg))
return true;
@@ -1131,12 +1132,13 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause)
Expr *isnullarg = ((NullTest *) clause)->arg;
/* row IS NULL does not act in the simple way we have in mind */
- if (type_is_rowtype(exprType((Node *) isnullarg)))
+ if (((NullTest *) clause)->argisrow)
return false;
/* foo IS NULL refutes foo IS NOT NULL */
if (predicate && IsA(predicate, NullTest) &&
((NullTest *) predicate)->nulltesttype == IS_NOT_NULL &&
+ !((NullTest *) predicate)->argisrow &&
equal(((NullTest *) predicate)->arg, isnullarg))
return true;