*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.257 2009/12/29 17:40:59 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.258 2010/01/01 23:03:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
if (isDone && *isDone == ExprEndResult)
return result; /* nothing to check */
- if (nstate->argisrow && !(*isNull))
+ if (ntest->argisrow && !(*isNull))
{
HeapTupleHeader tuple;
Oid tupType;
nstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullTest;
nstate->arg = ExecInitExpr(ntest->arg, parent);
- nstate->argisrow = type_is_rowtype(exprType((Node *) ntest->arg));
nstate->argdesc = NULL;
state = (ExprState *) nstate;
}
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.456 2009/12/29 20:11:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.457 2010/01/01 23:03:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
COPY_NODE_FIELD(arg);
COPY_SCALAR_FIELD(nulltesttype);
+ COPY_SCALAR_FIELD(argisrow);
return newnode;
}
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.377 2009/12/23 02:35:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.378 2010/01/01 23:03:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
{
COMPARE_NODE_FIELD(arg);
COMPARE_SCALAR_FIELD(nulltesttype);
+ COMPARE_SCALAR_FIELD(argisrow);
return true;
}
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.377 2009/12/29 20:11:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.378 2010/01/01 23:03:10 tgl Exp $
*
* NOTES
* Every node type that can appear in stored rules' parsetrees *must*
WRITE_NODE_FIELD(arg);
WRITE_ENUM_FIELD(nulltesttype, NullTestType);
+ WRITE_BOOL_FIELD(argisrow);
}
static void
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.228 2009/12/15 17:57:46 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.229 2010/01/01 23:03:10 tgl Exp $
*
* NOTES
* Path and Plan nodes do not have any readfuncs support, because we
READ_NODE_FIELD(arg);
READ_ENUM_FIELD(nulltesttype, NullTestType);
+ READ_BOOL_FIELD(argisrow);
READ_DONE();
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
{
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;
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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;
/*
*
*
* 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
/* 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))
/* 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))
/* 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;
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 */
/* 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;
newntest = makeNode(NullTest);
newntest->arg = (Expr *) arg;
newntest->nulltesttype = ntest->nulltesttype;
+ newntest->argisrow = ntest->argisrow;
return (Node *) newntest;
}
if (IsA(node, BooleanTest))
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
att->atttypmod,
0);
ntest->nulltesttype = IS_NOT_NULL;
+ ntest->argisrow = type_is_rowtype(att->atttypid);
result = lappend(result, ntest);
}
}
*
*
* 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 $
*
*-------------------------------------------------------------------------
*/
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) &&
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 */
/* 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;
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;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.251 2009/12/15 17:57:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.252 2010/01/01 23:03:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
n->arg = (Expr *) transformExpr(pstate, (Node *) n->arg);
/* the argument can be any type, so don't coerce it */
+ n->argisrow = type_is_rowtype(exprType((Node *) n->arg));
result = expr;
break;
}
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.563 2009/12/29 22:00:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.564 2010/01/01 23:03:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 200912291
+#define CATALOG_VERSION_NO 201001011
#endif
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.214 2009/12/15 04:57:48 rhaas Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.215 2010/01/01 23:03:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
{
ExprState xprstate;
ExprState *arg; /* input expression */
- bool argisrow; /* T if input is of a composite type */
- /* used only if argisrow: */
+ /* used only if input is of composite type: */
TupleDesc argdesc; /* tupdesc for most recent input */
} NullTestState;
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.152 2009/12/15 17:57:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.153 2010/01/01 23:03:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* The appropriate test is performed and returned as a boolean Datum.
*
* NOTE: the semantics of this for rowtype inputs are noticeably different
- * from the scalar case. It would probably be a good idea to include an
- * "argisrow" flag in the struct to reflect that, but for the moment,
- * we do not do so to avoid forcing an initdb during 8.2beta.
+ * from the scalar case. We provide an "argisrow" flag to reflect that.
* ----------------
*/
Expr xpr;
Expr *arg; /* input expression */
NullTestType nulltesttype; /* IS NULL, IS NOT NULL */
+ bool argisrow; /* T if input is of a composite type */
} NullTest;
/*