]> granicus.if.org Git - postgresql/commitdiff
Add an "argisrow" field to NullTest nodes, following a plan made way back in
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 1 Jan 2010 23:03:10 +0000 (23:03 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 1 Jan 2010 23:03:10 +0000 (23:03 +0000)
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.

14 files changed:
src/backend/executor/execQual.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/nodes/outfuncs.c
src/backend/nodes/readfuncs.c
src/backend/optimizer/path/indxpath.c
src/backend/optimizer/plan/planagg.c
src/backend/optimizer/util/clauses.c
src/backend/optimizer/util/plancat.c
src/backend/optimizer/util/predtest.c
src/backend/parser/parse_expr.c
src/include/catalog/catversion.h
src/include/nodes/execnodes.h
src/include/nodes/primnodes.h

index a56045375154450b54959e94895a18cc4337aed2..8f025cfba5e9aaa8c4df215adef1c0d3bc5432ef 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * 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)
                return result;                  /* nothing to check */
 
-       if (nstate->argisrow && !(*isNull))
+       if (ntest->argisrow && !(*isNull))
        {
                HeapTupleHeader tuple;
                Oid                     tupType;
@@ -4704,7 +4704,6 @@ ExecInitExpr(Expr *node, PlanState *parent)
 
                                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;
                        }
index afbc3edaf62c89c62b8724ac4efa7acd94b35e57..88c1318a807c660aa8f4407b2d7e0f35a1539e13 100644 (file)
@@ -15,7 +15,7 @@
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -1506,6 +1506,7 @@ _copyNullTest(NullTest *from)
 
        COPY_NODE_FIELD(arg);
        COPY_SCALAR_FIELD(nulltesttype);
+       COPY_SCALAR_FIELD(argisrow);
 
        return newnode;
 }
index e53b4a89e6e4eae5eef94fcff7a7261f55f3d5dc..8764ea9960120fbcba2daa4f1df9b5f807a6bbd6 100644 (file)
@@ -22,7 +22,7 @@
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -623,6 +623,7 @@ _equalNullTest(NullTest *a, NullTest *b)
 {
        COMPARE_NODE_FIELD(arg);
        COMPARE_SCALAR_FIELD(nulltesttype);
+       COMPARE_SCALAR_FIELD(argisrow);
 
        return true;
 }
index b35b0beaf19333a44fa3d7d2196f1e2c11cfe911..b48ffe778a55c683e4b0d739a2d68e98e589ea98 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * 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*
@@ -1229,6 +1229,7 @@ _outNullTest(StringInfo str, NullTest *node)
 
        WRITE_NODE_FIELD(arg);
        WRITE_ENUM_FIELD(nulltesttype, NullTestType);
+       WRITE_BOOL_FIELD(argisrow);
 }
 
 static void
index 3e4a595e827609ac81bc3edac64fb8e7012e5f8d..043f436d55a4875241a933993ecff426fbdc3b5b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * 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
@@ -963,6 +963,7 @@ _readNullTest(void)
 
        READ_NODE_FIELD(arg);
        READ_ENUM_FIELD(nulltesttype, NullTestType);
+       READ_BOOL_FIELD(argisrow);
 
        READ_DONE();
 }
index 456a5b9be48316d2a43fa69d069d5502671ce6d3..c69dd8686dd53409095a25555ab8c2417c939e96 100644 (file)
@@ -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;
        }
index a32a06fc28dd5535cc7d5b317bd627b5ec44b55c..aa841ccff569697c0ca07429a361dedb965c8d2d 100644 (file)
@@ -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;
 
        /*
index 56b432c9bb2008404157b27dbadd65b0b126c1a2..b7db0e9d164278e39bd33f027d8ede06748a45a5 100644 (file)
@@ -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))
index 4640bbd205d4c721139b18acc6991cd6b08f09c5..f18b66ca1463415a9f63b4362859b599343f4cde 100644 (file)
@@ -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);
                                }
                        }
index 87a822dce072f778419db0581675659c63c1c790..7c30c62a2a23fa4425703b353a36ad76e5c8c99a 100644 (file)
@@ -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;
 
index 7dc20b4d6a7c4ba6a973ccdab1251ef54303e528..c5c7e7e873d44a5366d4079ea7e2dca6db733f97 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * 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);
                                /* the argument can be any type, so don't coerce it */
+                               n->argisrow = type_is_rowtype(exprType((Node *) n->arg));
                                result = expr;
                                break;
                        }
index 05ee9590260ea489e81c44e1124b6eb142fbe743..50b6f33a1e2133f7df19594e5ca45c85b804a471 100644 (file)
@@ -37,7 +37,7 @@
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     200912291
+#define CATALOG_VERSION_NO     201001011
 
 #endif
index ac11b496fcfc58eb4779fda1d08728119e61f341..12cfcc4fdfa31304127ddf85cca17f5bd49e46fb 100644 (file)
@@ -7,7 +7,7 @@
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -886,8 +886,7 @@ typedef struct NullTestState
 {
        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;
 
index 58d286ab9c8a287fa56f0a821f370038c0784dbe..601f9c6470cd9a2d53a691995269bc2121b34de7 100644 (file)
@@ -10,7 +10,7 @@
  * 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 $
  *
  *-------------------------------------------------------------------------
  */
@@ -936,9 +936,7 @@ typedef OpExpr NullIfExpr;
  * 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.
  * ----------------
  */
 
@@ -952,6 +950,7 @@ typedef struct NullTest
        Expr            xpr;
        Expr       *arg;                        /* input expression */
        NullTestType nulltesttype;      /* IS NULL, IS NOT NULL */
+       bool            argisrow;               /* T if input is of a composite type */
 } NullTest;
 
 /*