mirror of
https://github.com/postgres/postgres.git
synced 2025-06-10 09:21:54 +03:00
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.
This commit is contained in:
parent
29c4ad9829
commit
7839d35991
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -3475,7 +3475,7 @@ ExecEvalNullTest(NullTestState *nstate,
|
|||||||
if (isDone && *isDone == ExprEndResult)
|
if (isDone && *isDone == ExprEndResult)
|
||||||
return result; /* nothing to check */
|
return result; /* nothing to check */
|
||||||
|
|
||||||
if (nstate->argisrow && !(*isNull))
|
if (ntest->argisrow && !(*isNull))
|
||||||
{
|
{
|
||||||
HeapTupleHeader tuple;
|
HeapTupleHeader tuple;
|
||||||
Oid tupType;
|
Oid tupType;
|
||||||
@ -4704,7 +4704,6 @@ ExecInitExpr(Expr *node, PlanState *parent)
|
|||||||
|
|
||||||
nstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullTest;
|
nstate->xprstate.evalfunc = (ExprStateEvalFunc) ExecEvalNullTest;
|
||||||
nstate->arg = ExecInitExpr(ntest->arg, parent);
|
nstate->arg = ExecInitExpr(ntest->arg, parent);
|
||||||
nstate->argisrow = type_is_rowtype(exprType((Node *) ntest->arg));
|
|
||||||
nstate->argdesc = NULL;
|
nstate->argdesc = NULL;
|
||||||
state = (ExprState *) nstate;
|
state = (ExprState *) nstate;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1506,6 +1506,7 @@ _copyNullTest(NullTest *from)
|
|||||||
|
|
||||||
COPY_NODE_FIELD(arg);
|
COPY_NODE_FIELD(arg);
|
||||||
COPY_SCALAR_FIELD(nulltesttype);
|
COPY_SCALAR_FIELD(nulltesttype);
|
||||||
|
COPY_SCALAR_FIELD(argisrow);
|
||||||
|
|
||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -623,6 +623,7 @@ _equalNullTest(NullTest *a, NullTest *b)
|
|||||||
{
|
{
|
||||||
COMPARE_NODE_FIELD(arg);
|
COMPARE_NODE_FIELD(arg);
|
||||||
COMPARE_SCALAR_FIELD(nulltesttype);
|
COMPARE_SCALAR_FIELD(nulltesttype);
|
||||||
|
COMPARE_SCALAR_FIELD(argisrow);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* Every node type that can appear in stored rules' parsetrees *must*
|
* Every node type that can appear in stored rules' parsetrees *must*
|
||||||
@ -1229,6 +1229,7 @@ _outNullTest(StringInfo str, NullTest *node)
|
|||||||
|
|
||||||
WRITE_NODE_FIELD(arg);
|
WRITE_NODE_FIELD(arg);
|
||||||
WRITE_ENUM_FIELD(nulltesttype, NullTestType);
|
WRITE_ENUM_FIELD(nulltesttype, NullTestType);
|
||||||
|
WRITE_BOOL_FIELD(argisrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* Path and Plan nodes do not have any readfuncs support, because we
|
* Path and Plan nodes do not have any readfuncs support, because we
|
||||||
@ -963,6 +963,7 @@ _readNullTest(void)
|
|||||||
|
|
||||||
READ_NODE_FIELD(arg);
|
READ_NODE_FIELD(arg);
|
||||||
READ_ENUM_FIELD(nulltesttype, NullTestType);
|
READ_ENUM_FIELD(nulltesttype, NullTestType);
|
||||||
|
READ_BOOL_FIELD(argisrow);
|
||||||
|
|
||||||
READ_DONE();
|
READ_DONE();
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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;
|
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 true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 = makeNode(NullTest);
|
||||||
ntest->nulltesttype = IS_NOT_NULL;
|
ntest->nulltesttype = IS_NOT_NULL;
|
||||||
ntest->arg = copyObject(info->target);
|
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;
|
info->notnulltest = ntest;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* 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 */
|
/* IS NOT NULL can be considered strict, but only at top level */
|
||||||
NullTest *expr = (NullTest *) node;
|
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);
|
result = find_nonnullable_rels_walker((Node *) expr->arg, false);
|
||||||
}
|
}
|
||||||
else if (IsA(node, BooleanTest))
|
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 */
|
/* IS NOT NULL can be considered strict, but only at top level */
|
||||||
NullTest *expr = (NullTest *) node;
|
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);
|
result = find_nonnullable_vars_walker((Node *) expr->arg, false);
|
||||||
}
|
}
|
||||||
else if (IsA(node, BooleanTest))
|
else if (IsA(node, BooleanTest))
|
||||||
@ -1601,7 +1601,7 @@ find_forced_null_var(Node *node)
|
|||||||
/* check for var IS NULL */
|
/* check for var IS NULL */
|
||||||
NullTest *expr = (NullTest *) node;
|
NullTest *expr = (NullTest *) node;
|
||||||
|
|
||||||
if (expr->nulltesttype == IS_NULL)
|
if (expr->nulltesttype == IS_NULL && !expr->argisrow)
|
||||||
{
|
{
|
||||||
Var *var = (Var *) expr->arg;
|
Var *var = (Var *) expr->arg;
|
||||||
|
|
||||||
@ -2856,6 +2856,7 @@ eval_const_expressions_mutator(Node *node,
|
|||||||
newntest = makeNode(NullTest);
|
newntest = makeNode(NullTest);
|
||||||
newntest->arg = (Expr *) relem;
|
newntest->arg = (Expr *) relem;
|
||||||
newntest->nulltesttype = ntest->nulltesttype;
|
newntest->nulltesttype = ntest->nulltesttype;
|
||||||
|
newntest->argisrow = ntest->argisrow;
|
||||||
newargs = lappend(newargs, newntest);
|
newargs = lappend(newargs, newntest);
|
||||||
}
|
}
|
||||||
/* If all the inputs were constants, result is TRUE */
|
/* 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 */
|
/* Else we need an AND node */
|
||||||
return (Node *) make_andclause(newargs);
|
return (Node *) make_andclause(newargs);
|
||||||
}
|
}
|
||||||
if (arg && IsA(arg, Const))
|
if (!ntest->argisrow && arg && IsA(arg, Const))
|
||||||
{
|
{
|
||||||
Const *carg = (Const *) arg;
|
Const *carg = (Const *) arg;
|
||||||
bool result;
|
bool result;
|
||||||
@ -2893,6 +2894,7 @@ eval_const_expressions_mutator(Node *node,
|
|||||||
newntest = makeNode(NullTest);
|
newntest = makeNode(NullTest);
|
||||||
newntest->arg = (Expr *) arg;
|
newntest->arg = (Expr *) arg;
|
||||||
newntest->nulltesttype = ntest->nulltesttype;
|
newntest->nulltesttype = ntest->nulltesttype;
|
||||||
|
newntest->argisrow = ntest->argisrow;
|
||||||
return (Node *) newntest;
|
return (Node *) newntest;
|
||||||
}
|
}
|
||||||
if (IsA(node, BooleanTest))
|
if (IsA(node, BooleanTest))
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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,
|
att->atttypmod,
|
||||||
0);
|
0);
|
||||||
ntest->nulltesttype = IS_NOT_NULL;
|
ntest->nulltesttype = IS_NOT_NULL;
|
||||||
|
ntest->argisrow = type_is_rowtype(att->atttypid);
|
||||||
result = lappend(result, ntest);
|
result = lappend(result, ntest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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;
|
Expr *nonnullarg = ((NullTest *) predicate)->arg;
|
||||||
|
|
||||||
/* row IS NOT NULL does not act in the simple way we have in mind */
|
/* 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) &&
|
if (is_opclause(clause) &&
|
||||||
list_member_strip(((OpExpr *) clause)->args, nonnullarg) &&
|
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;
|
Expr *isnullarg = ((NullTest *) predicate)->arg;
|
||||||
|
|
||||||
/* row IS NULL does not act in the simple way we have in mind */
|
/* 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;
|
return false;
|
||||||
|
|
||||||
/* Any strict op/func on foo refutes foo IS NULL */
|
/* 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 */
|
/* foo IS NOT NULL refutes foo IS NULL */
|
||||||
if (clause && IsA(clause, NullTest) &&
|
if (clause && IsA(clause, NullTest) &&
|
||||||
((NullTest *) clause)->nulltesttype == IS_NOT_NULL &&
|
((NullTest *) clause)->nulltesttype == IS_NOT_NULL &&
|
||||||
|
!((NullTest *) clause)->argisrow &&
|
||||||
equal(((NullTest *) clause)->arg, isnullarg))
|
equal(((NullTest *) clause)->arg, isnullarg))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -1131,12 +1132,13 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause)
|
|||||||
Expr *isnullarg = ((NullTest *) clause)->arg;
|
Expr *isnullarg = ((NullTest *) clause)->arg;
|
||||||
|
|
||||||
/* row IS NULL does not act in the simple way we have in mind */
|
/* 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;
|
return false;
|
||||||
|
|
||||||
/* foo IS NULL refutes foo IS NOT NULL */
|
/* foo IS NULL refutes foo IS NOT NULL */
|
||||||
if (predicate && IsA(predicate, NullTest) &&
|
if (predicate && IsA(predicate, NullTest) &&
|
||||||
((NullTest *) predicate)->nulltesttype == IS_NOT_NULL &&
|
((NullTest *) predicate)->nulltesttype == IS_NOT_NULL &&
|
||||||
|
!((NullTest *) predicate)->argisrow &&
|
||||||
equal(((NullTest *) predicate)->arg, isnullarg))
|
equal(((NullTest *) predicate)->arg, isnullarg))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -276,6 +276,7 @@ transformExpr(ParseState *pstate, Node *expr)
|
|||||||
|
|
||||||
n->arg = (Expr *) transformExpr(pstate, (Node *) n->arg);
|
n->arg = (Expr *) transformExpr(pstate, (Node *) n->arg);
|
||||||
/* the argument can be any type, so don't coerce it */
|
/* the argument can be any type, so don't coerce it */
|
||||||
|
n->argisrow = type_is_rowtype(exprType((Node *) n->arg));
|
||||||
result = expr;
|
result = expr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 200912291
|
#define CATALOG_VERSION_NO 201001011
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -886,8 +886,7 @@ typedef struct NullTestState
|
|||||||
{
|
{
|
||||||
ExprState xprstate;
|
ExprState xprstate;
|
||||||
ExprState *arg; /* input expression */
|
ExprState *arg; /* input expression */
|
||||||
bool argisrow; /* T if input is of a composite type */
|
/* used only if input is of composite type: */
|
||||||
/* used only if argisrow: */
|
|
||||||
TupleDesc argdesc; /* tupdesc for most recent input */
|
TupleDesc argdesc; /* tupdesc for most recent input */
|
||||||
} NullTestState;
|
} NullTestState;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -936,9 +936,7 @@ typedef OpExpr NullIfExpr;
|
|||||||
* The appropriate test is performed and returned as a boolean Datum.
|
* The appropriate test is performed and returned as a boolean Datum.
|
||||||
*
|
*
|
||||||
* NOTE: the semantics of this for rowtype inputs are noticeably different
|
* 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
|
* from the scalar case. We provide an "argisrow" flag to reflect that.
|
||||||
* "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.
|
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -952,6 +950,7 @@ typedef struct NullTest
|
|||||||
Expr xpr;
|
Expr xpr;
|
||||||
Expr *arg; /* input expression */
|
Expr *arg; /* input expression */
|
||||||
NullTestType nulltesttype; /* IS NULL, IS NOT NULL */
|
NullTestType nulltesttype; /* IS NULL, IS NOT NULL */
|
||||||
|
bool argisrow; /* T if input is of a composite type */
|
||||||
} NullTest;
|
} NullTest;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user